I have just brought the new engine up to the same point the old engine had reached, and the design is much clearer this time around. I won't go into the details of the old engine's design, but the new engine basically consists of these objects:
Application - acts as the interface between the engine, the player at this machine, and the OS. This object contains a single Engine instance, which it initialises and sends update commands to. The application contains the 'main game loop', similar to:
- Handle events from the OS
- Tell the engine to update itself (which in turn will update the world)
- Tell the player to render
World Dominationsorry, wrong list
Engine - the engine. This will contain a reference to the game world, as well as act as the 'owner' of the various subsystems, e.g. resource management, loading/saving worlds, plus lots more! I haven't fleshed out this object yet. One main point I emphasised when designing the engine was that the Engine object will not know about, or care about, players. I came to this conclusion after thinking about games that support dedicated servers, in that they are perfectly happy to run with no humans connected.
Render Window - represents the window that is rendered to. This also receives and distributes window events from the OS to the renderer, e.g. resized, closed, etc.
Renderer - provides a set of functions for rendering to the screen (more specifically, a Render Window). Note that only the Renderer object 'knows' about the render window - the Player object only interacts with the Renderer object, which delegates to the render window.
Player - the interface between the application and the player. The Player object handles updating input and contains the reference to the renderer. This object will not represent the player entity in the world. Instead, the entity that represents the player in the world will have a reference to the Player that controls it, and will query it for input commands. This kind of breaks the encapsulation of the world, in that the player entity will have to 'reach outside' the world to grab its data from the human controlling it, but I guess this is exactly the point of the player entity being controlled by a human.
World - this is where all the entities in the game world will exist. Each entity will have it's own Think() and DoPhysics() (etc) routines, which will be called by the World object each 'update frame'.
At this early stage, it's hard to tell if everything will work out. I haven't even started on the engine and world code yet! The engine is designed to support multiple renderers, OSes, input mechanisms, etc, but so far I have only implemented the features to work with Windows and DirectX9, so I can only hope that I've abstracted the interfaces enough to support other configs!