Archive for the ‘Art’ Category
Design Trek III: The Search for Inspiration
Tuesday, May 3rd, 2011
(No, this isn’t the 3rd in a series, that was a bad reference to Star Trek)
At the end of last week I wrapped up my work on a contract I’d been working on since last fall. My part of the project has been passed on to the next team of developers who will wrap up the final features. It feels great to be able to get back to work on my own projects, and I look forward to seeing the game launch when it’s done.
As I am returning to working on my own games, I thought a post about the time between projects would be in order. I often get asked by players where I find the inspiration for my games. I’m sure we all have different answers for this, but I thought I’d try to explain mine.
Where an idea comes from is difficult to answer. Inspiration comes in many forms for me, and I’m never quite sure where I’m going to find it. Sometimes it comes from playing another video game, sometimes a movie, sometimes discussing politics with friends.
One of the things that I think is most misunderstood about inspiration is the idea that you don’t need to work at it, that it will just come to you in a flash. I don’t believe this ever to be the case. Inspiration takes work, it takes dedication, and it takes patience. You need to work at being inspired. You need to work at your ideas. An artist might do dozens of sketches, then several small paintings working on an idea before finding the direction they want to take the final work. We too must actively look for ideas, experiment and refine them. That flash of inspiration only comes after you’ve done the research, the work, and given it all time to let your brain process the ideas.
Well that’s great, you say, but where do I begin? If it takes all this work, where does the work start? These are some of the activities I’ll do when I’m actively looking for inspiration:
- read a book about a new subject
- watch a film
- go for a walk in nature
- go for a walk in the city
- play a video game
- play a board game
- go to a museum
- go to an art gallery
- write something
- draw
- build something with my hands
- go out for a good meal
- cook something new
- go out with friends and/or family
- walk to the river and listen the sounds of the water
- start writing ideas down
You might have your own list that’s totally different. However, I believe that one of the most important items on that list is the last one: write down your ideas. The act of forcing yourself to think about a problem will lead to inspiration. It is not easy, it may even be actively difficult, but working through it will lead you in new directions and to new solutions. The more ideas you write down, the more ideas you will have. The less you work at actively thinking of new ideas, the fewer ideas you will have. This is why inspiration takes work.
But perhaps most importantly, you need to be constantly open to new ideas. You need to be aware of when an good idea is speaking to you, and know to follow it. That means resisting the urge to make assumptions and snap judgements about an idea. It means talking with people who disagree with you. It means debating without shutting out. It means empathy. Because finding a new idea often means looking at a problem from another point of view; understanding someone else’s feelings; putting yourself in someone else’s shoes.
As game designers, we need to be engaged in the world around us. Games are about interactivity, emotion, and narrative. The world is full of all these things, we just have look for it, and work at it seeing it.
Owen
Universal OpenGL Apps
Sunday, November 28th, 2010
I recently took part in the 360iDev Game Jam remotely from home. The game jam is always a lot of fun, even if you can’t get yourself to the 360iDev conference itself (which you should totally do, by the way, if you can. It’s an amazing conference). I created a game in 8 hours which I’m calling “Dirty Diapers”, you can see the details of its creation on the Game Jam site. There’s a video of the game in action at the end of that page.
The game is about keeping a room full of babies happy. Over time, babies become unhappy because they either want to be fed, changed, or rocked. It’s your job to drag an action up from the bottom of the screen to make the baby happy again. As time goes on, they get more unhappy more frequently.
I think it turned out quite well, so I’ve decided to try to get it into the store at some point. Right now I’m extremely busy with some contract work, but I’m trying to find a few hours here and there to finish it up and submit it.
One of things I decided to try with this game was to build it as a universal app (that is, one app that runs on iPhone/iPod touch, and iPad, instead of separate apps for iPhone and iPad). The game is 100% OpenGL on the rendering side, so I needed to figure out how to set up my frame buffers for a universal app. I thought I’d go through that today. (Holy moly, a technical post instead of an indie lifestyle post! Hold on to your hats!)
Project Setup
The first thing you need to do for a universal app is set up your Xcode project so that it knows to build the app as universal. I went to Jeff LaMarche’s excellent blog and followed his instructions to do this part (and read the follow-up post for a few more details).
Once you’ve done that, you should have a project that can at least compile for iPad or iPhone. Good.
Frame Buffer Setup
Now that you’ve got your app building for multiple devices, you’re going to need to do some work to support multiple screen resolutions. As of this writing, there are three different resolutions to worry about:
- iPad: 1024 x 768
- iPhone/iPod touch (non-retina display): 320 x 480
- iPhone/iPod touch (retina display): 640 x 960
However, Apple does some clever stuff to help you with the retina displays. If you query the size of the screen:
CGRect screenFrame = [[UIScreen mainScreen] applicationFrame]; |
You’ll get 320 x 480 on both retina and non-retina displays. This is because they measure the screen in “points” instead of pixels now. On a retina display, there are 2 pixels for every point. The nice thing is that it lets you treat all iPhone/iPod touch screens the same way, with the same positioning code.
Ok, so we’ve got these different screen sizes, we need to tell OpenGL to create different sized frame buffers. Somewhere in your code you’ve probably got something like this, which creates a render buffer from an EAGLDrawable CAEAGLLayer:
glBindRenderbufferOES(GL_RENDERBUFFER_OES, buffer.m_colorBufferHandle); [oglContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:drawable]; glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &buffer.m_width); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &buffer.m_height); |
If you build and run, what you’ll find is that your render buffer will be created with the proper size for iPad and non-retina displays, but you’ll end up with a 320 x 480 render buffer for retina displays (which need 640 x 960), and your retina display game will look awful. This is because the CAEAGLLayer is telling OpenGL that it’s dimensions are 320 x 480 on the retina display.
In order to remedy this, we need to make use of two new UIView properties found in iOS 4.0 and up called: scale and contentScaleFactor.
scale
The new scale property will tell you the amount the point values of the UIView are being scaled. If you’re running on a non-retina display and query a view’s scale, it will be 1.0. If you’re running on an retina display, you’ll find that it’s 2.0. This gives you a way to test which kind of display we’re working with, and we’ll use this later.
contentScaleFactor
The contentScaleFactor is a different beast. This will always be 1.0. However, if you’re running OpenGL in a view on a retina display, you need to set this value to match the scale value of the view. This will tell the CAEAGLLayer to update its dimensions to match the actual pixel size of the screen, allowing you to create an appropriately sized render buffer.
Now, if you’re planning to support iOS versions prior to 4.0, these properties won’t be available, so you need to do runtime checks for them.
This is what I do inside my EAGLView’s -layoutSubviews method to set the contentScaleFactor on the view:
// Set the scale factor to be the same as the main screen if ([self respondsToSelector: NSSelectorFromString(@"contentScaleFactor")]) { [self setContentScaleFactor:[[UIScreen mainScreen] scale]]; } |
Now, when I tell the render buffer to create itself based on the size of the layer, it will create a 640 x 960 render buffer on a retina display, but a 320 x 480 buffer on a non-retina display. Hooray! But, we’re not quite there yet…
Viewport Setup
We’ve got our render buffer set up to create itself at the proper resolution now. It will match the screen dimension and contentScaleFactor of the EAGLView, which is what we want. Now we need to tell OpenGL to create an appropriately sized viewport. This code is for a 2D game, so adjust as necessary for a 3D game.
You’ll need to create a viewport that matches the frame buffer size for the given screen. Something like this:
glViewport(0, 0, buffer.m_width, buffer.m_height); |
For a 2D game, you then need to set up an orthogonal projection. There’s a good chance that you have a line in your code somewhere that looks like this:
glOrthof(0.0f, 480.f, 320.f, 0.0f, -1.0f, 1.0f); |
Clearly this isn’t going to work. Now, there are two options here for creating the transform:
1) Create the transform based on the UIScreen size
The code for this is simple:
CGRect appFrame = [[UIScreen mainScreen] applicationFrame]; glOrthof(0.0f, appFrame.size.width, appFrame.size.height, 0.0f, -1.0f, 1.0f); |
However, let’s look at what this does. On iPad, it creates a 1024 x 768 sized viewport. Great, that’s what we want. On a non-retina display, it creates a 320 x 480 viewport. Also good. But, on a retina display, it also creates a 320 x 480 display. Now, this is OK. The framebuffer is 640 x 960, so the pixels are there. So what does this mean?
The Good
You only need to write two code paths for positioning sprites on the screen: one for iPad, and one for iPhone, and let OpenGL handle matching the render buffer to the viewport appropriately for you. The only caveat here is that you’ll need to manually scale all your sprites’ sizes by 50%. If you do this, you’ll scale them down to the correct point size, and then OpenGL will render them at 100% resolution when it pushes the textures through the render pipeline.
Confused? Think about it this way: you’ve got a view port of 320 x 480 but a render buffer of 640 x 960. Take a sprite that’s 100 pixels x 100 pixels and render it as a 100 x 100 point sprite in the viewport. This is actually 200 x 200 pixels in the render buffer. So in order to render it as 100 x 100 pixels, you need to scale your vertices down by 50% to a 50 x 50 point sprite.
The Bad
You’ll need to write some code into your sprite system (and bitmap font system) to scale things to 50% if you’re on a retina display.
This is the approach I use. At app startup, I get the screen scaling factor, and then use it to scale all my sprites:
if ([[UIScreen mainScreen] respondsToSelector: NSSelectorFromString(@"scale")]) { ScreenScaleFactor = [[UIScreen mainScreen] scale]; InverseScaleFactor = 1.f / ScreenScaleFactor; } |
2) Create the transform based on the layer size
The alternative is to create a different viewport size based on the actual pixel size of the screen. You can do this by getting the size of your created render buffer. Something like this:
glOrthof(0.0f, frameBuffer.m_width, frameBuffer.m_height, 0.0f, -1.0f, 1.0f); |
This will give you a viewport that matches the screen size in pixels, not points.
The Good
The advantage here is that you don’t need to do any sprite scaling. You just render everything at 100%.
The Bad
You’ll need to have three different code paths for sprite positioning, based on the size of the screen, as you’ll now have three different sized viewports to worry about.
Art Work
You’ll probably want to have different sized artwork for non-retina displays than for iPad and retina displays. For Dirty Diapers I’ve got two game texture atlases: one for iPad and retina displays, and one for non-retina displays. The non-retina atlas is identical to the larger one, it’s just scaled down 50% in Photoshop. You could scale your graphics in OpenGL, but it will never look as good. If you’re like me, the imperfections will just drive you nuts.
So I have two texture atlases, but there are 3 possible screen sizes to worry about (see the next section). I do a check like this to determine which texture atlas to load:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad || ScreenSizeConsts::ScreenScaleFactor > 1.01f) { // Load texture atlas for iPad/Retina display } else { // Load texture atlas for Original iPhone display } |
If you want to load 3 different textures (iPad, non-retina, retina), you can use the @2x.png file naming convention (depending on how you’re loading your textures) and just check for iPad or not, but now you’re dealing with 3 sets of textures. The choice is yours. If you’re loading textures manually and the @2x trick doesn’t work, you can split things out like this:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { // Load texture atlas for iPad display } else if (ScreenSizeConsts::ScreenScaleFactor > 1.01f) { // Load texture atlas for Retina display } else { // Load texture atlas for Original iPhone display } |
Finally, Positioning
Now you’ve got your different artwork loading, you’ve got your render buffer set up, and your viewport set up. Now you just need to tell your objects to render in different positions, based on the screen. To do this, I set up a bunch of member variables for positioning code (for static items), and then on init, check the device and screen scale factors and adjust them accordingly. This is necessary for 2D art layout, but if you’re working with a viewport into a 3D world, you may not need to do nearly as much work here.
That’s it…
There you go. I hope you were able to follow along and I wasn’t too confusing. If you’ve got better ways of doing any of this, feel free to post suggestions in the comments.
Owen
Sneak Peek: City Theme Sketch
Thursday, July 8th, 2010
I thought a few people might like to see how the design of a new theme for LandFormer starts. I’ve started working on the concepts for a city theme for the game. I did some sketching the other night and these are the drawings I’ll be basing the theme on:
You can see there are the 5 tile heights from the game. I’ll be working from these drawing to start creating the main tiles for the theme. There’s a lot of other art that goes into a theme, but the tiles are what I start with.
Owen
Theme Sneak Peek
Tuesday, June 8th, 2010
LandFormer is coming along nicely. I’m getting really close to submitting; hopefully within the next week, if all goes according to plan.
One of the things I’ve been working on the for the last couple of days is a new theme for the game. You’ve seen the Earth theme already:
This is the new Colorful Blocks theme I’ve been working on:
This new theme will be available for purchase inside the game when it launches.
Now, I must get back to work!
Owen