Sign in to follow this  
ChugginWindex

How to structure a game engine.

Recommended Posts

I've been working my way step by step through designing my first 2D game engine. I've done similar projects in the past (actually more like attempts) and I always get hung up at the same point. How do I separate the different parts of the engine? I know how to use classes, create DLLs, precompiled headers etc. as well as how to use design patterns such as the singleton, and I use them in my code where I think it's appropriate. However every time I think I've successfully separated my classes and code so that I have something like an Engine which runs a Graphics system, an Input Manager, a File I/O manager, etc. I can't take the next step and actually build anything upon this because I quickly realize all of these are so interconnected in order to function properly that for something like a sprite to be rendered it has to know about all of the inner aspects of the engine itself, which just doesn't seem right. I guess what I'm asking is if there is a way to do something similar to what HAL does on an Operating System that works between the engine and the game code, an EAL? I've searched all over the web for good articles on how to design an engine, but they all just tell me the different pieces that I need, not how they communicate. I've thought about events but I have little knowledge of how to implement them either...

Share this post


Link to post
Share on other sites
It seems to me that you focus too much on classes while programming.
It's never a good idea to rely on implementation, so no code of yours _ever_ should use a certain class directly.

The trick is to stick to the rule "program to interfaces, not implementations".
Interfaces define the outer receptance of a group of classes, a single class or a complex sub-system.
The thing is, you don't know what's behind an interface, and you don't have to -
you simply stick to using what the interface offers, period.

Why this imperative for abstraction?
It keeps your code clean. It keeps your design clean.
And, if done properly, it reduces coupling between classes.

Let me give an example...
Imagine you have your scene graph update all the items in it.
If you stick to just classes, you'd have to differentiate between huge amounts of classes to do so, but if every class requiring updates implemented an IUpdatable interface with a public update() method, you could treat all kinds of objects the same way, and could be presented with all kinds of objects without even knowing their implementation at all - they could be even outside of your own assembly unit, so e.g. plugins written by some users or whatever you could possibly think of.
All of these classes would simply just follow one rule - implement a method called update(), specified by an interface IUpdatable.

I hope you get the idea ;)

Another thing you mentioned is design patterns - especially Singleton.
Use them with caution - they tend to bloat your code when you don't fully understand them, as in the saying "When all you know is nails, everything looks like a hammer".
Design patterns are great in many places - but, in many places they aren't, because you're not using the right pattern at the right place.
And using the _wrong_ tool to do the job just complicates things.

Finally you spoke about events.
Events and event-driven programming are a complete paradigm of their own, which is the right tool for some applications, and for some it simply isn't.
The problem is, events are ideally suited for asynchronous operations, as they are non-deterministic by nature.
For use in a game engine, at _some_ places events are just fine and have their advantages, but at a greater scale, they make things worse.
Events can be used to locally communicate changes in state between objects, but they do at a cost (event handler execution, instantiation of event objects, destruction of event objects, and possibly raising other events, too).
This cost is it which has to be taken into account when using them.
For example, updating an entire engine with events, where each and every object receives the same event, may seem thrilling - but, updating objects with method calls may be more efficient.

This may seem a bit negative, but there is no super-remedy for everything in software design.
All these things are a bit generalized, though, maybe it would help you more if you could give some insight into your engine as it is right now, so one could point out possible solutions.


[Edited by - lucem on January 30, 2008 5:21:18 PM]

Share this post


Link to post
Share on other sites
This is a common question and one that has a lot of answers. Some answers are better than others, but for the most part there are shades of grey. I can tell you my thoughts. Others will have different opinions, equally valid.

I use a hierarchy of C++ classes. I'll have a top-level "GAME" class, which has (as private members) a GRAPHICS class, an INPUT class, a SOUND class, and so on. I called these classes "systems" or "subsystems". For example, I'd call my SOUND class a subsystem. It exposes a public interface to do the job and contains a number of subclasses and objects as private data.

I think it’s good practice to try to minimize subsystem dependencies. If one subsystem has to know a lot about other subsystems, it may mean that the way you’ve architected what data and functionality goes into each class isn’t optimal.

I recommend that you architect your classes so that they can do their job without having to know about other subsystems. Put any interconnection code in a higher level system that knows about both of the subsystems that need to work together.

Let’s take a simple example of a keyboard input subsystem that takes care of the low level stuff associated with reading key-press events (and possibly re-mapping them based on key assignments), and a player subsystem that has a bunch of actions that can be performed. If implemented the way I'd recommend, the keyboard subsystem doesn’t need to know anything about a player, and a player class doesn’t need to know anything about the keyboard. Instead, there needs to be a higher level system that knows about both the keyboard and player subsystem. For this example let's just say that our GAME class is going to be the higher level system — but really it’s any appropriate higher level system (and doesn't have to be the top level system). Anyway, the game system ties the keyboard input to player actions via some method. Since this is a simple example, I’ll say the game system will, each time through its main/update/tick loop, ask the keyboard input subsystem if the “jump” key is pressed, and if so, it tells the player subsystem to jump (by, for example, calling a player::jump() function).

I try to avoid singletons and globals as much as possible, because they introduce interconnectivity where you really don't want any. I think the advantage of avoiding singletons and globals is that you don’t need the player or keyboard to know about each other. This improves compile times, but much more than that, it makes your code very modular. If you want to add joystick support, you don’t have to change the keyboard or player classes at all. Likewise, if you want to add network support, you don’t have to touch your keyboard or player classes. If you need to re-write the keyboard class, you don’t have to touch your player class. Also, if you are working on a different project later, you can often just pull out any subsystems you might need and use them in a completely different application without modification. It's almost like each subsystem is a separate library.

This example is pretty simple, and I might just be telling you things you already know. But it extends to more complicated cases without trouble and alleviates headaches down the line, even if it takes a bit more work (and a bit more thought) to code than using a convenient singleton or global.

Again, just my 2 cents based on my experiences -- I'm not saying other ways aren't just as good or better -- this is just what I do.

Share this post


Link to post
Share on other sites
I'd say, don't build an engine, build a game instead.

After all, that's what game engines are for anyway: to make game development easier by taking care of common functionality. But how can you tell what is common if you haven't made any games before? How can you tell which approach worked and which didn't if you've never gone through the process completely?

I've tried creating some 2D engines before too, but at some point, I simply decided to build games. The interesting part is that, once you've built a game, you can usually reuse some of it's code. After a few games, you can end up with a vastly improved framework or engine that has proven to be usefull. It worked for me. :)


Anyway, since you mentioned singletons, you should be aware that, in most cases, they're just globals in a shiny design pattern wrapper. Since they're globally accessible, it's easy for anything to access them. As a result, as venzon already mentioned, you'll likely end up with many dependencies. If some system needs to know about another system, pass it a reference. If you end up sending many references, it's a clear sign that your design is flawed and that you should spend some time thinking about what dependencies you really need.

Share this post


Link to post
Share on other sites
I do pretty much the same thing with my games. If its done correctly it works great, if not, well, it has a tendency to paint you into a corner as you've discovered.

Now, as for that nasty use of singletons you've alluded to... Please learn to live without the Singleton pattern. As the other poster said, they tend to introduce a sort of indirect coupling between systems that use the same singleton. Furthermore, singletons are really just glorified psuedo-OO globals and they also have potential issues with their order of creation.

Instead, locate systems in the smallest scope in which they can accomplish their duties and pass references to those who need access.

Also, adopt some other practices and patterns such as the Single Responsibility Principle, Message Passing and/or the observer pattern, and the Visitor Pattern, among others.


Also, I'm very much agreed with Captain P: build a game, not an engine. What that means is that you should come up with a specific game and develop an engine to support exactly the features it will require (and no more!) -- Some of this code you will be able to carry into your next game, but most will be re-written or thrown away. What you do keep will probably be made more general. Over the course of 3 or more games, your core code-base will grow into a framework of general and proven engine components.

Now, it doesn't mean that you shouldn't plan ahead or write hackish code full of magic numbers, it simply means don't try to engineer your solution for all sorts of crazy hypothetical use-cases. What it does mean is that you should try to write an elegant solution for the exact requirements at hand.

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
I'd say, don't build an engine, build a game instead.

After all, that's what game engines are for anyway: to make game development easier by taking care of common functionality. But how can you tell what is common if you haven't made any games before? How can you tell which approach worked and which didn't if you've never gone through the process completely?

I've tried creating some 2D engines before too, but at some point, I simply decided to build games. The interesting part is that, once you've built a game, you can usually reuse some of it's code. After a few games, you can end up with a vastly improved framework or engine that has proven to be usefull. It worked for me.


AMEN. Make a game, and make it playable. That'll teach you so much more than making an 'engine'. There's always a balance between making your game work as quickly as possible, and making your code elegant. Don't spin you wheels, bogging down it designing a proper 'engine'.

Share this post


Link to post
Share on other sites
Maybe it's a good idea to differentiate a bit on that...

It's always a good idea to put some thought on what you need and how it's going to work before you start coding, and laying out an "engine" is just one way to do it.

The thing is, for one-man-projects, the word "engine" should not have the same meaning as in large-scale development teams.

An engine can well be some sort of abstraction from the libraries used, with some glue code attached.
That's just fine, and it helps you keep your focus on the game.

You should not, however, start thinking about how to organize your game data in an engine, or about game code in general, in terms of an engine.

So, you can design some classes which do the painting of sprites for you, and add the capability of playing some sound.
You also can design a class that takes input device data and translates it into a more generalized form.

Something like that, with a bot of experience, is what you can call your "engine", and build on top of that - but, do your self a favour and keep things simple.
No one ever completed a program once he started writing frameworks....

Share this post


Link to post
Share on other sites
Wow, a lot of valuable info there! Thanks for the quick responses!

First off regarding the singletons, could one of you possibly give me a brief example of when to use a singleton vs. when not to? At the moment I'm implementing it for a few things where I don't see a reason for there to be more than one instance of ever (My File I/O, Input and the Renderer to name a few), is this wrong?

Venzon your description involving one top-most system operating many subsystems with their own private subsystems is more or less the design approach I've taken so far, as well as in the past. My problems come when I want to start drawing objects and I see two possible options:

A) I include the rendering code headers in the source for the main object class, and then in a Render() function or something similar for the object I want to draw (let's say of type "Sprite") I could all the drawing functions possibly from some interface as Lucem suggested.

B) The more complicated idea that I like more is that I store all relevant rendering info in some sort of structure with the objects I want to draw, and then have the engine pickup this info and feed it to the interface when it's rendering time. (My main problem with this seems to be that it just seems like a sloppy solution, if it isn't please tell me so.)

Also on the idea of using interfaces, my main problem with that idea in the past (and really the only reason I haven't tried them yet) is that I always figured I would just end up with a header file that had functions defined, that did nothing more than get the sole instance of the render, and call the same function from it (thus removing direct communication with the render itself). After reading your comments it looks like I might have the wrong idea of how such an interface should be structured...

Finally, Captain P I like your idea of building multiple games until I've refined my code into something like an engine, my only problem with that is that I've written small games before, I could write pong or tetris in a day or less depending on how much to add, the problem is that doing so would mean deliberately ignoring certain things such as a manager for input versus just checking for 4 or 5 keys that only work in THAT game, or something similar for other aspects.

EDIT: Some of this has been answered by you guys in the time it took me to write this originally, thanks!

Share this post


Link to post
Share on other sites
Singletons:
Simple - use them never.
When you run in a situation where you need them, you'll see for yourself.
In all other circumstances, when something's crying for Singleton, ignore it.
Singletons are more of an anti-pattern today, with good reason.

After reading what you wrote about your experience with interfaces, it's obvoius to me that you haven't understood object oriented programming at all.
There should be no direct interaction of a game object with the renderer.
A game object is responsible for managing it's own data, such as it's world position (not screen position!), and the way it behaves.
It's not responsible for drawing itself, it's not responsible for updating its screen coordinates, if visible, it shouldn't even know about the fact that it's a renderable object at all.

The renderer is responsible for drawing everything, finding the right sprite to draw, and all stuff graphics.

So, how to do that?

Well, there comes in an architectural pattern that's called MVP.
Model View Presenter is about a three-tier design where there is
(in this case) game data (model), a renderer (presenter) and someone
in the middle that intermediates between them (view).

So, in your case, the view is the center of all attention, and it interacts with the model data, and is interacted with by the presenter.
The presenter doesn't talk to any game object in the model tier.
It gets all that there is to know using a defined interface that is implemented either by view alone (using delegation of certain request to model) or by view and model.

So, each system is responsible for one task only, and using interfaces here provides you with the possibility of e.g. re-using the renderer in the next game, while the view and the model change.

Share this post


Link to post
Share on other sites
Ahh that makes more sense and gives me another direction to head in.

I'd like to just say that I truly do understand how OOP SHOULD work if it's implemented correctly, I just tried to emphasize that I don't quite understand how to do this myself to the extent that something larger than a few-hundred lines of code would require. With my interface examples I was just trying to say that I only saw two possible ways of doing it at all, example A: the truly wrong way that was never really an option in my mind (now that I read that again I can see that I didn't really show that I wasn't considering it, a mistake on my part) and example B: which actually doesn't seem to be what you suggested I tried, but also isn't what you said is a horrible idea either (it wouldn't interact with the renderer directly, and that private structure of display information for the sprite class constitutes being responsible for managing its own data (texture to use, world-position etc.) if not, let me know.

Also when I saw that the sprite class would know what texture to use, I'm referring to it having some sort of ID tag and the renderer would look up the texture it corresponds to.

Oh one more question. With this "MVP" architecture, if I'm using DirectX for example in my renderer, what would each part of this be. Obviously model is self-explanatory, but in this case would I even need to write a "renderer" at all? or would "view" just be an interface between the model and the DirectX functions needed to display it?

[Edited by - ChugginWindex on January 30, 2008 6:37:55 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by ChugginWindex
Finally, Captain P I like your idea of building multiple games until I've refined my code into something like an engine, my only problem with that is that I've written small games before, I could write pong or tetris in a day or less depending on how much to add, the problem is that doing so would mean deliberately ignoring certain things such as a manager for input versus just checking for 4 or 5 keys that only work in THAT game, or something similar for other aspects.


One thing to remember is that just because you only need to check 4 or 5 keys doesn't mean you should do it in some hard coded manner. Why not create a system to manage keyboard input. Create commands for the keys pressed which can be remapped to different keycodes. There's lot of things like this which even a game like tetris if you do it right can then be reused in other games.

This is what is meant by building games not engines. Build the proper systems and controls but concentrate on the game at hand rather then concentrating on an engine that can be used for any game.

Another thing you could try doing rather then building an engine is a map/character/terrain/etc editor for your game, this can lead to needing a lot of the same systems which a game will need and provide a fullfilling result when you complete it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dancin_Fool
One thing to remember is that just because you only need to check 4 or 5 keys doesn't mean you should do it in some hard coded manner. Why not create a system to manage keyboard input. Create commands for the keys pressed which can be remapped to different keycodes. There's lot of things like this which even a game like tetris if you do it right can then be reused in other games.

This is what is meant by building games not engines. Build the proper systems and controls but concentrate on the game at hand rather then concentrating on an engine that can be used for any game.

Another thing you could try doing rather then building an engine is a map/character/terrain/etc editor for your game, this can lead to needing a lot of the same systems which a game will need and provide a fullfilling result when you complete it.


Also true. I'm starting to regret saying that I was trying to build a 2D engine in my original post. There is a game that I am working on as a proof that I can design something more than just pong or tetris, and now I'm trying to write the inner workings of the game, in a more professional situation what I'm trying to write would be the engine; in my case it's just what makes the game work I suppose.

I've thought about what I would need, and I'm currently trying to develop those pieces for use in the game "engine". Like I said, it was more getting those pieces to function without knowing everything there was to know about the engine that was starting to confuse me, and the posts in this thread are certainly shedding some much-needed light on the subject.

Share this post


Link to post
Share on other sites
Didn't mean to insult you ;)

Using your example of render data, maybe this makes it a bit clearer:

Think of the system as data which is held in parallel, suited to the needs of each subsystem (render, control, model) and is linked by some common denominator (like an ID or whatever).

So, the renderer has it's own list of data (sprite, spatial etc.),
the view has it's own data (which object is controlled by which controller),
and the model has its own data (the objects).

Everything is tied together by a high-level object containing the game loop,
which knows all the subsystems and talks to them directly (by using interfaces rather than classes).

So, there would be three Interfaces for the three subsystems:
IRenderer, IController, IModel (or, IPresenter, IView, IModel)

The controller would know the model (by using the IModel interface) and the renderer, the renderer would know the controller.

The model would need to know the controller, too.

On this level, the three subsystems would be able to communicate changes
without knowing the classes of the other systems - as long as they implement their respective interfaces, everyone's fine.

So, if a tank was destroyed while it was visible, the model would notify the controller of the fact that that tank was destroyed.
The controller would notify the owner of that object (let's make it an AI player) that is was destroyed, which will delete it from it's list of inventory.
The controller would also notify the renderer about the destruction of that tank, causing the renderer to remove the corresponding sprite from its own data.

As you can see, all subsystems keep their own data, and synchronisation between them is done via messaging (method calls, events, whatever).
The systems can interact with one another, but do not have to know about the other systems' data or implementation details.

In the end, you'll have a robust system, that is easily understandable and is less error-prone.
Plus, you can easily modify your renderer without it affecting the game model representation of a tank!

Share this post


Link to post
Share on other sites
Quote:
Original post by lucem
The renderer is responsible for drawing everything, finding the right sprite to draw, and all stuff graphics.

So, how to do that?

Well, there comes in an architectural pattern that's called MVP.
Model View Presenter is about a three-tier design where there is
(in this case) game data (model), a renderer (presenter) and someone
in the middle that intermediates between them (view).

So, in your case, the view is the center of all attention, and it interacts with the model data, and is interacted with by the presenter.
The presenter doesn't talk to any game object in the model tier.
It gets all that there is to know using a defined interface that is implemented either by view alone (using delegation of certain request to model) or by view and model.

So, each system is responsible for one task only, and using interfaces here provides you with the possibility of e.g. re-using the renderer in the next game, while the view and the model change.


The MVP pattern can indeed be used, but to correct Lucem, the View corresponds to the renderer and the Presenter corresponds to the intermediary.

MVC is another useful pattern for entities in the game world. MVC stand for Model-View-Controller, where model and view are basically the same as in MVP, and controller corresponds to an object which directs the behavior of the model. I've used this pattern in my projects to implement AI and player input as entity controllers. Often times in MVC, the View takes on many of the responsibilities of Presentation (mostly because MVC addresses a different concern than MVP) but there's no reason you can't have a Presentation layer applied to MVC, I guess you might call it the MVCP pattern.

Share this post


Link to post
Share on other sites
Oh, thanks, I always get those two wrong :)

MVC is mainly used in GUI, half of Windows consists of that pattern -
but, the problem is, MVC makes it hard to correctly identify the responsibilities, as ravyne pointed out.
MVP makes that a lot clearer, IMO (though both are related, it does make a huge difference after all).

By the way, you shouldn't worry too much, write your game.
Just put some thought in advance on how you can deal with different responsibilities of different "components" of your engine.
In the end, there are only two rules:
- Make it fun. If it's not fun, it's not a game.
- Keep it simple.

Anything else is subject to discussion, and there is no clear wrong and right.
It all depends...

Share this post


Link to post
Share on other sites
Alright, this is starting to make a lot more sense now. I just have a few more questions:

When I think of interfaces I think of the one such as iDirect3D9 which as far as I know there can only be one copy of (and then you call CreateDevice() and get a pointer to the device and so on blah blah blah). How would I do this with the IModel, IPresenter and IController interfaces though? Say I want to put a tank on the screen, if I have this right, would I just have something like a Tank class, that has the name of the texture to use, the world position, health of the tank etc. Then the IModel interface would notify IController of the Tank object's world position and health, and IController would notify IPresenter on stuff like whether to draw the texture or not or if it was destroyed. Also, would the IModel just notify the IController->IPresenter right away of the name of it's texture so it could be looked up, or would the texture be accessed / defined a different way.

Am I getting this at all? (I really have not found any info on the web that is half as in depth as you're describing, so thanks, this is all new to me.)

-Also, I've actually got a bit of experience in UnrealScript and modding for Unreal Tournament 2004, and a lot of what you describe with this MVC and MVP design actually seems very similar to what they use for managing most of the "actors" in the engine. That alone is making this a lot more understandable (unless I'm totally wrong somehow and the three are unrelated)

Share this post


Link to post
Share on other sites
Actually, you'd have different sets of data.

For convenience, you'd have a factory of some form which you tell to build a new tank.

This would create the game object "tank", attach it to some owner (AI, human player, whatever) and tell the renderer to create a new sprite for a tank, along with the initial data (position etc.).

How this creation of objects is done would be up to you.
You could create everything in there and "inject" it to the subsystems, or you could delegate object creation to factories inside the subsystems which will do locally (and transparently).

After that, all three subsystems would have their own "tank" object, having the data they need.
So, one monolithic "tank" is split up in 3+ smaller objects that only contain the data that's needed for the specific subsystem.


iDirect3D9 is not an interface, but an adaptor class (see the adaptor pattern) -
it presents you with some of the functionality Direct3D provides, and gathers them in one place.
So, it is an interface, but on a larger scale. It's an interface for a lot of other classes, not only one.
iDirect3D9 itself would talk to a lot of other classes inside the D3D library, which you do not have to know, so it hides this information from you and presents you only the things you need to know.

In a smaller scale, the MVP works the same.
For your game, you might implement all your game code in "model", and use renderer and controller (or presenter) as adaptors to the underlying subsystems.

The Unreal Tournament thing:
Yeah, believe it or not, that's how things work.
Every good programmer and system architect out there has read the GoF "Design Patterns", and knows how to use them.
You come across patterns everywhere today - even inside programming languages and their runtime environments (Java and .Net are prominent examples of that).

Share this post


Link to post
Share on other sites
I guess I don't understand why something like IModel would store a smaller class that only had information about a specific tank object such as the health and world position rather than just storing a pointer to the actual Tank object and relaying the info to the IController in that way. I also don't understand why IController would need to store it's own information if it's purpose is to coordinate what IPresenter does based on what it determines from IModel. (I suspect I'm still not grasping something here for some reason, usually stuff like this doesn't take this much explaining for me).

Share this post


Link to post
Share on other sites
This is going to be my last post for now, I need to get some sleep...
it's past 3 am and at 10:30 I need to write an exam.

You could mail me at sebastian.porstendorfer@web.de if there are any further questions, and I'll try to answer them.

The reason for separating the data is actually two reasons.
First, game objects ( as in model ) do not have to know implementations details like what texture they use, or their position on the screen.

Second, if for whatever reason you decide to change your renderer, you would have to change your "tank" class as well.
( Like, switching from SDL to SDL+OpenGL, you would suddenly have to have normal vectors inside your game model... )

Thus, data is split up by responsibility of the objects that use it.
It just allows for greater modularity and flexibility (what if you decide to support multiple renderers? dx9, opengl, software rendering...).

Plus, if you've got everything in one class, and you derive from that class, everything is derived, even the things that are general enough to not have to be derived from - a sprite is a sprite, you adapt it to your needs by using its data, but you hardly ever subclass from it.

Share this post


Link to post
Share on other sites
So to clarify, the responsibility of the Model is to hold the data and rules that make a tank a tank for example. It has nothing to do with its representation, such as its graphic or 3D model, because those things don't make it a tank. To borrow a phrase "If it walks like a duck and talks like a duck, it must be a duck." -- notice no mention of it looking like a duck? The duck is defined by a function of its behavior rather than its appearance. So a Model in the MVC/MVP patterns is much like a scientific model in that it is an abstract representation, rather than a tangible one.

For a tank, the Model holds things such as position within the world, orientation, damage percentage, ammo count, etc. It also has an interface which allows its various externally-visible state information to be queried. This is how the View and/or Presenter are able to build a visualization of the tank object -- They ask the Model for its position and orientation, combine that with what they know about what a tank looks like, and draw it appropriately. Another portion of the interface exists to allow the Controller to issue high-level commands like "drive to this position X, Y" or "Fire on this target." The controller doesn't need to tell the tank how to move, how fast to go or how steep of a hill it can climb. Similarly, it doesn't need to tell the tank to deduct a shell from its ammo count when it fires because the Fire() command knows this, and also knows that it can't fire unless it has ammo. You get to choose exactly how high-level the commands that the controller will issue will be, it might be a valid choice to implement path-finding as part of the Controller for instance, in which case the movement interface for the tank Model would be at a lower-level than had path-finding been implemented within the tank Model itself. Either approach is equally valid and the conditions and assignment of responsibilities will dictate which is most appropriate in a given situation. The common thread, however, is that the Model implements just enough "smarts" to
be able to follow the Controller's commands and maintain a consistent internal state; nothing more.

Although this Wikipedia article has a heavy GUI slant (that is what the MVC pattern was designed to address, after all) its not hard to read through it with a mind for game entities and other game systems, and you'll come to understand that it applies 100% as is.

This image also has a GUI slant, but is equally relevant to game systems. Even the portion where the View and/or Presenter communicates the "User Gestures" to the Controller is valid. For example, it can be interpreted as a user click into the view port where View and/or Presenter have the responsibility of identifying what was clicked, since only they know the screen coordinates of UI elements or game units.

It also shows the possibility that a Model can push updates to the View and/or Presenter. Many games implement a pure poling system, but its easy to imagine that rare state changes or those that affect the internal state of View and/or Presenter might be pushed, rather than having the View/Presenter query the Model for all possible state changes every single frame.

Share this post


Link to post
Share on other sites
Personally I would put the 3d model in the model because its mathematical data, and is view independent. It doesn't have to have anything to do with rendering, it just required for it, like the world position. The 3d model data can be used for things other than 3d rendering.


The view would use that mathematical data, (3d model + world position), to generate a 3d image.


My idea is that the model contains all data, mathematical representations etc
Controller forms the logic of the program, when play that sound, what to render, and gives to the view. It does not have any data
The view/presenter, outputs this to the user. It should not have any data held. It just knows how to present it.

All 3 should have clear defined interfaces, so you can treat them as a black box. so you don't get any messiness

Share this post


Link to post
Share on other sites
Quote:
Original post by Alastair Gould
Personally I would put the 3d model in the model because its mathematical data, and is view independent. It doesn't have to have anything to do with rendering, it just required for it, like the world position. The 3d model data can be used for things other than 3d rendering.


Except that it's not. further, I don't believe anyone ever said that the model data resides in the renderer. In all likelihood the mesh and texture data reside in their respective resource caching objects. What the Model might hold is some sort of handle or other identifier that can be used to select the appropriate mesh and texture data.

It is also not necessarily independent of the View and/or Presenter because the whole point of the View/Presenter is to abstract the visual representation away from everything else.

Imagine a chess program, for instance, which uses the MVC pattern as its basis. The top level Model represents the board state and rules of the game. A Controller is used to represent the AI and Human player. Finally, a View and/or Presenter is used to provide the visualization of the game.

Now imagine that some people like a simple, overhead 2D chess board while some other folks like a nice 3D perspective-rendered board and yet others like their game to be rendered as isometric. Clearly, each method requires drastically different image data and drawing techniques. The 2D board requires simple 2D tokens of the same size, the isometric board requires 2D tokens of varying heights and also needs to sort the tokens back-to-front before drawing, the 3D board requires 3D models for both the board and the pieces and uses completely different 3D rendering methods. Still others might like to play using a text-based representation, a ray-traced representation, and abstract representation, or they might have the program connected to some kind of USB chessboard peripheral that actually moves physical pieces on a physical chessboard.

Consider also the process of selecting and moving a piece with a mouse gesture. The View and/or Presenter must know the shape of the piece representation in order to select it based on the click-coordinates sent over by the Controller. In contrast, the Model doesn't need to know anything about its visual representation in order to perform its duties.


Also, another point of clarification is that the View and/or Presenter should not be tied directly to low-level rendering duties, they merely direct rendering and presentation at a high level. They are not meant as a place to hold rendering API code, but rather serve as a conduit between the Model and the rendering API which funnels Model data and optional visualization information (such as sprites, meshes, textures, ascii codes, etc) through a presentation filter resulting in various visualizations.

Share this post


Link to post
Share on other sites
Exactly.

Most game engines suffer from the fact that they put everything into a "game object/ entity" class which more or less resembles the anti-pattern "blob".
This results in fairly ugly code, where you run into serious problems once
you're trying to bring in new features (which usually you shouldn't) or alter existing functionality. You shoot yourself in the foot.

Dividing up the data into smaller pieces which are handled by several classes (that have distinct responsibility) makes it much easier to cope with such problems.
Plus, the resulting classes that arise from this design approach don't get so bloated, so it's a lot easier to grasp for someone reading the code that uses them.

I wish game programmers would simply stop thinking of their programming work as different to any other programming work, where good design is established and enforced right from the start.
The thing is, easy to read and use code tends to be more performant as well.
Plus, if you talk to people in the (game) industry, on a professional level all these things are done - but some hobbyists seem not to be willing to accept that, so I guess trying to reach those people is like fighting windmills.

Share this post


Link to post
Share on other sites
Quote:
Original post by Alastair Gould
Personally I would put the 3d model in the model because its mathematical data, and is view independent. It doesn't have to have anything to do with rendering, it just required for it, like the world position. The 3d model data can be used for things other than 3d rendering.


I'd actually like to come back and respond to the second part of Alastair's assertion which I had neglected to rebut before.

I argue that it is not often the case that the mesh or other representations are ever used for other purposes. Take, for instance, the case of a mesh. One might assume that the mesh's vertex data is used for things like physics and collision detection, but that is often not the case. Physics and collision often deal with simple bounding volumes and/or a simplified mesh structure. The visual fidelity of an object required to make it look real is much higher than the fidelity required to make it respond to forces or constraints in a believable fashion, therefore lower-poly "physics meshes" are the norm these days. For the foreseeable future this is only going to become more pronounced, as graphics capabilities continue to grow exponentially and physics acceleration still very much immature. Someday, they will probably become closer in parity, but that day is not nigh.

The same goes for 2D, where physics and collision are also based on simple bounding volumes, simplified meshes (albeit in 2D form) and 2D collision-masks.

Is it possible to use the image or mesh of an object for collision or physics calculation? Sure, if it's of a low enough fidelity in the first place. Does some software take this approach? Probably. Is it a good idea? Not unless you've got a damn good reason and no other solution.

Share this post


Link to post
Share on other sites

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