Sign in to follow this  

game engine design

This topic is 4704 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been reading a book on OOA and design, and patterns, and i want to start on a d2 game engine. I am having trouble getting started because i am always thinking i could read more before i start and would be able to make a better design. How do i know when to put the book down and actually start. Also i have a few questions about a rough design i have been thinking of for the graphics part of the engine. It seems i would want a graphics class, which would handle initialization and shutdown of a grpahics api, but should this graphics class render sprits, or should a sprite object render itself. By information expert it would seem a sprite object should render itself. Also it would seem like a good idea to make the graphics class an adapter, that way i could plug in any graphics api i wanted. Are these good ideas. Does anyone have suggestions on things i should be thinking about as i start this design. Thanks

Share this post


Link to post
Share on other sites
Since you are making a 2D engine (right?), I think it would be best if the graphics system handeled the init/deinit of the graphics system. That is the approach I am taking. The reason for this is if you want to make an engine, it *should* be able to be used again in other projects wiht little modifications. If you happen to change around your sprite structures (hey it happens), then your graphics component will probabally be broken, since the graphics component is dependent on the sprite structure. Now if you made the graphic component only init/deinit the video, which is what I did in my engine, you can easily reuse it since it will not change (for the most part).

Instead, what you should do is have a "sprite" manager that will interface the graphics component to the sprites, that way you can easily change interactions between the two. The manager would basically store the sprites and you will access/process them through the manager. This design allows for more flexibility and organization.

Only go through the pains of making your graphics component support different api's if you plan on using them. Designing an engine that is very specific is challanging enough as it is, making a generic engine that supports multiple APIs is quite a task. I have done it before though so I can tell you I am say this from experience.

If this is your first engine attempt, I would suggest just picking one api and using that. I can also tell you from experience that your first engine, if you are able to complete it, will not be a master piece. I have worked on many engine projects of my own, none of which I have complete and used to successfully make a game. I'm sure that will change soon,, b/c of the new engine im working on =), but keep that in mind.

I hope this advice helps, if you have any more questions feel free to ask. I've been finding myself to be giving out quite some amount of advice on engine programming [wink]. Best of luck!

Share this post


Link to post
Share on other sites
thanks for the advice, i'm sure i will have more questions later. I have made lots of games in the past, but never a well thought out and designed object oriented engine. I'm excited and nervous to start. One question i have is should all the sub systems be derived from the same base class. So say graphics, sound, and input are all derived from a system interface. This interface would just define init, and shutdown. This way my egine could have a list of systems it had, and treat init, shutdown of these engines as though they were all the same. Good idea, or not?

Share this post


Link to post
Share on other sites
Quote:
Original post by corrington_j
thanks for the advice, i'm sure i will have more questions later. I have made lots of games in the past, but never a well thought out and designed object oriented engine. I'm excited and nervous to start. One question i have is should all the sub systems be derived from the same base class. So say graphics, sound, and input are all derived from a system interface. This interface would just define init, and shutdown. This way my egine could have a list of systems it had, and treat init, shutdown of these engines as though they were all the same. Good idea, or not?


Well I am in that same bind myself. I originally made all the components as independent controls that are their own dlls and such. When you wanted to use them you just included the .h file and everything is ready for use (I auto linked the .lib). That kind od articheture worked, but I was looking for something else now, I want all the components to be dervived from the base class, so I can easily just call create and destroy. I think this is a great idea, and allows a lot of flexibility, but it is easiy to idealize than implement. You will have to think of a way so your engine can easily load these components - either use .dlls or make it part of the base engine. If it it part of the base engine, then there is no sense in making all the dervivations and using inheritance. If you use a plugin scheme, the end user can make their own components and *easily* itnerface them with your engine. This kind of design would be the best, but then again, it will take some thought. I am wokring around with deviving componments and see how I want to use them. I can reinterpret cast the base class pointer, so I have access to the specific fuinctions of a class, but I'm trying to decide what are the long terms applications for it.

I say you should just start trying out stuff, see what works the best for you. As you go along, youll get more ideas of how to do things. Just be patient and you'll find yourself a good desing in no time [WINK]. Goodluck!

Share this post


Link to post
Share on other sites
The beauty of OO design is the ability to make changes without worrying about breaking everything. With sloppy design, all the pieces make assumptions about all the other parts, sprite code in graphics init, sound code in the game code, etc. Use classes keeps the parts separate. They say OO design is great because it makes code reusable, but in MY opinion, its greatest benefit is allowing you to REWRITE code without having to hunt down changes to make elsewhere. Freshly written code is good (although potentially buggy :), but rewritten code can be a near-perfect fit for the task. "You don't know what you don't know", so the second shot will practically always result in much better code.

Also, remember that OO is best when you can apply its concepts to GROUPS of objects. For example, there should be an object which maintains a bunch of sprite objects. Remember, drawing one sprite at a time would be slow - if you could find a way to draw them consecutively, you would see huge performance increase due to good cache utilization (for example, the cpu could keep the drawing code in its cache, drastically increasing performance). In this example OO design is generalizing the sprite itself, to make it simpler to draw all the sprites in one stream of render calls.

My advice is to push forward. Do NOT get bogged down waiting to come up with the perfect design. Sketch it out, get it working - you will realize which parts are a mess and which parts are great. THEN, rewrite the messy horrible parts.

It's amazing how much you can accomplish by refining an existing design.

[Edited by - doug65536 on December 25, 2004 12:21:51 PM]

Share this post


Link to post
Share on other sites
Ah, one more thing. Test your graphics code on LOTS of different video cards. If you use OpenGL, this is not really a major issue, but if you are using DirectX, TEST IT ON MANY COMPUTERS!!!! DirectX is an absolute nightmare for compatibility. If you get it working on your own computer IT MEANS ABSOLUTELY NOTHING - It's almost guaranteed you'll be trying to track down compatibility problems on different hardware. :)

You are making it 2D, so I assume you are going to use DirectDraw. Test it on many different machines - I guarantee you'll be adding workarounds if you use DirectDraw. :) DirectDraw has this funny thing where surfaces are "lost". If the user switches away from a full screen program, all it's video-memory-resident surfaces are "lost". Your code has to be able to handle surfaces being lost at any time.

I know it seems I am getting carried away with DirectDraw specifics - I am not - I am outlining a case where one subsystem will need refinement, and an OO design will keep is separate enough so that when you come up with a great design that handles lost surfaces, it can be rewritten and integrated into the rest of the game.

Share this post


Link to post
Share on other sites
The best resource I found for designing a highly-compatible, well-structured, object-oriented game engine is the book "Focus on SDL" by Ernest Pazera (Major contributor to the GameDev.net community)

Info: http://www.gamedev.net/columns/books/bookdetails.asp?productid=206

However, I guess you did say that you wanted to put down the books tough... anyway, it's just a suggestion.

Share this post


Link to post
Share on other sites
Quote:
Original post by GaMe wIg
The best resource I found for designing a highly-compatible, well-structured, object-oriented game engine is the book "Focus on SDL" by Ernest Pazera (Major contributor to the GameDev.net community)

Info: http://www.gamedev.net/columns/books/bookdetails.asp?productid=206

However, I guess you did say that you wanted to put down the books tough... anyway, it's just a suggestion.


Well I'll be...I just bought that book yesterday - but I haven't had a chance to read it yet, but I flipped through and saw the stuff you are talking about. I'm just like *wow*, I really got my money's worth! I can't wait to read it now!!

Anyways, corrington_j, you may also want to take a look at isometric game programming with Direct X 7, also by Ernest Pazera.

Share this post


Link to post
Share on other sites
Heres's how my engine works. It's a dll that contains all that I need.

I've managers as singletons, so each class functions can communicate with everyone.

cSingleton
+->cEntityManager : manages cEntity (like mesh, sounds, zones...)
+->cFontManager : manages cFont (.ttf or bitmap fonts))
+->cSoundManager : manages cSound and cMmusic
+->cTextureManager : manages cTextures (.bmp, .tga and webcam video)
+->cTimeManager : manages cTimer
+->cScreen : manages cScreen (all differents ingames screens like when you press escape to switch screen)

cEntity is the abstract class which contains ie the following functions :

class cEntity{
public:
void SetState(E_STATE state);

bool Process(E_MSG, long, long) = 0;
void OnTouch(iEntity*) {};
void OnLeave(iEntity*) {};

protected:

iVector3d<float> Position;
iVector3d<float> View;
iVector3d<float> UpVector;
iVector3d<float> BoundingBox[2];
iEntity *Parent;

private:
E_STATE entityState;
};



So as You can see, the manager know all entities but each entity has the responsability to draw itself, move itself, update itself... To do such a thing, the manager use the function cEntity->Process() function.

Hope it will help You.

Share this post


Link to post
Share on other sites
Quote:
Original post by iliak
Heres's how my engine works. It's a dll that contains all that I need.

I've managers as singletons, so each class functions can communicate with everyone.

cSingleton
+->cEntityManager : manages cEntity (like mesh, sounds, zones...)
+->cFontManager : manages cFont (.ttf or bitmap fonts))
+->cSoundManager : manages cSound and cMmusic
+->cTextureManager : manages cTextures (.bmp, .tga and webcam video)
+->cTimeManager : manages cTimer
+->cScreen : manages cScreen (all differents ingames screens like when you press escape to switch screen)


Question - how to the objects communicate with each other? Is it by using the singleton variable itself or via some other system?

Share this post


Link to post
Share on other sites
This was a tricky part, but since I use singletons, objects just need to get the good manager and use the good function to communicate with everything.

ie the cSoungManager::Foo() function need to output some text in the debug log (using cDebug() I forgot to mention in my previous post as the DebugManager) :

void cSoundManager::Foo(void)
{
cDebug *debug = cDebug::GetInstance();
debug->Print("pouet");
...
debug->Print("All ok !");
}

ie the cRender::Update() need to know elapsed time since last frame :

void cRender::Update(void)
{
cTimeManager *time = cTimeManager::GetInstance();
float elapsed = time->GetElapsed();
....
}

Share this post


Link to post
Share on other sites
Drew, the idea about emulating the Windows Message pump is a really good one. You are on the right track with that. The one issue with having Singleton's everywhere is that you don't cut down on the amount of dependability in your system. In other words, if you're not careful, it becomes really easy to make brittle OO "spaghetti" code. It is good to think of your architecture in more of an event-driven way.

For example, let's discuss the Sims. The Sims is very event-driven (I may be off on these descriptions, it's been a while since I read the article about the AI in Sims 1). In Sims 1, a Sim was actually rather stupid. A Sim just had core needs it needed to fulfill and had no idea how to fulfill them. The objects in the world basically broadcast a message of what needs they can fulfill. So, the Sim didn't need to know anything about what objects did what in the game world. Not only did this reduce dependancies in the code, this also made the whole expansion pack mechanism possible. If a Sim had to know about all the different objects in the world (or if any object for that matter had to know about other objects in the world), the expansion pack mechanism wouldn't be very feasible because these objects would have to be updated everytime a new object was added that it needed to know about.

Anytime you can make a system event-driven, it "Is A Good Thing." Not only will your design contain less dependancies, but you will have an easier time building new features into your game. In this sense, Design Patterns are your friend, especially patterns like the Observer pattern.

Another example, if your system has a message pump and is message-driven, then to implement a replay feature, all you would feasibly have to do is record what events pass through the system when. Then, when you replay the game from a recorded file, the system simply pumps the recorded messages into the message pump, and the rest of your game doesn't know the difference :D.

Share this post


Link to post
Share on other sites
What you want is a subscriber/publisher system, where objects can "subscribe" to receive events from certain "publishers" that send events. So an object might subscribe to your input system to receive key_down events, and any time a key is pressed, your object gets an event with the key code included. Or the object might subscribe to collision events, state change events, etc.

The following link might help you get started, and although it's Java oriented, it can be accomplished in C++ (or whatever language you like) just as well.
http://www.javaworld.com/javaworld/jw-03-2003/jw-0328-designpatterns.html

Share this post


Link to post
Share on other sites

This topic is 4704 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this