|
R-Type 0.1
|
This page describes how the project is split into layers, how the two programs run, and where each part lives in the repository. The details of each layer are covered in Game engine and Networking.
lib/ knows nothing about R-Type, so it can drive another game.Text description of the diagram. Both programs sit on top of the same game engine. The engine wraps the rtk ECS (registry and scheduler) and adds the main loop, the scene manager, the event bus, the entity factory and a set of generic systems. The client also uses the NetworkClient and two adapters that connect the engine to the rtk graphical library for drawing, input and sound. The engine never includes the graphical library: its render and input systems talk to the adapters through the rtk::ecs::concepts::IsRenderWindow and rtk::ecs::concepts::IsAudioManager concepts. The server uses the rtype::server::Server class, which sits on the NetworkServer of the network library. Both sides share the protocol payloads and the gameplay components found in src/Common. The network library only depends on Asio.
Each program runs two threads.
Text description of the diagram. On both sides the main thread runs the engine loop and never waits for the network. A second thread runs an Asio io_context that receives and sends UDP datagrams. When a datagram arrives, the network thread validates it, decodes it and pushes the result into a queue protected by a mutex. The main thread drains these queues once per frame. To send, the main thread posts a task to the network thread, which owns the socket. The client sends Hello, Input and QueryEntity messages. The server answers with Welcome, then replicates the world with CreateEntity, DestroyEntity and Snapshot messages.
rtk::GameEngine::run() drives both programs with the same loop:
onLoad() on the game, then onStart() on every system.onUpdate(context, dt) on the game. Both games use it to process network events and to update the active scene.dt, stage by stage, in this order: Input, Update, Physics, SecondUpdate, Render. Destroyed entities are flushed after each stage.onStop() on every system and onUnload() on the game.All movement, animation, scrolling and spawn timers are multiplied by dt, so the game runs at the same speed on every machine.
| Quantity | Unit and convention |
|---|---|
| Position | Pixels. Origin at the top left of the screen, x grows to the right, y grows downwards. |
| Visible area | 1280 by 720 pixels on the client. The server simulates a wider strip: enemies spawn between x = 1920 and x = 2920. |
| Rotation | Radians. |
| Speed | Pixels per second. |
| Time | Seconds, as a float. |
| Server tick | One per server frame, about 60 per second. |
A component::Transform stores the top left corner of an entity. Colliders are offset from that corner and scaled with the entity.
| Path | Content |
|---|---|
lib/GameEngine/include | Engine headers: rtk::GameEngine, rtk::EngineContext, components, systems, rtk::SceneManager, busEvent, rtk::factory::EntityFactory, rtk::Input::InputMapping. Header only. |
lib/Network/src | Network library: PacketReader, PacketWriter, PacketHeader, MessageHeader, MessageParser, HandshakeHeader, PacketTracker, Connection, UdpTransport, NetworkServer. Built as a static library. |
src/Common | Code shared by both programs: protocol payloads in Protocol/, gameplay components and systems, rtype::server::NetworkIdGenerator. |
src/Server | r-type_server: rtype::server::Game, rtype::server::Server, server scenes, rtype::server::ServerDeathSystem. |
src/Client | r-type_client: rtype::client::Game, rtype::client::NetworkClient, client scenes, rtk::systems::PlayerSystem, backend adapters. |
assets | Sprites, sounds and JSON entity blueprints. |
docs | This website: Doxygen configuration, guides and style sheet. |
tests | Network library tests. |
| Decision | Short reason | Details |
|---|---|---|
| Entity Component System | Decouples data from behavior and keeps systems independent. | Technical and comparative study |
| Event bus | Lets systems react to each other without direct references. | Game engine |
Scenes in a std::variant | Compile time checked state machine, no heap allocation. | Game engine |
| Concepts for backends | The engine has no dependency on the renderer or the audio library. | Game engine |
| UDP with a custom binary protocol | Low latency, compact packets, full control over validation. | Network protocol specification |
| Dedicated network thread | The game loop never blocks on the network. | Networking |
| JSON blueprints | New entities without recompiling. | Tutorials and how-tos |