Skip to content

Latest commit

ย 

History

History
371 lines (275 loc) ยท 12.5 KB

File metadata and controls

371 lines (275 loc) ยท 12.5 KB

๐Ÿ—๏ธ Architecture Overview

This document describes the architecture of the R-Type Clone game engine.


๐Ÿ“‹ Table of Contents


High-Level Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         Application Host                             โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                      ModulesManager                            โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚  โ”‚
โ”‚  โ”‚  โ”‚  Window  โ”‚ โ”‚ Renderer โ”‚ โ”‚   ECS    โ”‚ โ”‚  Sound   โ”‚   ...   โ”‚  โ”‚
โ”‚  โ”‚  โ”‚ Manager  โ”‚ โ”‚  (GLEW)  โ”‚ โ”‚  (Lua)   โ”‚ โ”‚ Manager  โ”‚         โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚  โ”‚
โ”‚  โ”‚       โ”‚            โ”‚            โ”‚            โ”‚                โ”‚  โ”‚
โ”‚  โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚  โ”‚
โ”‚  โ”‚                          โ”‚                                     โ”‚  โ”‚
โ”‚  โ”‚                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                          โ”‚  โ”‚
โ”‚  โ”‚                โ”‚    ZeroMQ Bus     โ”‚                          โ”‚  โ”‚
โ”‚  โ”‚                โ”‚    (Pub/Sub)      โ”‚                          โ”‚  โ”‚
โ”‚  โ”‚                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                          โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”Œ Module System

Design Philosophy

The engine uses a dynamic module architecture where each subsystem is:

  • Loaded at runtime as a shared library (.so / .dll)
  • Isolated in its own thread
  • Communicating via message passing
  • Hot-swappable without recompiling the host

Module Interface

All modules implement the IModule interface:

namespace rtypeEngine {

class IModule {
public:
    virtual ~IModule() = default;
    
    // Lifecycle
    virtual void init() = 0;
    virtual void loop() = 0;
    virtual void stop() = 0;
    virtual void cleanup() = 0;
    virtual void release() = 0;
    
    // Messaging
    virtual void subscribe(const std::string& topic, MessageHandler handler) = 0;
    virtual void sendMessage(const std::string& topic, const std::string& message) = 0;
    
    // Threading
    virtual void start() = 0;
    virtual void processMessages() = 0;
};

}

Module Loading

Modules are loaded via a C-style factory function to avoid ABI issues:

// In each module's .cpp file
extern "C" {
    rtypeEngine::IModule* createModule(
        const std::string& pubEndpoint,
        const std::string& subEndpoint
    );
}

The ModulesManager handles:

  1. Opening shared libraries (dlopen/LoadLibrary)
  2. Retrieving the createModule symbol
  3. Instantiating modules with messaging endpoints
  4. Managing module lifecycle

๐Ÿ“จ Inter-Module Communication

ZeroMQ Pub/Sub Pattern

Modules communicate via a topic-based publish/subscribe system using ZeroMQ:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Module A  โ”‚         โ”‚  ZMQ Proxy  โ”‚         โ”‚   Module B  โ”‚
โ”‚             โ”‚         โ”‚             โ”‚         โ”‚             โ”‚
โ”‚  Publisher โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚ XSUB  XPUB โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€ Subscriber โ”‚
โ”‚  Subscriberโ—„โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚             โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ–บ Publisher  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Message Format

[ Topic (string) ] [ Payload (string/binary) ]

For binary messages:

[ Topic Length (4 bytes) ] [ Topic (N bytes) ] [ MsgPack Payload (M bytes) ]

Example Communication Flow

LuaECS                    Renderer                 WindowManager
   โ”‚                         โ”‚                          โ”‚
   โ”‚  RenderEntityCommand    โ”‚                          โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚                          โ”‚
   โ”‚                         โ”‚                          โ”‚
   โ”‚                         โ”‚  (renders frame)         โ”‚
   โ”‚                         โ”‚                          โ”‚
   โ”‚                         โ”‚     ImageRendered        โ”‚
   โ”‚                         โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚                         โ”‚                          โ”‚
   โ”‚                         โ”‚                    (displays)

๐Ÿงต Threading Model

Per-Module Threading

Each module runs in its own thread:

class AModule : public IModule {
protected:
    std::thread _moduleThread;
    std::atomic<bool> _running{false};
    
public:
    void start() override {
        _running = true;
        _moduleThread = std::thread([this]() {
            while (_running) {
                processMessages();
                loop();
            }
        });
    }
};

Benefits

  • Isolation: Slow modules don't block others
  • Parallelism: Utilize multi-core CPUs
  • Resilience: Module crashes are contained

Synchronization

  • Message queues are thread-safe (ZeroMQ handles this)
  • Shared state is minimized
  • Critical sections use mutexes when necessary

๐ŸŽฎ ECS Architecture

Overview

The Entity Component System is implemented in Lua using Sol2:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      LuaECSManager                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚
โ”‚  โ”‚   Entities   โ”‚  โ”‚  Components  โ”‚  โ”‚   Systems    โ”‚       โ”‚
โ”‚  โ”‚              โ”‚  โ”‚              โ”‚  โ”‚              โ”‚       โ”‚
โ”‚  โ”‚  ID: 1 โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”ค Transform    โ”‚  โ”‚ InputSystem  โ”‚       โ”‚
โ”‚  โ”‚  ID: 2 โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”ค Physic       โ”‚  โ”‚ PlayerSystem โ”‚       โ”‚
โ”‚  โ”‚  ID: 3 โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”ค Mesh         โ”‚  โ”‚ RenderSystem โ”‚       โ”‚
โ”‚  โ”‚  ...         โ”‚  โ”‚ ...          โ”‚  โ”‚ ...          โ”‚       โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Components

Components are Lua tables created by factory functions:

function Transform(x, y, z, rx, ry, rz, sx, sy, sz)
    return {
        x = x or 0, y = y or 0, z = z or 0,
        rx = rx or 0, ry = ry or 0, rz = rz or 0,
        sx = sx or 1, sy = sy or 1, sz = sz or 1
    }
end

Systems

Systems process entities with specific components:

local RenderSystem = {}

function RenderSystem.update(dt)
    local entities = ECS.getEntitiesWith({"Transform", "Mesh"})
    for _, id in ipairs(entities) do
        local transform = ECS.getComponent(id, "Transform")
        local mesh = ECS.getComponent(id, "Mesh")
        -- Update rendering...
    end
end

ECS.registerSystem(RenderSystem)

Capabilities System

The ECS supports different runtime modes:

ECS.capabilities = {
    hasAuthority = true,      -- Can modify game state
    hasRendering = true,      -- Has graphics output
    hasLocalInput = true,     -- Has local input
    hasNetworkSync = false,   -- Network synchronization
    isClientMode = false,     -- Running as client
    isServerMode = false      -- Running as server
}

๐ŸŒ Network Architecture

Server-Authoritative Model

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      Server      โ”‚                    โ”‚      Client      โ”‚
โ”‚                  โ”‚                    โ”‚                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚    ECS     โ”‚  โ”‚   ENTITY_POS       โ”‚  โ”‚    ECS     โ”‚  โ”‚
โ”‚  โ”‚ (Authority)โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  โ”‚ (Predicted)โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                  โ”‚                    โ”‚                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚      INPUT         โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  Physics   โ”‚  โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  โ”‚   Input    โ”‚  โ”‚
โ”‚  โ”‚ Simulation โ”‚  โ”‚                    โ”‚  โ”‚  Handler   โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Message Flow

  1. Client sends input โ†’ INPUT message to server
  2. Server processes โ†’ Physics simulation, game logic
  3. Server broadcasts โ†’ ENTITY_POS to all clients
  4. Client interpolates โ†’ Smooth visual updates

Protocol

  • Transport: UDP via ASIO
  • Serialization: MsgPack
  • Update Rate: 20Hz (50ms intervals)

See Network Protocol for details.


๐Ÿ“ฆ Module Reference

WindowManager (SFML)

Purpose: Window creation and input handling

Subscribes to:

  • ImageRendered - Display rendered frames

Publishes:

  • KeyPressed - Key press events
  • KeyReleased - Key release events
  • MousePressed - Mouse click events
  • MouseMoved - Mouse movement events
  • WindowResized - Window resize events

Renderer (GLEW/SFML)

Purpose: 3D rendering with OpenGL

Subscribes to:

  • RenderEntityCommand - Entity rendering commands

Publishes:

  • ImageRendered - Frame ready for display

LuaECSManager

Purpose: Entity Component System with Lua scripting

Subscribes to:

  • Various game events (forwarded to Lua systems)

Publishes:

  • RenderEntityCommand - Rendering instructions
  • PhysicCommand - Physics instructions
  • Sound/Music commands

PhysicEngine (Bullet3)

Purpose: Physics simulation

Subscribes to:

  • PhysicCommand - Physics instructions

Publishes:

  • Collision - Collision events

SoundManager (SFML)

Purpose: Audio playback

Subscribes to:

  • SoundPlay - Play sound effect
  • SoundStopAll - Stop all sounds
  • MusicPlay - Play music
  • MusicStop - Stop music
  • MusicPause / MusicResume - Control music

NetworkManager

Purpose: Client-server communication

Handles:

  • UDP socket management
  • Client connections
  • Message routing
  • Binary protocol encoding/decoding

๐Ÿ”— See Also