Saturday, June 26, 2010

Pause IRL

I'm taking a break from coding. The size of the project has reached a point where I'm now officially navigating unchartered territory. At this point, the design decisions that I'm making will affect future iterations of the project and I want to make sure I don't build an entire house before realizing I need to move a few walls around on the first floor. In coding terms, I'm trying to decide how enemy patterns, weapons, bullets, and bullet patterns should all interact. My usual approach would be to start very simple, such as enemies that spawn based on a fixed pattern, shoot a few straight-lined bullets, and then die when they get shot. But I need to make sure that building something this way is flexible enough that if I want to have enemies move in linear patterns, and then curved patterns, and then a sequence of linear and curved patterns (etc...), that I don't have to rewrite large blocks of code every time I improve functionality.

I have a few designs in mind, and I'm getting a lot done on paper. But before I actually put anything into place, I want to step back and do a little summer reading and see if I can't draw upon the wisdom of some experienced programmers before embarking on this journey.

Summer reading list:
I finished Accelerated C++ this week and just started reading Code Complete. The next few blog posts will probably be book reviews and design discussions instead of project status. Hopefully the time I invest now will yield faster, better programming down the line.

Monday, June 21, 2010

Much Ado About Nothing

So I thought that changing my game coordinate system from 'int' to 'float' would wreak havok and... I was wrong. Changing everything took less than an hour, cleaning up some warnings took 15 minutes, and the game now plays 10 times better.

This story has 2 morals:
  1. Carefully crafting modular software on the front end will save you from huge headaches when you (inevitably) end up changing something fundamental later.
  2. For bullet hell shmups, floats >>>> ints.

Sunday, June 20, 2010

Float it is

The forum gurus weighed in and convinced me to change everything to float. I'm starting tonight... this'll probably take a couple days.

Saturday, June 19, 2010

New Blog: MatrisGames

I need a blog dedicated to games that aren't mine, so here it is.

One step forward, one (massive) step back

Thanks to Darkness for shedding a little light on the memory leak courtesy of TTF_RenderText_Solid. Shmup02 specs are still in the works, but I might try to write up a game design doc based on the Shmup01 engine first. Of course, this would require a couple more modifications to the engine (such as storing level data).

In the meantime, one big dilemma I've been facing is whether I should be using float or int for all of my coordinates. More details can be found on my gamdev.net forum post. Ultimately, it sounds like float is the way to go, which means I'll need to do some serious reworking of the engine to eliminate all traces of int from the code. It's going to be a pain, but I think the long term benefits will be worth it.

In the meantime, stay tuned for updates on my Shmup01-based game!

Tuesday, June 15, 2010

TTF_RenderText_Solid is the devil

I added game state and gave the player a few lives, so Shmup01 FINALLY plays like a real game! There's still a lot of work to do, but one lovely thing I noticed is that, after the game is over, the process begins consuming approximately 12MB/second... given that the ENTIRE debug folder (exe, media, third party dlls) is just over 9MB total.... I found that to be absolutely insane.

Turns out that the SDL_TTF function TTF_RenderText_Solid is the culprit. My game over state basically said "keep on drawing the game over screen." Unfortunately, this included lines like this:

tempText = TTF_RenderText_Solid( font, "Final Score: ", textColor );
apply_surface( 350, 570, tempText, screen );

Every single call to TTF_RenderText_Solid was creating a brand new surface and assigning it to tempText. My faulty assumption was that the rendered surface only existed in the scope of assignment to tempText and then disappeared. This does not seem to be the case and it resulted in a heinous memory leak. For me, the solution was simply to have it render the text once instead of 30 times per second, but I could still see issues with regularly needing to update text on the screen (such as with scores or lives). I suppose you could pre-load a set of text surfaces (such as the single digit characters 0-9, etc), but that doesn't seem good either. I'm not sure if I'm missing something here or if I'm just running into limitations of SDL.

The good news is that I've been formulating some of the requirements for what Shmup02 will look like. There are still a couple gameplay bugs that I need to work out, but soon enough Shmup02 will be underway.

Sunday, June 13, 2010

Cleaning things up

Still no video, although I should be very close. I spent a lot of time cleaning things up and paving the way for smoother coding down the road. I haven't used any sort of revision control in the past, so I spent a lot of time learning about how it works and finding a good service. I ended up hosting my code for free on Assembla and using TortoiseSVN on the front end. So far, I'm very pleased with both of these products, and using version control in general! I'm amazed that I made it this far without using it.

I also spent a lot of time restructuring my inheritance hierarchy. Somehow, this led to a really nasty bug that has been in my code for a while but only surfaced after restructuring. Sometimes the program would crash AFTER I closed it, but the behavior was intermittent. The good news is that I became very good friends with Visual Studio's debugger. I still need to figure out where it debugs "from", as I could only get my game media to load if I used absolute paths instead of relative paths. The culprit ended up being a line in certain classes destructors:

GraphicalObject::~GraphicalObject()
{
SDL_FreeSurface( image );
}

I have no idea what SDL is doing when it frees surfaces, but I don't think my intuition was right in this case. My guess is that sometimes the program would try to access invalid memory or something as all the destructors were called (i.e. if a GraphicalObject frees an image that an EnemyShip is using as well, when the EnemyShip's destructor is called, there will be nothing to free).

I think I'm close to implementing the next set of features. Although I haven't made a ton of progress on the game in the last week and a half, I would say it has been extremely productive nonetheless.

Wednesday, June 2, 2010

Phases 1-5: Complete!

I'm very happy to announce that, on a very basic level, phases 1-5 of Shmup01 are complete. It's ugly as sin and the code is in desperate need of some cleanup, but it works. You can more around and fire bullets at enemies. The enemies don't move, but they can fire bullets at you. Other than some minor changes (graphics, adding a background, creating a notion of losing a life, and making the enemies aim at you instead of simply shooting down), Shmup01 is done. Once I implement a few more features and clean up the code, I'll begin speccing out Shmup02. I'm not sure what features it will include, but it will definitely include the notion of levels (which will basically be a series of enemy and bullet patterns) and the ability to use various weapons.

Hopefully I'll be able to post a video of Shmup01 shortly.