Sign in to follow this  
Angelic Ice

Avoiding the God Class

Recommended Posts

Hello forum!

 

Initially my game-engine-class (only one residing in the int main) owned all active game states (no usual state machine) and ran them, that was it.

But now, I want to restructure my game's modules and my game-engine-class turns verbose and its one responsibility is unclear.

The class is called "game engine" and I'm not happy with that either. But for now, I do not know any better name as its one responsibility is still overloaded.

 

In my case, modules are a set of Graphics, Audio and Input organising classes.

Example: There are 3 files that handle Graphics operations, they form my Graphics-module.

 

So, my current concept will move modules into the game-engine-class. In order to provide decoupling, I finished coding an event bus.

Now, classes only need to know their relevant communication-channel via their specific event-bus.

But as the event-bus being another module, it would reside in the game-engine-class too.

 

So, I reconsidered my plan and thought: How about a class that manages my modules, but then, I would get one of these "manager-classes" that I wanted to get away from as well.

Which I partly failed with my "game engine"-class already.

 

Moreover, here is a rough example of what modules I have at the moment:

 

State iterator, iterating over active game states

Graphics module, allowing rendering sprites

Audio module

Input module, for pressed key events

Event bus, so components can listen/trigger each other without knowing about their partners

...

 

A module-iterator-class would make sense. Or maybe multiple classes that each handle one job of states handling.

One fore module-iterating, another one for holding them and another one for getting/setting up communications with the event bus.

 

To be mentioned, I thought that continuous communications for sprites via the event-bus is weird. As many sprites will be drawn a thousand of times per second, direct access to the Graphics class via visitor pattern would make more sense.

But who is in charge for that?

Would it be a module-module that consist of classes like: Module-iterator, module-handler, ...

 

I would be really happy if somebody could show me what possibilities are there and what is good practice.

 

Share this post


Link to post
Share on other sites

I would say you're already doing quite well by separating distinct units of code into modules.  

 

But be careful not to over think the single responsibility principle or separation of concerns.  Introducing an Engine or Application class that acts as glue between those module units isn't necessarily something which needs to be pruned immediately.  It's often a good way to let new ideas and solutions percolate and as you see enough code of a specific use case building up, refactor that into its own module or class as needed.

 

At the end of the day, all engines have their fair share of glue code. 

Edited by crancran

Share this post


Link to post
Share on other sites

Hello forum!

 

Initially my game-engine-class (only one residing in the int main) owned all active game states (no usual state machine) and ran them, that was it.

But now, I want to restructure my game's modules and my game-engine-class turns verbose and its one responsibility is unclear.

The class is called "game engine" and I'm not happy with that either. But for now, I do not know any better name as its one responsibility is still overloaded.

 

In my case, modules are a set of Graphics, Audio and Input organising classes.

Example: There are 3 files that handle Graphics operations, they form my Graphics-module.

 

So, my current concept will move modules into the game-engine-class. In order to provide decoupling, I finished coding an event bus.

Now, classes only need to know their relevant communication-channel via their specific event-bus.

But as the event-bus being another module, it would reside in the game-engine-class too.

 

So, I reconsidered my plan and thought: How about a class that manages my modules, but then, I would get one of these "manager-classes" that I wanted to get away from as well.

Which I partly failed with my "game engine"-class already.

 

Moreover, here is a rough example of what modules I have at the moment:

 

State iterator, iterating over active game states

Graphics module, allowing rendering sprites

Audio module

Input module, for pressed key events

Event bus, so components can listen/trigger each other without knowing about their partners

...

 

A module-iterator-class would make sense. Or maybe multiple classes that each handle one job of states handling.

One fore module-iterating, another one for holding them and another one for getting/setting up communications with the event bus.

 

To be mentioned, I thought that continuous communications for sprites via the event-bus is weird. As many sprites will be drawn a thousand of times per second, direct access to the Graphics class via visitor pattern would make more sense.

But who is in charge for that?

Would it be a module-module that consist of classes like: Module-iterator, module-handler, ...

 

I would be really happy if somebody could show me what possibilities are there and what is good practice.

 

You're doing fine as is. Keep in mind that you won't always be able to adhere to certain practices in a sane way. And sometimes the simplest way is normally the best way to go about it.

For Example, most people will say that Singletons are the devil and you can always find a better way.

Yet both the Unreal and Cryengine (made by long time industry experts) make use of singletons as a service to access engine modules. They simply disguise these calls with syntactical sugar so the user doesn't notice it.

 

If you feel the most efficient, and simplest way to tie all your modules together is a god class, then go for it. You can always change it later.

Edited by Tangletail

Share this post


Link to post
Share on other sites

A god class would be if you took all those module classes and just dumped their state and methods into your engine class. Usually my top level class is 'Game' and it contains:

  • The shared store (a struct that contains state objects that are independent of the state machine - a reference to this is passed to all new states)
  • The module instances (Graphics, Window, Audio, Input, and whatever else I'm using for that project)
  • The state machine (the current or root state, a function that updates it, and a public run() function that runs the update loop)

That may seem like more than one responsibility, but the reality is that the Game class is responsible for encapsulating the game, and it's actually usually a very short and simple class.

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