Steps and process for creating a game engine

Started by
26 comments, last by nef 17 years, 10 months ago
Ok, so since my last post, I have started a new workspace, and am working on my new version of my engine.

After 219 lines of code, I have a simple program that runs, opens a master settings file that will always be named the same thing that contains information for the program to run like display mode, window title etc.

It opens that, reads the data, and makes the changes to the application.

I also have a simple Error Handler that handls ALL errors through out the program.
I simply make a call like this to my functions that could possibly return an error .

// INITIALIZE APPLICATION
if(ErrorHandler.Report(Application.Initialize()) != 0)
{
Application.SetLoop(false);
}

This code right here initializes the application, makes changes, and if the settings file cannot be found, the error handler handles the error by displaying a message box stating the error, and then I opted to add additional code by telling the application to stop the loop, and shutdown.
Advertisement
To be blunt, it seems like you're well behind the point where you should be considering any sizable application, let alone a game engine. You might be better suited to aim for something slightly smaller, or with less intent on doing it right. Doing everything right is fine and all, but is quite slow; you generally learn more from doing things wrong anyways...

That said,

Quote:
Ok I have been working on a game, and so far my code has been getting all messy and crammed, im getting stuck on a lot of parts to the game engine, but I think my main problem is I dont know the steps to creating one!


Actually, it sounds like you don't have a high level design document, or much forethought into the actual design before coding. Helps with cram and clutter.

Quote:
Do they load all of the games sounds when the game is 1st loaded, or between each level change.

What does an engines loop cycle look like!

Are all aspects of the game dealt with in one, or by subject.


No, generally sounds are loaded as needed, or batched along with the level or some 'theme'.

The loop cycle, like what order to do things will vary depending on the game, the design, your skill, your teams' composition... Multithreaded apps might look similar in their loops, although in practice the concurancy makes them hard to diagram.

Quote:
Do I do the thing where one function checks for input at the top of the loop, and then later down in the loop, the graphics function updates the graphics and then after that a sound function checks for the variable and plays the sound, or can I do something like this...


Or you can have the key trigger an event which has the various reactions bound to it, or the key can trigger a message that is handled by the various movement reactions... Those sort of designs tend to be more friendly to keybinding and the such.

Quote:
if it doesnt matter id rather do it the 2nd way, since it would be more organized, and when there is a problem, I can say "Hey, my footsteps arnt playing, why!" and I look in the player move section, instead of going through 3 or 4 different functions to mae sure that all the variables are being passed and getting there. Would probably be faster that way too.


And then you'd also have to include the sound/gfx/networking/etc headers in c++ which is perhaps undesirable.

Quote:
For the main app loop, what do I do? (states)


I wouldn't do it that way, though it's fine for simple games. A proper state system or a psuedo state system built off of the UI are perhaps more flexible.

Quote:
I dont think there is, but is there an easy way to store game files in pak, pck, or cab files?


I hear zlib is easy to use, but who cares? Make it work first. It's easy to fiddle a little with loading code later.

Quote:
Im trying to give real world aspect to my classes like my book said.


Which book if you don't mind answering? Personally, I find basing "object" in OOP around actual objects (rather than conceptual objects, or solutions) is... failure-prone.

Quote:
I simply make a call like this to my functions that could possibly return an error .


But what of ones that return values?
As Telastyn mentioned, starting off with something simple and learning from your mistakes may be preferable... the basic concepts for the game loop don't really change, and you'll have some codebase for some of the lowlevel stuff to work off to create something bigger. Maybe something like a nethack clone?

About the gun, what you mean is composition, where an object contains other objects. That's fine. I'm also not sure if giving the system additional complexity by basing it off reality is a good idea or not. The process of firing projectiles and applying damage is probably very similar between different weapons.

Something like zlib can help with creating resource archives, but first you may want to create an interface to the filesystem that abstracts away the actual technicalities of whether the file is in an archive or not (or it may abstract the whole filesystem, though you may not have much reason to do something like that right now). Then you can do both types of access transparently.
Usually a game engine is divided in several separate layers. First you could have some basic layer where all system specific code resides. This can be handy because all your higher layers will use this, so once you want to port your engine to another OS, you only have to port this basic layer.

Next layer could be an abstraction. For example there is no such thing as a Bullet or Player here, instead you have something like a GameObject and you try to find what all GameObjects should have incommon, for example (position, velocity, shape, ...).
A very basic layout could look like this:

class GameObject {   Vector velocity;   Point position;   float mass;//to be implemented in your next layer. //Or you could let this have some basic implementation //which draws primitives (without textures).   virtual void draw() = 0;    void integrate();};class Engine {   AbstractMap *map;   float gravity;   void draw(); //calls AbstractMap.draw()};class AbstractMap {   GameObject *objs;   void draw(); //draws each object};


And in the next layer (if really needed), you could make a more specific implementation, something like you are trying to do now.

For switching back to menu's and such you could work with a frame or something...
class Window {   Frame *frame;   void setCurrentFrame(Frame *frame);   void draw(); //calls Frame.draw();};class Frame {   virtual void draw() = 0;   virtual void processInputEvents() = 0;};//and then an implementation in your game...class MenuFrame : Frame {  //as a result of an option select, you call window.setCurrentFrame(someOtherFrame);};class GameFrame : Frame {};class OptionsFrame : Frame {};
Thanks for all the info.
What I have so far is pretty basic.

I can make a simple game, and build upon the engine and make changes as my programs increase in size and difficulty.
You may want to include a scripting language of some kind "from day one"; I need to start doing this as well as I have a few games where I've started and expected to install a scripting engine later, and then never got around to it (ending up with piles of special-case hacks instead).

It's also super useful for prototyping.
Quote:Original post by Anonymous Poster
Honestly I strongly recomend Game Coding Complete, Second Edition by Mike McShaffry published by PARAGLYPH PRESS. It's one of the few books I have read that goes over in detail, the process of creating a game engine using stratagies comertial games use. It goes over a framework for your application, a cooperative multitasking process manager, a resource loader, events and triggers, scripting languages, audio, graphics, and scene graphs.


I second that. Dispite the book having typos here and there, it is still a very good book for someone just getting into game engine programming. It will tell you what you need to know to get a good idea of how the game engine works and how to program one. It even gives insight on what it is like to work in the industry. But in my opinion, the code is rather sloppy. I think it's just his style. So that's good too, if you know what good code is and is not. He at least gives you a solid foundation for starting out.

There is a difference between a game engine and a game. A game will implement the game engine at high level to function. It seems as though what you're trying to do is make the game a part of the engine. But that's ok because a hard coded game will run faster than a scripted one. But you just might want to make a totally different game afterwards with the same engine, and the engine has all this stuff built in for like an FPS, and you don't want to rewrite the whole thing, so you should think about keeping the game code and the engine code separate.

The engine should handle things like scene graphing, resource management, messages (especially when running in an OS like Windows), messages between objects in the engine, sound, networking, physics, user interface, and probably a few others. Each of these topics goes pretty much in depth.

Here is a simplified version of how I'm doing it, and I have found that it works pretty well. There is no short way to say this. I'll start from the top down (hence, the steps):

There is the high level code which is where the main() function is. This is your high level code. If you want to load a scene, you should do it from here. In this high level code, you have a variable of type CApplication, which is a user made class, which is the application layer.

CApplication is where I have a high resolution timer for stopwatching the time between frames. Each frame, I send the amount of time that has elapsed down the update pipe, and this time will go through mostly all objects in the game engine telling them how much to update. It keeps everything in sync (I also pass down a pointer to a stucture containing input from a mouse and keyboard so that objects can update themselves accordingly, and input is updated in the CApplication class as well). Rendering is similar in that it follows the same pipe or chain of objects, but instead it passes down a LPDIRECT3DDEVICE9 object so that scene nodes can draw themselves.

So, there's the application layer, which is pretty much code that will handle what your program does in the OS. This is also where the main loop is located. If the OS tells your program to close, the application layer will handle this. I implemented this as a single class.

Inside this class is another member variable of type CSceneManager, another user made class that can handle any number of scenes. So inside the CSceneManager class is a list (a special templitized class for storing objects or pointers to objects) of CScene objects, another user made class.

Inside the CScene class, there is an instance of CRootNode, which is another user made class that derives from CSceneNode. I like to think that the scene node is the life and breath of the game engine, because without it, you can't draw anything, you can't interact with anything... These scene nodes are basically the objects that live inside of your game that the player can interact with.

Scene graphing is probably the most core element of a game engine, so you might want to learn about that really early on. Learn about scene nodes and stuff. Get that down and you can move on to the other parts. The scene graph is practically the engine itself.

Here's a few things to keep in mind:
When you go in to program your game engine, you want to think about flexibility. A scripting engine can help a lot with that. But if you're just starting out with your first engine, I wouldn't bother (but it wouldn't hurt to have one).

Another tip for keeping things flexible (and every engine should impliment this in my opinion, unless there's something better) is to use a single base class for each type of object. Especially with the scene nodes, you will want every type of scene node to inherit from the same scene node class, so that you can have different types of scene nodes, like maybe a mesh node that has a vertex buffer and index buffer or somthing like that, and then a light node that controlls the lighting in the scene, and also a camera node that controlls the view and projection matricies on a frame render, and stuff like that. And they all inherit from the same base class, so you can stuff them all into a single list and go through them sequentially. I would recommend keeping the lights and camera in separate lists from the other scene nodes though so that you can update those first before the rest of the scene nodes.

I could go on about scene nodes and tell you what they actually are and how they work and how to make one, but there are other places to learn that.

Really, the best advice though, is to get a book on the subject. Get several books. That way you can read through it over and over untill it sinks in and actually get it. Not all books are geared toward beginners though, and many that are are meant for like, the consumer, the person who really likes playing games all the time and thinks that because they are good at playing them they should be good at making them. Yeah, stay away from those books. They will teach game programming in another language or to a specific game engine.

So, I totally went on a long and boring rant, and although I tried to keep it short, my thoughts just spilled. So I guess you can say it's no easy job to learn this stuff, but it sure is fun and rewarding when you get somthing that actually works the way you wanted it to.
Quote:
Really, the best advice though, is to get a book on the subject. Get several books. That way you can read through it over and over untill it sinks in and actually get it.


Except of course that what you recommend isn't the best advice, and it isn't going to sink in (at least not to any useful level) until you get practical experience fiddling with it; seeing what works, what doesn't, the (dis)advtantages, and why.

Wow nice write up :)
Thanks.

I am having trouble with this for some reason:

I am getting this error message

main.obj : error LNK2001: unresolved external symbol "public: int __thiscall igeSplash::PlaySplash(char *)" (?PlaySplash@igeSplash@@QAEHPAD@Z)
Debug/InsaneCombat.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

when I try putting a point in my function.

Look here at how I prototype it.

int PlaySplash(char *sSplashFile);

In this function, it opens up the splash CFG file and plays the splash screens (if any). I decided I am making a game engine 1st for a 2D game, sorta like starcraft. That type of game (although I know not nearly as grand).

I get that error, but the functions in the DSDK to use files need a char * variable to work.

I am stuck here :/
It usually means you forgot to write an implementation for that function. But if u did, try a full rebuild.

This topic is closed to new replies.

Advertisement