Wednesday, August 18, 2010

Week Six / Day Three

I really should know better than to assume something will be easy to implement, because as I said yesterday it is never as easy as you assume it will be.

Now, this isn't as bad as I'm making it seem. I am much more comfortable working with Objective-C now than when I started work this morning. It is quite interesting how much you can do with such little code. I've never used a dynamically typed language before, but it does make a lot of tasks simpler. For instance, I'm setting up a big array to save all my high scores in. At the deepest point there is a score entry containing the name of the player and their score. I create an array with these two items. I then create an array to hold ten of these arrays, creating the top ten score list for the level. Last, I create an array to hold one of these arrays for each level. Now, in C++ that might be something like vector< vector< ScoreEntry > >, where ScoreEntry has to be defined as a struct. However, in Objective-C you just pass whatever object you want into the array. It's as easy as defining an array, pushing anything onto it, then just pushing that array onto the next level array, all with no type definitions. Now, the objects need to be formatted as NSObjects, which all other NS* data types are subclasses of (such as NSString and NSArray as I've already mentioned), which adds a bit of complexity, but the simplicity gained in the overall structure is worth it. Also, Objective-C's standard for methods is a bracket system. Where in c++ you would call obj1.foomethod(x), obj-c would be more like [obj1 foomethod:x]. Also, arguments get names, which at first is distracting but once it clicks it is actually quite useful. I'm not sure I'm ready to jump ship just yet, but it's nice to know I have a more solid background as I continue iPhone development.

Now, as to what I actually got accomplished today. I did get high score lists implemented into the engine, however I haven't gotten my NSUserDefaults framework working yet, so the lists aren't valid between play sessions. Also, I've put the level's top score at the bottom of the play screen, a la old arcade games. You can see these down at the bottom in the screenshots.

One thing I need to mention is how much of a slippery slope hard coding values into an engine is. As I said in earlier blog posts, my game is simple enough that I figured having some hard coded values and states would not be that big of a deal. Thankfully I had the foresight to implement a high-level rudimentary state machine, so I'm not working entirely with hard wired conditionals, however as I add small bits that span the menu, level select, and play environments, I am really wishing I had a more general interface builder and state machine. What I hadn't considered was child states, so that I could handle the Pause and Level Completion "states" as true states, and not hard wired conditionals and locks in the application engine. Rather than a smooth, easily manipulated organization I have a decent high-level setup with lots of little conditionals, along with each buttons' position hard-coded in. The plus side of this is that I've learned how not to go about things in the future. I've already got some plans started for the interface and state handler for the next game which should allow for much more rapid and clear development. I only wish I would have seen the light sooner.

Tuesday, August 17, 2010

Week Six / Day Two

Today's post is slightly shorter than others, on account of me being pulled away from 'the office' all afternoon for landscaping duty.

I started work on the high score lists this morning. My goal is to have Top 10 lists associated with each level that can be accessed from the level select screen. Now, I figured I would basically just be able to do my level loading in reverse, using fstream, just as I've always done for outputting to a file. Unfortunately, it isn't that simple. I have a feeling that fstream is a little too 'dirty' for the iPhone's clean application bundle, and that direct write access needs to be done via approved methods only. Therefore, today began my first major lesson in Obj-C/Cocoa since I started my app development.

As I explained in an earlier post, despite the native language of the iPhone being Obj-C (from what I can tell, being the necessary language for integration of major iPhone technologies used in non-OpenGL apps), C++ execution is perfectly acceptable. Better yet, for OpenGL development C++ is preferred for all platform independent code, specifically for the future porting of the engines. The iPhone specific code for my game is only about 200 lines or so. Porting to something such as the android would require some tuning for handling the differences in touches between the two devices, and appropriately controlling the instantiation of each engine component. Other than that, it wouldn't be all that difficult. There were tutorials I had read that seem to foster a much more iPhone-centric view, but I think the benefits of an interface controlled engine are fairly obvious.

The point of all this was that I needed to learn some iPhone specific data management. While I was trying to avoid this, what I needed to learn was extremely simple. There are a few methods for going about data management. One I would like to learn eventually is SQLite, handling app data in a database style fashion. Not only does this lend to a much more powerful data/data-manipulation connection it would be a good way for me to get some database experience, as I've currently got zilch. However, what I am using is a data type known as NSUserDefaults. NSUserDefaults, from my understanding, is sort of an open book ready to filled with whatever values you want, and a key associated with said values (C++ Dictionary?). As the name describes they are generally associated with the Defaults of a program, such as user name and preferences, however everyone on the internet seems to suggest using them when implementing a high score list. I suppose I can't argue with that. So tonight I started to get a bit of a basic framework in for handling the saving and restoring of an NSUserDefault within my game. Since it is an OpenGL application is has a few modifications from the default app structure. It takes a few hops to get the data down deep enough to where I need it, but not a big deal really.

Tomorrow's work will begin with getting more than a string moved around. Apparently arrays are just as easy as strings (NSArray and NSString respectively), so an array of a levels scores along with a simple key should do the trick. Things don't always go as easily as you think they will, but with this step in the implementation they seem to have, so I'm counting on it continuing. Tomorrow should hold some more comprehensive updates, so stay posted.

Monday, August 16, 2010

Week Six / Day One

Last night driving home I was mulling over the fact that my game appeared too static. When you start a level, it's just there. Nothing is happening, and the whole scene appears dead. Now how to go about changing this? Something I've been considering for a while is moving planets, but I didn't how a clever idea of how to go about it. Would they move back and forth in lines, or better yet what about an orbit? One of the keys to my game though was that the planets didn't need to be updated, as this was one less headache to consider during optimizations. Planet updates added another layer of complexity, requiring extra work per frame updates. However, if I wanted to move in an orbit, all I really needed was an angle, a radius, and a center point. From here I could just increase the angle as I updated the planets' position, and I would have my orbit. Also, since I was already calculating the force between each planet and the ship, I wasn't adding any complexity to the runtime for the n planets, just 3 more lines of code, two of them simple trig calculations.

With that I had dynamic planets, and they added exactly what I wanted to the game. It was only a few extra values to include with the level input file and I was able to create planets which used other planets as their center points, effectively creating moons. In the screenshot at the bottom of the page you can see such an example. The green planet has a large swooping orbit, while the tiny green planet (or moon) orbits around the former. An initial test of over 20 planets seems to make little difference to frame rate. Any frame rate issues I have right now I believe are due to the fact that I still don't have the physics updates and render updates properly decoupled.

The second project of the day was to get scoring working, along with properly handling level completion, which can also be seen in the screenshot at the bottom. On the game screen, the top two numbers are the timer and the total number of color changes made thus far. In the level completion section, you can see the calculation of the score, which is just the product of the timer and the color changes. The scoring system is similar to golf, such that lower is better. You are trying to get the quickest time as well as the least amount of color changes. The number at the bottom of the screen is the distance to the goal. That way when the goal is out of the player's view there is still a method of tracking it.

I also made a few small art changes, such as the new texture for planets. They also spin now, to add more 'life' to the scene. Again, none of the art is final, as it still hasn't 'clicked' with me. I must say though, each day I get more confidence in the completion of the game. I am getting closer to really having something that I would call a presentable game, and it's pretty exciting. There is still a lot of work to be done, but the motivation doesn't hurt.

Friday, August 13, 2010

Week Five / Day Four

If I keep having weeks like this one I'll be pro in no time.

So today I started off fixing the error I had with the level loading. It turns out that it wasn't necessarily my fault. For some reason if I create a file in vi and then import it into my project in XCode, I have no problems accessing it and using it. However, if I create a blank file within XCode, it doesn't work properly. It's as if there is garbage in the file. Perhaps XCode's blank files aren't actually blank. Annoying. Regardless, I figured out the bug and level loading works as expected now.

I also wanted to stress test a bit, so I created a file that had 16 planets. While 16 isn't that many, if it made noticeable differences in performance it would give me a benchmark as to how much I can push the engine. Luckily, it seemed to make practically no difference. Considering how lightweight my geometry is, and the fact the textures are more streamlined since I found out how to make color changes, I didn't expect it to make much of a difference. I'm hoping to support 100+ planets, but without a level builder it is extremely tedious to create a file with those sorts of parameters.

I cleaned up the menu system quite a bit, as you can see below the buttons are much slicker, and the interface has some cohesion to it. This is by no means final art, as the UI and game art really don't go together, but at least it looks more like a game.

What you see in the background is a starfield that scrolls behind the menus. The Intro, Main Menu, About, and Level Select screens all lay over top of it, so there is a smooth transition between each. You can see it in motion in the video at the bottom.

I've also got a pause menu implemented, which allows you to restart the current level or quit back to the main menu at anytime:

Simple stuff given the modularity of the engine, but a useful necessity none the less. As I said earlier I got color changing working with the lighting, so now everything has lighting effects as well as textures with adjustable colors. Now rather than a texture for each button, each planet, etc. I have a single greyscale one that gets adjusted based on what I need.

Before I finished today I added in the level end marks, which are currently marked by the purple planets seen in the pause menu screenshot. By having the end of the level be a planet (with a few extra parameters) it gets treated just like any other planet, and sucks you in once you are just close enough. While nothing happens yet, the next step is a menu for handling a level completion. I would also like to add a timer and the ability to keep track of color-changes for ranking the player at the end of each level, and thus being able to keep a high score list for each.

I believe that is all the changes for today. I did have a very peculiar error worth mentioning though. Usually when an iterator goes out of the bounds of its vector it results in a EXC_BAD_ACCESS error. However, I had a problem today where it seemed like an infinite loop just prior to the applications completion of launching. I had resized a vector one less than needed and therefore the iterator was out of bounds (as a result of sloppy access on my part). It wasn't too hard to pinpoint, but still interesting that there was no 'segfault'. I'm guessing this has something to do with the startup process of an app. Anyway, here is the first video demo of Project Chromo. I don't have any good capture software so I had to use some demo software, so excuse the watermark. In the meantime, happy coding.


Thursday, August 12, 2010

Week Five / Day Three

This week seems to be rolling right along quite well, as today played out just about as smoothly as the last two days. Today's big goal was to get the basics of the level loader working, and to do that proper I had to implement some form of text rendering. Now, OpenGL has no built in way to render text, so there are a few ways of going about it. One of the tutorials I read through described using a glyph scripting language to 'build' fonts out of primitives. While this brings a lot of versatility in terms of fonts, the process was quite complicated and a bit more than I needed for my game (I also couldn't get all the different python libraries required installed correctly). The other method is to create a character map as a texture atlas and then pull individual characters out with the texture coordinates. This is the method I went with, and it works great. I haven't had a good challenge in a while where I had to implement an algorithm that took the place of brute force conditionals, and this was exactly what was needed for the character grabber. A 'slider' big enough to fit one character is moved along the texture based on the ascii values of the character. You insert a vector< string >, and each string is printed with a return at the end. The strings are parsed by character, each rendered from the coordinates found given the ascii value used by the slider. Unfortunately the map is rendered with white characters on a transparent background, so it won't show up here.

I also corrected the texture issue. I'm using a different method for loading pngs now that also allows me to load pvrs, so I've been able to mess around with compressed textures as well. They looked quite lossy, and the mipmaps were terrible, but in game you almost can't notice a difference. I still have a problem with updating my pngs in gimp and then loading them into the engine. After being manipulated a few times, the texture fails to load. I've been working around it for the time being, but hopefully I can get it straightened out.

I also got the texture color changing working. Turns out lighting has to be disabled or else the color is completely ignored. I'm hoping this just turns out to be a quirk with how I currently have lighting setup. The good thing is I can now adjust the alpha of a texture, which allows me to fade textures in and out. With this, I can now smoothly transition between screens and such, resulting in a much more professional 'feel' in the interface.

Lastly, once I had text working, I started on the implementation of the level selection. It isn't working perfectly just yet, as I can see the level names but it doesn't load anything other than the first, but I'm pretty sure it'll be a quick fix. I believe that's most of what I got done today. Things are rolling along well now, and I hope I can continue down the designing and tweaking path for a little while. In the mean time, here are some shots of where I got today. Names blocked out to protect the innocent:

Wednesday, August 11, 2010

Week Five / Day Two

Today went extremely well, and I'd say I've made one of the biggest one-day leaps in terms of tech demo to polished game with the work I got done. My intentions beginning the day were to work more on texturing, mainly to get placeholder graphics in for each place in the game that requires a texture. For the most part everything worked out just the way I needed, and I ended up with this as of 5 minutes ago:

What you see there are the main menu, level select screen, and an in-game shot respectively. I ended up just using static images for the buttons for the time being. Again, not something I agree with doing but I'm going to have to figure out a better solution for the level select, otherwise I'd have to make and load textures for every level, quite inefficient. The in-game stuff looks great in motion. I have that little ship over the colored ball right now, but I'm not too happy with it. The last thing I was working on today was getting it to properly rotate, so until that is done I won't be able to tell whether it's going to stay or not. Also, I added a background texture that moves based on a multiple of the ships movement, which gives it that distance effect 2D side scrollers use to make different background layers move at different speeds. My texture implementation is pretty ugly right now, and doesn't quite have all the features I need (specifically, color changing greyscale textures, so as not to need separate textures for each color of buttons, planets, etc.), so tomorrow once I'm satisfied with the ship and I have the rest of the placeholders setup, I'll be diving into that. I also have a bit of a bug currently. While the simulator runs fine, it seems the red and blue values of textures are getting swapped when running on the iPhone. Not a huge deal, but just an annoyance that needs to get ironed out. I posted up on idevgames about it, so hopefully I get some useful insight. Until tomorrow, happy coding.


EDIT: Almost forgot, I also created the app icon, or at least an initial design for one.

Tuesday, August 10, 2010

Week Five / Day One

Once again, back to your regularly scheduled program.

Full steam ahead today, as things are finally starting to shape up, at least on the backend. I now have a working 'menu' system in place. The application holds various states, and depending on the current state, the renderer, gamestate, and application engines all perform different tasks. The initial state is just 'blank', which each engine is set to while everything initializes. Once the renderer is loaded and ready to draw, each is thrown into an 'intro' state, where you would put studio information and such at the beginning of a game. This than leads into the main menu. Now granted, for the time being the menu is just basic primitives. But you can click on the buttons, move to the level select screen and back, and get into the test level through the menus. There is quite a bit of hard coded hacks in the background, so to see what is actually going on is a little nasty, but it is very clean from the user perspective.

In regards to the untidiness I started to consider how the menus could be done differently. Much the same as I plan to have my level editor create basic plaintext versions of the levels which are then loaded into the game, a much more abstract menu, or 'scene' object with an associated scene editor could be used for the UI. Each scene would have a background rendering (perhaps a static image, or maybe the engine running in realtime), buttons, and actions tied to those buttons. While this would be much cleaner and 1000x easier to expand, the simplicity of my current project's needs combined with the time needed to rewrite this engine to handle that sort of UI system isn't worth it. Normally this isn't something I agree with doing, but I suppose you can't have/build every feature you want, especially on your first project. Just more ideas for the second though, I suppose.

Textures are still looming over me, as I'm getting to the point where they are going to be necessary for the game to start looking like a real game, and not a simplistic example. I also need to be able to render font, as I want to procedurally draw all the text in the game, rather than have create static images for each block. For those interested, here is the menu: