My game engine consists of a range of loosely coupled modules, which can be loaded and unloaded.
Some examples are: The base module, handling window management and responding to OS events, entity manager, Lua manager, physics manager.
Right now, these modules are organized as namespaces, and their state is defined through local variables in the respective source files. Each of the namespaces has an Open(), Close() and Update() function.
Now, I don't really like the solution with namespaces anymore.
It's not flexible enough
Even if it might not be needed in reality, having the plain ability of creating multiple instances of a module seems proper
It seems like I'm not making use of OOP here - a module base class with a virtual Update() member function would sound more reasonable
It's harder to ensure that when the module is closed and reopened, all of the variables will be reset too (A class with constructors and destructors would be easier)
You can't properly have the modules managed without explicitly calling Open(), Close() and Update()
So, my idea would have been to use classes for each of the modules, derived from a module base class. The module class instances would be handled by the ModuleManager class, which updates them.
But the solution with OOP brings up the problem of how the modules should communicate. Right now, the base module told the console module to print something via console::print()
How can I work around this problem without having to use something like g_ModuleManager.GetConsoleModule()->print()
?
How could this module manager work in detail?
And my final question:
Do you have any further tips for me on the topic of writing a modular game engine in C++ with OOP?
Are there any design patterns that could help me in this situation, or maybe even concrete reading material?
Modular code is code which is separated into independent modules. The idea is that internal details of individual modules should be hidden behind a public interface, making each module easier to understand, test and refactor independently of others.
Modular Programming allows development to be divided by splitting down a program into smaller programs in order to execute a variety of tasks. This enables developers to work simultaneously and minimizes the time taken for development.
Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality.
Namespaces become very inflexible very quickly.
One way to keep things loosely coupled is to use messaging through a central message dispatcher; rather than saying console::print
you would say messenger->sendMessage(PRINT_MESSAGE, stuffToPrint)
.
The console would register itself as a listener to PRINT_MESSAGE
s and act the way it wants to. The sender doesn't need to care whether someone's listening, and there could even be several listeners to each message (useful for debugging).
Regarding reading materials, Jason Gregory's "Game Engine Architecture" is pretty good, discussing the pros and cons of several architectures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With