It has been recently brought to my attention that many people ask about game development, yet there aren't any articles on the topic. I've decided to shed some light on the general process of developing a game from start to finish. Keep in mind that that this is a generalization and WILL change from project to project.
Step 1: Choose Your Game Library
Unless you want to write your own library for all the dirty graphics/sound programming, you will probably want to get a game library. There are many game libraries out there. but they all offer the same base functionality (mostly...).
Features that any good library should have:
- Some system to load and play sound files
- Some system to load and display graphics
- At least some basic image manipulation (rotation, etc)
- Primitive drawing functions (circles, lines, rectangles, dots, etc)
- Functions to display text
- Multi-threading support
- Basic timer functions
Some game libraries include:
Step 2: Define the Concept
All games start here, merely ideas in someone's head.
First, come up with an idea for a game. Once you have a simple idea, expand on it. For example, if it is a board game, what is the objective/How do you win? What will the rules be like? etc. If your game will have characters or a story, create them. Make sure you have a pretty well defined concept of what your game will be when its finished. The more complex the game, the better you should plan it out in the beginning so you don't have to worry about the game itself while your coding. Keep in mind that your game WILL evolve as you create it.
Step 3: Plan Your Engine
Here, you will plan out the various components your game engine will need and how everything will fit together. Depending on the complexity of your project, you may not need to do this step. This is also a good time to test various parts of your engine that you have never implemented in the past, just to make sure they work before you put them in the main project source. Also, you should begin to design the structure of your classes here as well(if you are using OOP, which you should be).
Keep in mind, however, that there are pre-made engines out there, available for use in all kinds of projects.
Step 4: Code Your Engine (if your making your own)
Now its time to actually start coding your engine. This doesn't necessarily mean the game itself, but rather, core rendering, physics, file handling and the like, functions and classes that will be used to construct your game. However, depending on the complexity of the game, the engine and game code may be the same. Also, a more complex game will probably require a resource manager. A resource manager does what it sounds like, it manages your resources (graphics, music, sounds, etc). It also keeps your code clean and helps to avoid memory leaks. See an excellent resource manager below by
Xander314. Try to give your entire engine some kind of compact, easy interface for use as well. That way, when you program your game, you don't have search through source to find functions names and the like. An easy way of doing this would be OOP.
Like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//put related components into classes
class collisions {
bool check_col(obj1*, obj2*); //you should have a base object class that all
void handle_col(obj1*, obj2*); //game objects are derived from, for easy passing to functions
public:
void handle_all(); //handles EVERYTHING collision related
}Collision;
class rendering {
void bots();
void bullets();
void players();
public:
void draw_all(); //calls other functions for rendering
}Renderer;
//this allows collision management and rendering in your game loop to be as simple as:
Renderer.draw_all();
Collision.handle_all();
| |
Resource Manager by
Xander314
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
ResourceManagerB.hpp - Generic template resource manager
(C) Alexander Thorne (SFML Coder) 2011
<a href="http://sfmlcoder.wordpress.com/">http://sfmlcoder.wordpress.com/</a>
Manages loading and unloading of a resource type specified by a
template argument.
****************************************************************/
#include <map>
#include <string>
#include <exception>
typedef const std::string URI;
// exceptions
namespace Exceptions {
// thrown if user requests a resource URI not present in the manager's list
class URINotFound : public std::runtime_error
{
public:
URINotFound(const std::string& Message = "The specified URI was not found in the resource index.")
: runtime_error(Message) { }
};
// thrown if a resource allocation fails
class BadResourceAllocation : public std::runtime_error {
public:
BadResourceAllocation(const std::string& Message = "Failed to allocate memory for resource.")
: runtime_error(Message) {}
};
}
template <class Resource> class ResourceManagerB {
typedef std::pair<URI, Resource*> ResourcePair;
typedef std::map<URI, Resource*> ResourceList;
// the list of the manager's resources
ResourceList Resources;
public:
~ResourceManagerB() { UnloadAll(); }
// Load a resource with the specified URI
// the URI could represent, e.g, a filename
URI& Load(URI& Uri);
// unload a resource with the specified URI
void Unload(URI& Uri);
// unload all resources
void UnloadAll();
// get a pointer to a resource
Resource* GetPtr(URI& Uri);
// get a reference to a resource
Resource& Get(URI& Uri);
};
template <class Resource>
URI& ResourceManagerB<Resource>::Load(URI& Uri)
{
// check if resource URI is already in list
// and if it is, we do no more
if (Resources.find(Uri) == Resources.end())
{
// try to allocate the resource
// NB: if the Resource template argument does not have a
// constructor accepting a const std::std::string, then this
// line will cause a compiler error
Resource* temp = new (std::nothrow) Resource(Uri);
// check if the resource failed to be allocated
// std::nothrow means that if allocation failed
// temp will be 0
if (!temp)
throw Exceptions::BadResourceAllocation();
// add the resource and it's URI to the manager's list
Resources.insert(ResourcePair(Uri, temp));
}
return Uri;
}
template <class Resource>
void ResourceManagerB<Resource>::Unload(URI& Uri)
{
// try to find the specified URI in the list
ResourceList::const_iterator itr = Resources.find(Uri);
// if it is found...
if (itr != Resources.end())
{
// ... deallocate it
delete itr->second;
// then remove it from the list
Resources.erase(Uri);
}
}
template <class Resource>
void ResourceManagerB<Resource>::UnloadAll()
{
// iterate through every element of the resource list
ResourceList::iterator itr;
for (itr = Resources.begin(); itr != Resources.end(); itr++)
// delete each resource
delete itr->second;
// finally, clear the list
Resources.clear();
}
template <class Resource>
Resource* ResourceManagerB<Resource>::GetPtr(URI& Uri)
{
// find the specified URI in the list
ResourceList::const_iterator itr;
// if it is there...
if ((itr = Resources.find(Uri)) != Resources.end())
// ... return a pointer to the corresponding resource
return itr->second;
// ... else return 0
return 0;
}
template <class Resource>
Resource& ResourceManagerB<Resource>::Get(URI& Uri)
{
// get a pointer to the resource
Resource* temp = GetPtr(Uri);
// if the resource was found...
if (temp)
// ... dereference the pointer to return a reference
// to the resource
return *temp;
else
// ... else throw an exception to notify the caller that
// the resource was not found
throw Exceptions::URINotFound();
}
| |
Step 5: Graphics/Sounds
Based on your game concept, start creating your graphics and sound effects/music. As you get further into development, you will probably need to create more GFX and SFX and possibly discard unneeded ones. This step may continue through the entire process of development.
Step 6: Code Your Game
Once you have your engine complete and working, you can start to code your actual game. This involves anything specific such as rules, story, etc. Your main game loop will be here as well. This is the loop that runs over and over and updates everything in your game. See example below. If you made your engine right, this should be easier than coding your engine, and more fun! This will probably be where you add your sounds as well. Once this stage is complete, you should have a working copy of your game. Make sure you get it just how you want it!
Game Loop:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
//your loop will probaly be very different from this, especially for board games
//but this is the basic structure
while (!Game.lost()) //or whatever your condition is (esc key not pressed, etc)
{
Game.handle_input(); //get user input
AI.update_bots(); //let your bots move
Collision.handle_col(); //check for collisions
Game.check_win(); //see if the player won or lost
Renderer.draw_all(); //draw everything
Game.sleep(); //pause so your game doesn't run too fast
//your game lib of choice will have a function for this
}
| |
Step 7: Optimize
Just because your game works, doesn't mean its finished. Besides adding in last minute details, there will probably be optimizations that you can put in your code. This involves memory usage (try not to use global variables, check for memory leaks, etc) as well as speed (make sure your code isn't too slow or overly demanding on the CPU for whatever its doing). General debugging can also be grouped here too.
Step 8: Package and Distribute
Now that your game is finished, you need to package it and then distribute it as you wish. For packaging, try to keep it organized and put the final product into a single file (installer package, zip file, etc). This makes distribution MUCH easier.
Tips:
I've learned many things about making games, some things the hard way. Here are some things that you should do:
- First, stay organized! You should have a good organizational system for everything; your code, your graphics, your sound effects, etc. I would suggest putting code into different files based on what it does. i.e, collision detection/resolution code in one file, resource management in another, AI in its own file, etc. This way, if you need to track down a bug, it will be MUCH easier to find various functions, and possibly, the bug itself. Keeping the structure of your code organized can help as well (i.e. have classes for various purposes; rendering, AI, collision detection, etc. Rather than hundreds of void some_func()'s all over).
- Also, try to keep your code clean and efficient. Reuse variables where you can, minimize use of global variables, check for memory leaks, don't load all of your graphics/sounds at once, etc.
- Try not to hardcode too much data into your game. Instead, try to implement a system of loading data from files (maps, etc) This will really help keep your code manageable, and will allow you to update something without recompiling anything.
Some starting tips from chrisname:
You don't need to work that hard. What you need to do, is go through a programming tutorial (the one on this website for example). Don't do too much in a day, or you will get bored and unmotivated. Don't set a goal based on time, that doesn't work. You'll forget alot of what you learn if you stop halfway through a lesson. Work through the tutorial on this website ( http://cplusplus.com/doc/tutorial/ ). Aim to get through two lessons a day. Don't stop partway through a lesson (unless it's for a short break, that's a good idea) and don't do too much in one go, or you simply won't remember it. I recommend reading and copying out each example (not copy and paste; type it yourself, this will help you to understand what you are doing), compiling it, seeing what it does when you run it and modifying things to see what changes. I also recommend you look at other people's code (one of the things that has helped me is to take other people's broken code and try to fix it, although don't get too hung up on this because it is hard to read other people's code when you first start out). When you are reading, try to rephrase things: "If you can't explain it simply, you don't understand it well enough." (Albert Einstein).
Once you've gone through this tutorial, and maybe some others (I read about three different tutorials because it was useful to have things said in a different way - I find having something explained in two different ways is useful for understanding and remembering it), you could read through the tutorials for SFML ( http://sfml-dev.org/tutorials/1.6/ ). Learning SFML will teach you to make 2D games. I'd also recommend learning SDL ( http://lazyfoo.net/SDL_tutorials/index.php ) because lots of games use it and you will most probably come across it eventually.
After that, you should get into OpenGL programming if you want to make 3D games. SFML makes this very easy, and the SFML tutorial includes a tutorial for using OpenGL. For OpenGL, perhaps someone here can recommend you a book or tutorial.
Throughout all this you should remember that it is important to pace yourself. Don't try to absorb too much at once or you'll forget lots of it. And don't stay up until 3am when you have an exam the day after next...
There are many other things that can be done to make development easier and your game more efficient, but, these are the biggies.
That's my 2 cents on game development and the general process. If you feel that I am wrong somewhere, or missed something, please let me know.