2
\$\begingroup\$

I am currently developping a 3D game using C# / XNA 4.0 and i am currently thinking about how i should structure my game. The actual game is in fact not really important as the framework i am working on right know is pretty generic.

1st layer :

  1. BaseFrameWork : This BaseFrameWork is managing all the different game modules

2nd layer :

  1. ContentProvider : This module is a layer loading all the needed content (texture/sound/models) and providing it when needed
  2. SoundManager : This module is handling all the audio request (music activation, music change, sound activation, ect)
  3. InputEventHandler : This module is handling all the inputs of the player. Some flags are provided to each module to operate (for example there is a flag "toggleMusic" which is turned on when the player is pressing "M" while in game.
  4. ObjectFactory : This module is creating all the different objects when it is needed (for example creating a floor, boxes and other stuff)
  5. Player : This module is exclusively dedicated to the player.
  6. HeadUpDisplay : This module is dedicated to write the HUD (2D) of the game

Currently the 3rd layer is not developped (i have a few different objects for the ObjectFactory but that's all).

My first question is : "Knowing how is structured my game, do you think i should do it differently, and why ? For example, should player be part of the ObjectFactory "

My second question is about the way these different modules should be linked together.

  • The easiest option, but (i think) the nastiest one, is to provide to each module a reference of the other ones with everything public. Really easy to implement, really easy to use ingame, but really REALLY nasty.
  • One other option could be to let the BaseFrameWork get the useful informations of a module to give it to an other module.
  • Other options ?

These questions may seem basic and common sense, but last time i have been part of a game development, it looked nice (http://yapt.free.fr/) but i think we/I could have done better by spending more time into the game architecture beforehand instead of just diving the head in water.

Thanks for your comments/advice

Al_th

\$\endgroup\$
1
  • \$\begingroup\$ In Xna you have IGameServiceProvider in Game.Services and you can pass stuff via this. And i would implement this totally differently and others would do that even more differently, so i dont think there is a right answer to this question \$\endgroup\$
    – Kikaimaru
    Commented Jul 26, 2012 at 14:39

2 Answers 2

0
\$\begingroup\$

The way I read your question, is you know how you want your game objects to be structured, but you don't know how you want them to communicate. To answer "should I structure this differently" I would say no. It looks pretty standard to most other structures I have seen.

For the second question, the method I use for this is an EventManager. It is somehow globally accessed (singleton, global variable, static, ect). It has two parameters that go with each event: a type and a data object.

The type is an enum that stores various things that happen, like object created, moved destroyed, collisions, player moved forward, ect.

The data is a virtual class that has an implementation for each type. So object created event would be passed the ObjectCreatedData, which inherents from the EventData base class.

Then, when something happens in the game, like the physics system detects a collision, it triggers the event. Everyone that cares has set up event listeners to the events they care about. So for instance the SoundManager registered an event listener for collisions so it knows when to play the collision sound.

This way you can trigger anything you want, and other parts of the framework can manage whether or not they care. As many parts can listen to one event as you want, or none at all.

This keeps things from getting interdependent.

As a last note, I would like to mention that I have seen different ways to store the type of than enum. I use enumerations because they are simple and easy to expand, but they get large in bigger games. Some people perfer to use some Hashed Strings or some other generate-able GUID for the event type so they don't have to maintain the enum. I prefer having all the event types in one place though YMMV.

\$\endgroup\$
0
\$\begingroup\$

The easiest option, but (i think) the nastiest one, is to provide to each module a reference of the other ones with everything public. Really easy to implement, really easy to use ingame, but really REALLY nasty.

That's where you're wrong: it may be easy to implement and to use, but it's a lot of boilerplate code, and it's hard to maintain.

Example:
You need to use IPatator in a Shooter class.
the class that creates your Shooter class doesn't have an IPatator, neither does his own parent, etc.
So because of your Shooter class, all previous classes in the hierarchy now depend on IPatator.

Another reason it's bad is circular dependencies a.k.a dependency hell.

You could either use a DI framework (MEF, Ninject... you name it) or a simple inversion of control container, a basic example can be found here.

It boils down to: have a Dictionary that stores implementations of interfaces used throughout the application (the IoC can be static), or a subset of the application (the IoC needs to be passed as dependency to child classes).
Then you can "resolve" dependencies from that Dictionary instead of passing them from constructor to constructor.

\$\endgroup\$
1
  • \$\begingroup\$ > That's where you're wrong: it may be easy to implement and to use, but > it's a lot of boilerplate code, and it's hard to maintain. That is what i meant by "nasty". This is a fast method to get rid of problems quickly by hiding the dust under the carpet. I'm sorry if i was not clear, my english is far from being perfect so i may introduce some on my own language expressions. I totally agree with your vision of the "full public" method, that is why i came here to find some solutions to overcome the issue. \$\endgroup\$
    – Al_th
    Commented Jul 26, 2012 at 17:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .