Planning Code for Game Development (XNA)
There is nothing more detrimental to quick progress than poor planning. We’ve all had times when partaking in a project where we get confused and lost, or we’re coding away without any real purpose. I find this often simply comes down to not really knowing what the final goal of a class, project or function really is. If we can sit back, look at an overview and understand just what it is that we’re aiming for – a lot of coding becomes plugging in the gaps. I’m going to show you the general programming overview of Ikaroids to help you plan your project. You may develop your game in a completely different way – and this way is neither perfect or the definitive way to do it, this is just an example of how we did it to give you some ideas.
Game Screen Flowchart
Once you have your concept down and you have an overview of the main features of your gameplay, I like to do is consider is an overview of the general process that the user go through when playing your game. These are the screens / interfaces that your players will go through when playing your game. While these may seem unimportant, they give you an overview of the game and also set the technical limitations of the game – do you need a a single player character select screen, or a co-op or even 4 player one? Do you need an option screen for user editable options? What options will they be?
The Main Game Loop
The majority of the screens in Figure 1 will be stand-alone screens that set configuration parameters or load specific game objects for the ‘Main Game Screen’. The Main Game Screen is where you will spend the majority of your coding time (and asset generation time, of course!) and this will make up the actual game that you’re producing. Depending on how you are representing these individual screens in your programming (we made each screen a class that plugs into a DrawableGameComponent that acts as a screen manager), you will need to load the level and associated assets in the ‘LoadContent’ routine for the screen before the game loop starts.
I’m assuming that you’re programming for a console or a similar, linear programming environment (you’re not running your game through an event driven system, such as with a typical windows UI). In the majority of games, your main game loop will probably look similar to that of Ikaroids;
The main game loop is often similar for the majority of games, although the actual processes taking place at each stage are likely to be very different. In many simple games, there may not be any physics at all, and updating the entities in a game like Tetris is a rather simple affair. It’s worth writing down a few bullet points about what you need to happen at each of these stages, and this will give you a rough outline of how your game will play and what code and classes you need for the game to function.
Thinking about Classes and Entities
Now that you have a general idea of what will be taking place at each step of the main game loop, you can start to think about the code that you will need to make up your game. This can vary massively from game to game, but it’s always worth trying to ensure that you make every effort to (a) break as much as is reasonably possible into separate classes and (b) separate game logic from the game engine as much as possible. If you adhere to both of these strategies, you will find it much easier to fix and/or replace classes if you need to fix bugs or improve certain parts of the game, and you will also be left with a large number of reusable components that you can use in future projects.
With this in mind, I’ll give you a short run down of some of the main classes that we built for Ikaroids;
Now, of course, there are a lot more classes that make up Ikaroids. There are about another 50-60 or so that make up all of the separate entities, bosses, weapons, bullets, pickups, AI Packages, etc. However, the majority of those classes are extensions of the Game Logic classes shown in Figure 3. The Reusable classes are actually already in use in a second game project, and where we are using all but one or two of those classes. We’re also building more resuable classes in the form of a User Interface Kit to make producing user interfaces for the menus quicker and easier.
The Entity class above has a lot going on inside it, and it handles everything that any entity on screen requires. It contains a reference to a sprite (or a collection of sprites), a number of AI Packages, it’s position, it’s properties for the Physics Entities, it’s draw state (is it invisible?) and it’s game parameters (is it invulnerable? how much health does it have? what does it do when it dies?). There are many virtual functions in this class which are overridden by derivative classes. The EntitityManager stores a massive list of all of the entitities and then iterates through them to update them / draw them / see if they collide etc. As previously stated, this is by no means the best way of doing things, and is far from perfect – but it gives you a good starting point if you’re thinking of putting together your own game engine.
The last thing I’m going to talk about is prototype code for your game. Before you leap into coding your game in it’s final form, it’s a a good idea to write some prototype for parts of your game. As your classes are now reasonably small and modular, you can whack some code together pretty quickly to make sure it works. This is especially useful to get you thinking about just how something is going to work. Are you going to load your levels from XML files? If so, put together a mock XML file and file reader before leaping in and writing the final version. This allows you to see all of the problems and questions that you’d not thought of, so that you can answer them before writing your final one. This leaves your code free from hacks and generally cleaner and more reusable.
Prototyping is also useful for testing performance in your code. However, you have to be careful when it comes to performance. One word of advise – if your prototype is ‘good enough’, don’t spend all of your time trying to make it perfect and even more optimised. It’s not worth worrying about wasting a few CPU cycles if your game doesn’t need it. Drawing a thousand sprites to the screen is no problem at all for XNA on the Xbox 360, and while it might sound like a huge task that will need you to make sure that every bit of garbage is reduce and removed, in reality – it’s not a problem. And if your code runs fast enough – ie. doesn’t cause any slowdown for the game you want to produce, it’s not worth the time it will take you to make it work 10% faster. Don’t write messy code, but don’t worry about writing the 100% perfect optimal codebase either – if it works under a stress test of the worst conditions it’s likely to face, don’t waste any more time on it – put that time to better use on other parts of your game!
Last of all – be flexible!
Perhaps the most important thing to remember, is that however much you plan – you will always want to make changes after you’ve started coding. Be flexible. If something that you thought sounded great just doesn’t work in the game, you should remove it. We spent hours coding up a system where time would dilate near a black hole – but it just didn’t work as a game mechanic. Above all, it wasn’t fun – and so it had to go. This flexibility is key to making a good game, and having a clean code base that you haven’t hacked up, with a good clear definition of which bits of the engine plug in where, you can easily make these changes along the way, even if it’s different to your original plan. However, start your game without planning, and these changes will be much more difficult and may even stop you from finishing your game!
Over to you!
I’d love to hear of your own game planning and development experiences. I’m by no means an expert in the field yet and would love to hear tips and tricks from you or any improvements you might like to suggest to this article. I hope that you found it useful.