In the early versions of my generic 3D engine "IMotion", this one was provided as a classic lib, with some headers and binary libs; this implies that each time I wanted to start a new test program or project based on it, it was mandatory to spend time creating the main program, with all those boring steps like creating the main window, calling renderer initalization routines, writing callback for input events from mouse, keyboards, blah blah blah... So I decided to join to my 3D lib release something that I called "framework classes"; the aim of those classes is to:
- replace and manage the program entry point (winmain()) to make all required initialisations steps, included full-screen or windowed app.
- provide a ready-to-use base class with all necessaries callbacks for various events hooks, like app startup, input from keyboard and mouse, closing app event... finally this class called 'cIMApp' must be inherited to implement all the app-specifics data and behaviours. Usually, I give the name 'IMAppClient' to this app-specific class
The problem was the following: as I gradually added features to the X-Frontier prototype, all those features were managed in the custom 'cIMAppClient' class, so this one was growing and growing again, until the point that this was too swollen to continue like that, indeed cIMAppClient class was responsible of quite all and everything in the game, like :
- game data load and init
- player input management (keyboard, mouse)
- 2D GUI object rendering and management
- scenegraph rendering and management
- game modes and states machines
- galactic map data provider (locations of systems and planets in the galaxy, under the following form : [sector, position])
- and more others things that I won't detail here...
I realized that it should be better to split this monolithic class in a few small and specialized services. So here is the list of the pool of 'services classes' present in the heart of the game now:
- GameCore service: This service is reponsible for data loading and initialization at startup phase, game logics, game modes managements, states machines, view and camera management, scenegraph management and rendering, and so on ... This is the game nodal point, so unfortunately it's intended to became quite complex again in the future; Maybe this one should be splitted again, wait and see... Of course, because of its central position in the architecture, GameCore leans on all other services.
- PlanetarySystem service: This one is the galactic map data provider. This means that it take as input a sector coordinate, and it provides as output this list and description of stars, planets, station and other object located in this sector. So, the randomly-created systems and also the handly-created systems (modding) will be hosted by this service. In the future releases of X-Frontier, when the graphic galactic map will be implemented in the game, this one will strongly lean on the PlanetarySystem service...
- GUI service: the purpose of this service is to manage all GUI 2D objects of the game : dialog, menus, and so on...
- IMAppclient:This class is now the interface between OS (Windows) events and the GameCore.
- MODAPI: MODing API : modding entry point of the game, with a set of method (interface) to mod the game : adding systems, stars, planets, vessels models, space stations... Mainly used by the lua stack.
- Game events : Managing high-levels game events; mmmh this one seems to be very near to gamecore in facts. Should I merge those 2 ?
- Console: In-game console management : the input strings are directly transmitted to the lua stack.
- Lua stack: binding between lua interpreter and MODAPI calls.
Finally, better than thousands and thousands words, here is a little draw showing the new enhanced X-frontier architecture: