   Game Enigne: Putting it all together (design)
  Greetings!I have huge problems with my conceptual design of a game engine. My basic idea was something like this:1.) cWindow - class that creates a window, just a very small WINAPI wrapper, with one mayor routine virtual MessageProc(....) like WINAPI. One might override it and trap the messages.2.) cGraphics - class that wraps arround Direct3D, takes cWindow as input. But there is a problem: when cWindow resizes or requires repaint, how shall it notify cGraphics? For example: WM_SIZE event was rised, cGraphics does not know anything about it but the Direct3D device should be reset.3.) cEngine - basicaly a state machine or a stack of states. You just push a new state and it becomes active, windows message pump is being overtken and in non messaging moments Update and Render methods are called. But still it requires cGraphics to function and on the other hand cWindow too etc.. etc...The problem is that souch classes are no longer independant, it becomes somewhat of spagetti code. cWindow might require cState or cTimer and on the other hand it also might require cGraphic and cGrpahic requires cWindow etc... etc..I could use singletons, but I believe with a better design, it would be possible to have a cWindow that can function without any reference to cGraphic and so the basic blocks would be independand.I do not want to produce too many classes, but the basic things sould be stand alone and capable to join with other classes. Thank you in advance.   
  Well I hate the cClassname thing but here is an idea, make a cEvents class that fires off events that other classes can register to recieve.  There has been a lot of writings on this, search google and this site for more info.   ;  I'm with Mike on this one.. some sort of message pump/event system/client server kinda idea seems to be the best idea. I would suggest you look into boost signals/slots to register and fire events. Its what I have been using and its incredibly well put together.   ;  I really dislike the way you design it.What you do is a top down designcgraphics cengine cwindow.... thats all the top of your engine and so simple that you will fail with your project as soon as you want to create a complex systemIn my current design (its both for a 3d editor and a fps engine)Well I have written some basic subsystems that are required by any decent engine1. a virtual file system wrapper for physfs + required classes for file access ....2. texture,material,effect & shader systemstexture represents the texture you load from your harddrivematerial represents what you get out of these texturese.g.: a material defines the material type, the effects that happen on interaction with polygons with this material and which textures are useda 4 layer blended terrain would get a material assignedlike this*material 007*layer 1 = ground1.dds*layer 2 = ground2.dds...*layer n = groundn.dds3. the whole system depends one a lot of classes and can be reused in any further project so I keep them together and let them interact with anothere.g.: the material,effect and shader managers require access to the filesystem so I chose to use singletons to give access to read in all the shader defs...Think about you approach if you really want to structure it as simple as you do right now, this cries for design flaws that will lead to failure or cause a ton of work to refactor code.You should really design your code for reuseability otherwise its pretty hard to come up with a decent app in relatively short timeI am working on my code base for 3 years now and its still far from finished but  I really increase my productivity with each day I invest into the code basejust make  sure you have unit tested everything long enough or it will lead to nested bugs all over the project and thats really a pain ** *** ***Summary:Make your design more complex and let the classes of the individual subsystems interact with each other and tread these subsystems as a whole that is only touched by accessors(e.g.: public getters and setters)now design you application in a way that you can unify these subsystems to a big whole that works well. The only unreusable and redundant code is that, that links the subsystems and that is a tiny part of the whole project   ;  I would make the seperation between 'engine' and 'library' even more clear...You could make a base-library (.lib, .dll), which (speaking in the example of the previous poster) contains your filesystem and a resourcemanager whichcan use the filesystem. Now have your application link with the lib, and inherith from the baseresourcemanager to add specialized behaviour (textureMgr, materialMgr, ...)Using timer-instances spread out over the code usually give headaches.Instead, you can abstract Timers away by having your renderloop all 'advanceTime(float elapsedTimeInSeconds)' on your engine-parts. Only the mainloop has the timer, and updates components on each iteration.This has the advantage you can easily add things like moviecapture (whereyou want a constant framerate, and your hdd won't be quick enough to writedata in realtime), or for making sth like a slowmotion (just scale yourtimedelta with some factor in the mainloop).cState sounds like a perfect canditate for a template/statemachine. YOucan derive your concrete states from the base-class, and use a genericstatemachine template in which make a few calls to say which transitionsare valid.>a cWindow that can function without any reference to cGraphic and so >the basic blocks would be independand.You could put your windowing system in a seperate library (reusability) and let it 'talk' to your graphics-system over an abstract interface - your app can then derive from this interface and make calls to your 'real' graphics-system.;Quote:Original post by Basiror...3. the whole system depends one a lot of classes and can be reused in any further project so I keep them together and let them interact with anothere.g.: the material,effect and shader managers require access to the filesystem so I chose to use singletons to give access to read in all the shader defs...A lot of people would argue the use of singletons is a design flaw.  Our engine has 1 singleton and I hate it.  It's our logger, there is better ways to do it though but at this point I'm not willing to change it (I didn't make it).  There are places for singletons but they should be an exception rather then a common thing (imo).   ;  Why shouldn t I use singletons when I consider a subsystem as a whole? I won t bloat my code with them, its just a way to access data directly without passing a ton of function parametersAnd they have the advantage that you can make them multithreading compatible on the fly opposed to simple global variables.I see no reason why you shouldn t use singletons. In my opinion every sub system that exists only once should be represented by a singleton.;  Because, honestly, if you're using a singleton its normally out of laziness or bad design.  Rarely can you flat out say you NEED it as there are normally better ways around it.  I'm not sure where you went to school but using globals in all the classes I seen (C++ classes) was a big no-no and earned you docked marks (10% on average PER global up to 50%).Why does your collision detection subsystem need access to your sound manager?  If you only want one instance of either of them, say so in the documentation."Try to follow the flow of an app using singletons. (To summarize, any part of the code can call any part of the code at any given time. The joy!)" -- SeriemaRead Washus great writings on "Singletonitis". Part 1, 2, 3.Here's a link to a GDNet journal entryIf your sound manager needs access to your renderer, you have other serious issues besides singletons anyways ;-)Like I said, our log manager is a singleton, but a junior coder implemented it and while I was on vacation.  It's now all over the engine and the one item I can almost justify as a singleton pattern.  But when I have spare time it too will be going the way of the Dodo bird.   ;Quote:Original post by Mike2343Because, honestly, if you're using a singleton its normally out of laziness or bad design.  Rarely can you flat out say you NEED it as there are normally better ways around it.  I'm not sure where you went to school but using globals in all the classes I seen (C++ classes) was a big no-no and earned you docked marks (10% on average PER global up to 50%).I didn t learn C++ in school. I learned it on my own. And you got a PM why Singletons are no sign of lazyness or bad software design of use properly in the subsystems only where they ought to be usedClearly nobody would say the use of a singleton to access the sound manager in the collision code is good design. But using a singleton class type with a well defined access api in a subsystem only that can be considered as a whole is still far better than passing information by messages or passing tons of base class pointers around to access the information needed.The access semantics of well defined subsystems won t change very much from project to project nor will a well defined codebase change very much so from the point of view of code reuseablility singletons can even improve reuseability.In my current projects I only have to change 1 line of code to plug in another class implementation without changing the access api at all.here an example of 3 subsystemsthe material/shader system, the geometry manager and the filesystemboth a geometry manager and the material system need access to the filesystem to load in the desired resources.The access semantics of a filesystem won t change anyway within the next 10 years.: open,close,read write seek ....Now the material systems provides access to resources like textures ....so the render needs access to retrieve handles that can be boundand he needs access to the geometry data both wont change very much within the next few yearsthe material system passes the texture data to the graphic card and stores a handle, you can access this handle from the render as described above or you can  let the geometry system store the handles in a preprocess at load time so the renderer only needs access to the geometry system in the endAnd the number of singletons reduces to a minimum and certainly won t pollute your code in any way .   ;  i have lots of managers. They are not singletons. I have a main device class contains references to all my managers. And all my managers have a reference to the d3d device So i go like this. (just an example of what it might look like and this has its own issues)device->getSkinManager()->ActivateSkin(skinID);device->getEffectManager()->BeginEffect(effectID);device->getMeshManager()->RenderMesh(meshID);device->GetEffectManager()->EndEffect();if a manager needs to know about another manager i pass a pointer and make it a friend class but i only do this as a last resort. E.g. Mesh managers has a reference to my Primitive manager. I cant stand passing references per function. It makes code look ugly. there could be a design flaw in your singleton and a remote piece of code could use your singleton incorrectly when it shouldnt be touching it at all.You cant say for certain you wont have more than 1 instance. You might extends your engine to use 2 monitors which uses multiple devices so now you might want another instance of your managers.It would be nice if you could make class members only public to some functions.   