OO Engine Design Issues

Started by
29 comments, last by Kylotan 16 years, 4 months ago
So I've got Game Objects which are either render-able or affect the game play in some way (part of the Scene Graph). And I also have certain services, such as a Texture Manager, Model Manager, which handle the loading and such of different resources. Game Objects need to know about certain Services (or managers) but not all of them all the time. There is a main "Engine" class which is the container for everything. I've looked into using the Factory pattern for creating GameObjects, but there is still the problem of, how does code that doesn't care about service X, pass service X to a GameObject which does need it. I was passing a pointer to the Engine object to each object, then they could use that to get the different service's they needed. But that necessitates a class knowing about it's container which is dirty. So there is that problem, objects shouldn't know about their container, but then how do they know about other objects inside the container which they need. Also, these Managers, I don't want them to be singletons, I mean they are pretty much just library functions, but still state full. Like the Texture manager actually holds the memory the textures are allocated into, and store lists of who is using them, so manages freeing them when they are unused and such. At the moment they are not singletons, they are just regular classes which could be instantiated twice, just never would be. So how do you guys handle things like this?
==============================
A Developers Blog | Dark Rock Studios - My Site
Advertisement
You should extend your definition of "cares about X" to also include cases of "creating objects that care about X". That is, your Foo-factory does not merely create Foo objects, because Foo objects can't exist in a vacuum. Instead, your Foo-factory creates Foo objects that live in a specific Bar—you then decide whether a given Foo-factory should always create its Foo objects in a given Bar (provided when it's created), or if the user should provide the Foo-factory with an individual Bar for every Foo upon creation of that Foo.
Quote:
So how do you guys handle things like this?


By not breaking rule #1.

Game objects are independent of their presentation.

You then end up with a few factories. Ones that create resources (presentation only) and one that is application specific (which can know about the game and the presentation since it's at the application level) that creates a presentation given a game object and a context.
Could we make this gamasutra article sticky? :o)

http://www.gamasutra.com/features/20050414/rouwe_pfv.htm

MaR
I'm reading that article and will probably come back w\ some more questions, but here is how I have things set up.

My Game objects are fairly agnostic of both what their presentation data is and how it is being presented.

All presentation data is requested by a Game Object from a Resource Manager (such as a texture or model manager). If the resource has not been loaded before, then it is loaded and registered with the manager and given a resource ID. That resource ID is returned to the Game Object. If it had already been loaded then it is found and it's ID is simply returned.

Then, the Game Object registers it's self with the Scene Manager (Scene Graph wrapper) where a Scene Graph Node is created for that specific object. Then when ever the renderer hits that Scene Graph node it finds the resource ID (which was given to the node by the Game Object) and renders the data specified by the ID stored in the specific resource manager.

This way the Game Object takes care of the logic ( Control ), the Scene Graph + Renderer take care of the presentation ( View ), and the Resource Mangers take care of the data ( Model... ish. )

This seems like a reasonable way of handling things to me, what do you guys think?
==============================
A Developers Blog | Dark Rock Studios - My Site
Quote:
This seems like a reasonable way of handling things to me, what do you guys think?


Exactly what I thought before.

BAD
 Model <====> View



GOOD
 Model <====> Controller <====> View


Game objects do not care about presentation. They do not care about scene graphs or textures or models. A dedicated server uses game objects but has no presentation. An AI uses game objects but has no presentation. A pathfinding thread uses game objects but has no presentation...

Your Scene Graph doesn't care what game it's being used in. It doesn't know or care about SpaceShip or NastyOrc.

Your Application knows about the game objects, and it knows which rendering api you're using. It acts as the intermediary to get the two parts that don't care about each other working in concert.
That's interesting, Telastyn. Most MVC architectures that I've seen generally allow for communication between the view and model. Are you suggesting that a better design is to route all communication through a controller class? I sort of see where that might be useful, but it also seems needlessly complex. The view certainly needs to know about state changes in the model.

Edit-

A slightly more concrete question: we're talking about using a MVC arrangement for every object in the game world, so say we have a SceneNode (view), Entity (model), and EntityController (hurr). The EntityController might handle player input, network messages, AI logic, or nothing at all, depending on what type of entity we're talking about. Obviously the SceneNode renders itself and the Entity stores/manages state, but how would you synchronize them?

When the EntityController decides to do something new it has to inform the Entity, but it can't directly inform the SceneNode since it doesn't have the "authority" to change state on itself. Would you say it's better to then have the Entity pass its new state information back to the EntityController, which then passes it along to the SceneNode, or would it make more sense to have the Entity itself inform the SceneNode of its new state?
Enh, sorry I just did it that way since the triangle ascii art never seems to work right...

And MVC is also perhaps not the best use of what I was trying to describe.

On one side you have your game. The game needs to exist and work without any presentation.

On the other side you have your UI/rendering. The UI/rendering needs to exist and work for any number of games.

So something needs to know about both of them. To me, that something is the Application. It takes the game code and the UI/rendering and makes them work together. Sometimes that's extending some code, sometimes that's setting up event handlers...

Regardless, that's how the 'knowledge' structure goes, in a tree.

    A   B C


B and C need to be independent of each other, but also need to work together. Thus you need A to make them work together. B and C can then be used elsewhere without dependencies.

Quote:
When the EntityController decides to do something new it has to inform the Entity, but it can't directly inform the SceneNode since it doesn't have the "authority" to change state on itself. Would you say it's better to then have the Entity pass its new state information back to the EntityController, which then passes it along to the SceneNode, or would it make more sense to have the Entity itself inform the SceneNode of its new state?


Two options, depending on the scenario.

1. Simple event. The Application (which knows of both the Renderables and the Game Object) has an event handler which understands the state change and can update the Renderable. Message passing does the same sort of thing.

2. Concrete Implementation. Part of the Application is a sub-class of the Game Object (likely registered into a factory known by the Game Objects) that does the extra work (unbeknown to the Game code itself). Similarly, the Renderable could be subclassed to 'peek' in at the Game Object and update itself as necessary.


The key though is that the Application is the code that is not reusable. It exists specifically to make this Game work with this Rendering. As such, the design motivation is to make it as small and simple as possible. Ideally not much more than making some objects and tying some events to some handlers.
Quote:Original post by Jools
That's interesting, Telastyn. Most MVC architectures that I've seen generally allow for communication between the view and model.


If you divide your app into model, view, and controller classes, but allow each of the 3 categories to communicate with the other 2, then how is that conceptually different from just having a single category? What benefit has it brought you, except perhaps a small degree of mental clarification?

Surely the only way to make maximal use of such a division, is to allow the controller to enforce the separation, so that the view doesn't break when the model changes, and vice versa.
Quote:Original post by Jools
When the EntityController decides to do something new it has to inform the Entity, but it can't directly inform the SceneNode since it doesn't have the "authority" to change state on itself. Would you say it's better to then have the Entity pass its new state information back to the EntityController, which then passes it along to the SceneNode, or would it make more sense to have the Entity itself inform the SceneNode of its new state?


It would make more sense to me to let the Entity inform their own EntityView(SceneNode), because the EntityController does only handle the interaction with the Entity the Entity will handle the logic of the overal object. If you want something different rendered you will send a message from the Entity to the EntityView. The EntityView will only care about rendering.

Like in the article if you want to have for example a particle effect rendered for an Entity you will fill in a structure and send that structure via a one way messagehandler to the EntityView which will process the message to render the particle effect.

If you want to process a function like fire() then the controller will let the entity now the player wants to fire and so the Entity will decrease the ammo or something like that and sends a message to the EntityView to process a particle effect. The EntityView will then render the particle based on the message it recieved from the Entity.

Personnaly i love this system it works very nice to seperate specific logic/rendering

Edit:
Also please note the Entity isnt the 2d/3d-Model its just a GameObject. The View will handle the 2d/3d-Model based on the Entity instructions

[Edited by - rvdwerf on November 22, 2007 7:38:24 AM]

This topic is closed to new replies.

Advertisement