I'm working on a game engine in C++. My current approach is described below:
- Engine is a library, provides all the necessary shared functionality (rendering, physics, etc.)
- Games are executables that link to the engine
- Editors are also executables, also linking to the engine
My initial plan was to work with a very specific constraint to avoid feature creep: games just need one window where everything happens, so we just need the engine to create this window (e.g via SDL), handle the main event loop (user input, etc.), update its own subsystems, and then update the game logic (which then queues up new tasks for the engine, e.g rendering). If the engine gets told to stop (main window closes, exit command on console, etc.), it shuts down the game as well.
Note: you can sort of picture it the way Unity works with MonoBehaviour objects, except in this case the entire game is one big “MonoBehaviour” that the engine queries for tasks.
The above approach works well enough to handle just the engine and a game hooked to it, as the latter can now focus entirely on game-specific code. On the other hand, this does create problems when trying to connect the engine to an editor, which tends to have a much more complex GUI. It would be unnecessarily complicated to write some kind of “full GUI abstraction” in the engine, just to allow the editor to create all of its UI through it. Thus it would make more sense to have the editor application handle window management, events, etc. and use the engine as a “subsystem”.
- For example, in an editor, we may now have several windows we want to render to, and at the same time, we don't expect to handle inputs from said windows the same way as we would in-game
- Same applies to the update mechanism: we don't necessarily want to update the entire engine on every frame while editing, and some parts of the engine would be turned off altogether
With this in mind, now it seems like the better approach is to have the applications that use the engine also handle the GUI and the main loop, which dictates what the engine does every frame. Few games need special GUI management, however, so this would cause a lot of code duplication, and it can be advantageous to give the engine tighter control over both the GUI and the update logic. Overall, it seems like a tradeoff.
Is there a way to have “the best of both worlds"? Are there good case studies you would recommend?