cs381/as9/AGENTS.md

6.3 KiB

as9-island-dominion Architecture

Project Identity

  • Directory: as9
  • CMake project name: as9-island-dominion
  • Executable target name: as9-island-dominion
  • Game name: Island Dominion

High-Level Structure

The project is split into five main areas:

  • src/ecs/: the homegrown ECS, following the storage and lookup patterns from as8
  • src/components/: plain data components used by the ECS
  • src/systems/: free-function systems that execute in a fixed order from main
  • src/game/: authoritative game-state structs and pure rules code
  • src/net/: ASIO TCP networking and protocol serialization

ECS Conventions

The ECS should stay very close to as8.

  • Entity is a numeric ID type (size_t)
  • Component type IDs come from a single global component counter in a .cpp file
  • Each component type uses sparse-set style storage with:
  • data
  • packed_entities
  • sparse_indices
  • The central registry owns all component storages via a vector of base pointers, like Context in as8
  • Systems are free functions, not inheritance-heavy classes
  • Main owns the registry and executes systems explicitly in order each frame

as8 did not need entity destruction, but this game does. as9 should preserve the same sparse-set design while adding safe entity destruction and component removal for unit and fortress elimination.

Game State Split

Two representations exist on purpose:

  • ECS state: runtime entities used for rendering, selection, and UI interactions
  • GameState: plain serializable structs used for rules, host authority, and network snapshots

Authoritative rules should operate on GameState, not directly on ECS entities. ECS entities are rebuilt or synchronized from snapshots/state transitions as needed.

Authoritative Networking Model

  • The host is always player 1
  • The client is always player 2
  • Both players run the same executable
  • The host owns the authoritative GameState
  • The client never mutates the game directly; it sends intents to the host
  • After every accepted state change, the host sends a fresh GAME_STATE snapshot to the client

This keeps validation and turn order in one place and avoids divergence between peers.

Networking Responsibilities

NetworkManager owns:

  • the ASIO io_context
  • host accept/connect logic
  • async TCP read/write queues
  • decoded inbound message queues for the game layer
  • disconnect detection and recovery to the startup screen

Protocol messages should stay small and explicit:

  • CONNECT_REQUEST
  • CONNECT_ACK
  • GAME_STATE
  • ACTION_REQUEST
  • COMBAT_CHOICE
  • GAME_OVER

TCP framing should use one consistent format throughout the project. A small length-prefixed binary format is preferred so snapshots remain predictable and easy to parse.

Privacy Rules

Hands are private information.

  • A local player may always know their own hand
  • A received remote snapshot must not expose the opponent's hand contents
  • Public state still includes hand size, discard size, deck size, area control, units, fortresses, turn state, and combat state

Combat Flow

Combat is blocking.

  • A move into an enemy-occupied area starts combat immediately
  • No other actions are processed until the current combat resolves
  • The host waits until both players have submitted a COMBAT_CHOICE
  • After both choices arrive, the host resolves one combat round
  • If both sides still have units, the host requests another round
  • When combat ends, the host checks fortress capture/removal and win conditions, then broadcasts the updated snapshot

Rules Ownership

GameRules should provide pure functions for:

  • board adjacency checks
  • area controller calculation
  • resource collection and cap enforcement
  • action validation
  • action application
  • combat round resolution
  • fortress capture/removal logic
  • win-condition checks

Pure rules code keeps the host logic testable and makes snapshot synchronization simpler.

Rendering and UI Ownership

  • RenderSystem draws the board, areas, units, fortresses, and highlights using raylib-cpp types
  • UISystem draws the startup screen, HUD, combat overlay, disconnect notices, and game-over screen
  • InputSystem translates local mouse/keyboard input into high-level actions or combat choices

The local host can apply validated local actions directly through the host game-logic path. The client instead packages equivalent intents into ACTION_REQUEST or COMBAT_CHOICE messages.

Frame Update Order

Each frame should follow a stable order:

  1. Pump network events and decode inbound messages
  2. Update local input and build pending local intents
  3. Apply host-side game logic if this instance is authoritative
  4. Update ECS/view state from the latest authoritative snapshot
  5. Draw world and UI

This order keeps render state consistent with the latest confirmed game state.

Build and Library Layout

  • Root build file: as9/CMakeLists.txt
  • Raylib wrapper comes from ../raylib-cpp following the as6 pattern
  • ASIO lives in as9/lib/asio
  • Include path should be lib/asio/asio/include
  • Compile definitions should include:
  • ASIO_STANDALONE
  • ASIO_NO_DEPRECATED

Platform link requirements:

  • Linux: pthread
  • Windows: ws2_32 and mswsock

Initial Source Layout

Planned layout:

  • src/ecs/Entity.hpp
  • src/ecs/ComponentStorage.hpp
  • src/ecs/Registry.hpp
  • src/ecs/System.hpp
  • src/components/TransformComponent.hpp
  • src/components/RenderComponent.hpp
  • src/components/UnitComponent.hpp
  • src/components/FortressComponent.hpp
  • src/components/AreaComponent.hpp
  • src/components/PlayerComponent.hpp
  • src/components/CardComponent.hpp
  • src/components/NetworkComponent.hpp
  • src/systems/RenderSystem.hpp/.cpp
  • src/systems/InputSystem.hpp/.cpp
  • src/systems/NetworkSystem.hpp/.cpp
  • src/systems/GameLogicSystem.hpp/.cpp
  • src/systems/CombatSystem.hpp/.cpp
  • src/systems/UISystem.hpp/.cpp
  • src/game/GameState.hpp
  • src/game/GameRules.hpp/.cpp
  • src/game/CardDeck.hpp/.cpp
  • src/net/Protocol.hpp
  • src/net/NetworkManager.hpp/.cpp
  • src/main.cpp

Implementation Priorities

Build the project in this order:

  1. CMake and third-party wiring
  2. ECS infrastructure split from the as8 pattern
  3. Serializable game state and rules
  4. Networking protocol and manager
  5. UI flow for startup, match, combat, disconnect, and game over
  6. Rendering polish and interaction cleanup