Sign in to follow this  
Guniferd

How do I organize the "modules" of my code?

Recommended Posts

Guniferd    126
Hi, I am mostly a novice to game development. I think my question will be best explained through an example:

So I want to use OpenGL to create graphics for my game. There is a fair amount of "initialization" code to get everything set up (shaders, vertex array objects, program objects, etc..). There is also a fair amount of code involved in "display" code, which is the actual sending of draw commands to OpenGL. And then there is the "changing of game state" that my graphics code needs to be aware of, so it knows what to render. This includes changing the positions/orientations of objects in the world, creating/destroying objects. There could also be other more technical, less game-centric "changes in state" like selecting a different shader, or notifying the graphics code that the window has been resized.

Now, it seems unreasonable to keep all this code in the same place as my main loop. The solution I am thinking of is to create a Singleton "Graphics" class that manages whatever state it needs, and deals with OpenGL-related code. It could have methods like initialize(...) and display(...) and whatever methods the main loop needs to change the state of the graphics code.

I have read that Singleton classes are like global variables, and that they should not be used unless you really need to. But with the Graphics singleton, communication seems relatively one-way (from the main loop to the graphics module), which might be relevant to this design choice. I don't see a better alternative. It would be very cumbersome for the main loop to manage the graphics state and instead rely on functions not of any class.

I imagine dealing with other "modules" will be similar to this.

Share this post


Link to post
Share on other sites
Waterlimon    4398
Have the graphics class only render triangles with textures and shaders and all that and have a nice interface for it that abstracts away opengl (so that you could change to directx by only editing that single class)

Then have a classes that use that class to render to the screen, like a mesh renderer, terrain renderer, gui renderer, text renderer...

Share this post


Link to post
Share on other sites
Guniferd    126
Yes, abstracting away the low-level API is good idea, thank you. But is the idea of using different classes with just one instance to control different aspects of my code a good idea in general?

Share this post


Link to post
Share on other sites
blutzeit    1650
I've found the ideas of Domain Drive Design useful when deciding how to modularize code. DDD is about designing complex systems, but can be applied any system that contains some kind of *domain*, such as a game world, the objects and mechanics that it consists of. One basic idea is to separate the domain code from support code. For example, bouncing balls are domain objects, while sprites are usually not. By distilling the domain objects and logic allows the code to move to a higher level, and makes it more readable and changeable. Balls should know how to bounce, sprites should know when they collide.

Share this post


Link to post
Share on other sites
alvaro    21246
I don't know of any situation that is improved by having a singleton. Most of the time, having another instance of the object is not as crazy as you initially thought it was (if you were to display graphics on two separate windows, would you need two `Graphics' objects?), so it's better to make sure the rest of the code doesn't assume there is a single instance. In any case, a global object is just about as bad as a singleton, and it's easier to understand.

Share this post


Link to post
Share on other sites
nitro404    103
Singletons definitely help, so long as you implement them properly. For example, I use a "variation" of this, wherein my "Game" object contains static pointers to various modules (including itself), such as: Settings Manager, Resource Manager, World, Console, Menu, etc. If you first create the different "modules", and initialize them later, this will allow them to access each other without really needing to worry about dependencies, if it makes any sense. Anyways, it works well for me.

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