Game engine structure - deodand-inc/crawler GitHub Wiki
This document describes a draft structure for the game engine.
Goals
- The engine should be standalone. It should not directly depend on any third-party game engine (i.e. Godot). To put it another way, the game engine side should be a server, while the Godot side should be a client.
- Why? Primarily because it allows us to write our game however we like. We are not bound by any of Godot's limitations or the way it encourages you to model your game. It also reduces the impact of Godot API changes.
- It simplifies the writing of the game engine and of the Godot interface. The engine can evolve ahead of the Godot listener and the Godot listener can make changes in representation without affecting game logic.
- It allows us to write tests for the game engine without performing any rendering. We can validate the correctness of game logic without involving Godot.
- It allows us to potentially support things like multiplayer - by conceptualising the game logic as a server, it's possible to have one person's game act as a server for another's client, and thereby allow the two to coordinate.
- How? This can be accomplished using an event-driven approach. The game engine should publish events that Godot listens to. Godot then takes the event and updates the UI accordingly. When Godot receives user input, it can call a method on the game engine, which should be treated like an RPC (i.e. they should not directly share state).
- Why? Primarily because it allows us to write our game however we like. We are not bound by any of Godot's limitations or the way it encourages you to model your game. It also reduces the impact of Godot API changes.
Structure
Let's think about at a high level how a new game would start, and then derive the components that are involved in that.
- The game launches. The client calls the server to initialise it.
- The server loads resources it needs. This is primarily entity definitions.
- The player launches a new game. The client calls a method on the server to begin this process.
- The server generates a world and saves it. The game server notifies the client that the world is loaded.
- The client draws the world to the screen. The game is now ready to be played.
So, the server needs to:
- Load entity definitions
- Generate a world
- Tell the UI what should be visible on the screen.
Entities will of course have sprites that need to be displayed. How should this be handled? The server should not necessarily need to know about them. In fact, it makes the most sense for the game engine to not be involved in loading this type of resource at all. All the game engine needs to know is how to load and save entity and map definitions. Let's think about how this would work:
Generating a map
A map definition might look like this:
worldCoordinates: string
terrain: list of coordinates and tile types
-
entities: list of coordinates and entity types
-