couple-repo/Projects/WIP/grove-sup.md
StillHammer fc45332c1c Add GroveEngine supplementary design document
- Complete technical stack (bgfx, SDL2, YAML/JSON/TOML)
- AI-friendly architecture (data-driven entities, UI, missions)
- Rendering 2D implementation details (sprite batching, camera)
- 16-week development plan (5 phases)
- ECS architecture + component examples
- LLM workflow capabilities (create/modify without C++ code)
- Questions ouvertes + risk mitigation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 13:34:49 +08:00

18 KiB

GroveEngine - Supplementary Design Document

Date créé : 24 novembre 2025 Auteur : Alexis (avec Claude Code) Status : Architecture Planning


CONTEXTE

GroveEngine est un moteur de jeu multi-projets conçu pour être :

  • Data-driven : Config/text-based pour tout ce qui est modifiable
  • AI-friendly : LLM peut créer/modifier assets sans toucher au code C++
  • Multi-backend rendering : Support Vulkan/DX12/Metal/OpenGL via bgfx
  • Solide & réutilisable : Foundation pour plusieurs projets

État actuel :

  • Coeur engine done (mode debug)
  • Pas de rendering
  • Pas de framework 2D/UI

PROJETS BASÉS SUR GROVEENGINE

  1. Pokrovsk: Iron Line (survival management, train builder)
  2. AISSIA (concepts via SecondVoice/YT-DL)
  3. Troisième projet : À définir

Objectif : Un seul moteur, plusieurs jeux, maintenance centralisée.


STACK TECHNIQUE

Rendering

  • bgfx : Abstraction multi-backend (Vulkan/DX12/Metal/OpenGL)

    • Multi-platform par design
    • Performant pour 2D (batching, sprites)
    • Mature (utilisé par Defold engine)
    • Dev : Branimir Karadzic (ex-Frostbite EA)
  • SDL2 : Windowing + input

    • Cross-platform
    • Léger, bien supporté
  • stb_image : Texture loading

    • Single-header, simple

Serialization/Config

  • yaml-cpp : YAML parsing

    • Entities definitions
    • Missions, events, dialogues
  • nlohmann/json : JSON parsing

    • UI layouts
    • Save files
    • Asset manifests (alternative)
  • TOML++ : Config files

    • Settings, constants
    • Game balance values

UI

  • ImGui : Debug/tools UI (dev only)

    • Immediate mode
    • Parfait pour tools
  • Custom UI system (bgfx-based) : In-game UI

    • JSON-driven layouts
    • Rendering via bgfx
    • Themeable

Scripting (optionnel)

  • Lua : Si besoin de scripting pour game logic
  • Alternative : Config-only (YAML events + state machines)
    • Plus simple
    • Assez pour beaucoup de cas

ARCHITECTURE AI-FRIENDLY

Principe : LLM peut créer/modifier game content sans toucher au code C++.

1. Entity System (Data-Driven)

Structure :

entities/
├── wagons/
│   ├── wagon_basic.yaml
│   ├── wagon_armored.yaml
│   └── wagon_workshop.yaml
├── drones/
│   ├── mavic_reco.yaml
│   └── fpv_strike.yaml
└── humans/
    └── commandant_template.yaml

Exemple : entities/wagons/wagon_basic.yaml

entity: wagon_basic
components:
  - type: visual
    sprite: wagon_base.png
    size: [20, 6]  # Grille interne

  - type: balance
    weight: 5.0
    center_of_mass: [10, 3]
    dampeners: 0  # Upgrade level

  - type: slots
    grid: [20, 6]
    layers: [high, low]
    specialization: null  # production, logistic, habitation, military

  - type: health
    hp_max: 100
    armor: 10

LLM peut : Créer nouveaux wagons, tweaker stats, ajouter composants.


2. UI Layouts (Declarative JSON)

Structure :

ui/
├── screens/
│   ├── train_builder.json
│   ├── mission_briefing.json
│   └── campaign_map.json
└── widgets/
    ├── balance_gauge.json
    └── resource_panel.json

Exemple : ui/screens/train_builder.json

{
  "screen": "train_builder",
  "elements": [
    {
      "type": "panel",
      "id": "wagon_view",
      "rect": [0, 0, 800, 600],
      "background": "#2a2a2a",
      "children": [
        {
          "type": "sprite",
          "id": "wagon_display",
          "anchor": "center"
        }
      ]
    },
    {
      "type": "gauge",
      "id": "balance_lateral",
      "rect": [820, 20, 160, 40],
      "label": "Balance G/D",
      "min": -10,
      "max": 10,
      "value_binding": "wagon.balance.lateral",
      "color_good": "#00ff00",
      "color_warning": "#ffaa00",
      "color_bad": "#ff0000"
    },
    {
      "type": "text",
      "id": "wagon_name",
      "rect": [820, 80, 160, 30],
      "text_binding": "wagon.name",
      "font": "main_ui",
      "size": 18,
      "color": "#ffffff"
    }
  ]
}

LLM peut : Créer UI screens, repositionner éléments, modifier styles, créer layouts.


3. Game Logic (Config-Driven Events)

Structure :

content/
├── missions/
│   ├── 2022_early/
│   │   ├── scavenge_kyiv.yaml
│   │   └── rescue_civilians.yaml
│   └── 2025_late/
│       └── drone_intercept.yaml
├── events/
│   ├── random_events.yaml
│   └── story_events.yaml
└── dialogues/
    └── commandants/
        ├── sergei.yaml
        └── oksana.yaml

Exemple : missions/2022_early/scavenge_kyiv.yaml

mission:
  id: scavenge_kyiv_outskirts
  name: "Colonne russe détruite - Périphérie Kyiv"
  year: 2022
  period: early
  difficulty: easy

  briefing:
    text: |
      Colonne blindée russe détruite à 2km au nord.
      Reconnaissance indique 8-10 véhicules abandonnés.
      Opposition minimale attendue.      

    intel:
      - "Matériel récent, peu endommagé"
      - "Zone relativement sécurisée"
      - "Temps limité avant arrivée autres scavengers"

  rewards:
    metal: [50, 100]
    electronics: [20, 40]
    components_military: [5, 15]
    fame: 10

  risks:
    - type: ambush
      probability: 0.1
    - type: mines
      probability: 0.15

  events:
    - trigger: mission_start
      text: "Votre équipe approche la colonne détruite..."
      choices:
        - id: approach_cautious
          text: "Approche prudente (sweep mines)"
          time_cost: 2h
          risk_modifier: -0.5

        - id: rush
          text: "Rush rapide (grab & go)"
          time_cost: 30min
          risk_modifier: +0.8
          reward_modifier: 1.2

    - trigger: loot_phase
      condition: "approach_cautious"
      text: "Temps de fouiller méthodiquement..."
      outcomes:
        - probability: 0.7
          result: success
          rewards_modifier: 1.0
        - probability: 0.3
          result: partial
          rewards_modifier: 0.6

LLM peut : Créer missions, events, dialogues, choix, outcomes.


4. Asset Pipeline (Text Metadata)

Structure :

assets/
├── sprites/
│   ├── wagons.manifest
│   ├── drones.manifest
│   └── ui.manifest
├── textures/
│   └── (PNG files)
└── fonts/
    └── fonts.manifest

Exemple : assets/sprites/wagons.manifest (TOML)

[wagon_base]
file = "textures/wagon_base.png"
size = [400, 120]
pivot = [200, 60]
tags = ["wagon", "basic"]

[wagon_armored]
file = "textures/wagon_armored.png"
size = [400, 120]
pivot = [200, 60]
weight_modifier = 1.5
tags = ["wagon", "armored", "heavy"]

[wagon_workshop]
file = "textures/wagon_workshop.png"
size = [400, 140]  # Plus haut
pivot = [200, 70]
specialization = "production"
tags = ["wagon", "specialized"]

LLM peut : Définir assets, metadata, tags, modifiers.


ARCHITECTURE ENGINE

Core Systems

1. Entity Component System (ECS)

class Entity {
    EntityID id;
    std::vector<Component*> components;
};

class Component {
    virtual void Update(float dt) = 0;
    virtual void Serialize(YAML::Node& node) = 0;
    virtual void Deserialize(const YAML::Node& node) = 0;
};

// Exemples components
class VisualComponent : public Component { ... }
class BalanceComponent : public Component { ... }
class SlotsComponent : public Component { ... }

2. Asset Manager

class AssetManager {
    // Textures
    std::map<std::string, bgfx::TextureHandle> textures;

    // Manifests (metadata)
    std::map<std::string, AssetMetadata> metadata;

    // Fonts
    std::map<std::string, FontHandle> fonts;

    void LoadManifest(const std::string& path);
    bgfx::TextureHandle GetTexture(const std::string& id);
};

3. Config System

class ConfigManager {
    YAML::Node LoadYAML(const std::string& path);
    nlohmann::json LoadJSON(const std::string& path);

    Entity* CreateEntityFromYAML(const std::string& entity_id);
    UIScreen* CreateUIFromJSON(const std::string& screen_id);
};

4. Rendering 2D (bgfx-based)

class Renderer2D {
    bgfx::ProgramHandle sprite_shader;

    // Sprite batching pour performance
    struct SpriteBatch {
        std::vector<SpriteVertex> vertices;
        bgfx::TextureHandle texture;
    };

    void DrawSprite(const Sprite& sprite);
    void DrawRect(const Rect& rect, Color color);
    void DrawText(const std::string& text, Font font, Vec2 pos);

    void Flush();  // Submit batched draws
};

5. UI System (JSON-driven)

class UIManager {
    std::map<std::string, UIScreen*> screens;

    UIScreen* LoadScreen(const std::string& screen_json);
    void Update(float dt);
    void Render(Renderer2D& renderer);

    // Data binding
    void BindValue(const std::string& path, float* value);
    void BindText(const std::string& path, std::string* text);
};

class UIElement {
    std::string id;
    Rect rect;
    virtual void Render(Renderer2D& renderer) = 0;
    virtual void Update(float dt) = 0;
};

// Concrete elements
class UIPanel : public UIElement { ... }
class UIGauge : public UIElement { ... }
class UIText : public UIElement { ... }
class UISprite : public UIElement { ... }

RENDERING 2D AVEC BGFX

Concept de base

bgfx ne fait PAS de 2D directement → Tu construis la couche 2D par-dessus.

Primitive : Quad (pour sprites)

struct SpriteVertex {
    float x, y, z;     // Position
    float u, v;        // UV coords (texture)
    uint32_t color;    // Tint color (ABGR)
};

// Vertex layout bgfx
bgfx::VertexLayout sprite_layout;
sprite_layout.begin()
    .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
    .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
    .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
    .end();

Sprite Rendering

void Renderer2D::DrawSprite(const Sprite& sprite) {
    // 1. Batch sprite (grouper par texture)
    GetOrCreateBatch(sprite.texture).AddQuad(sprite);
}

void Renderer2D::Flush() {
    // 2. Pour chaque batch, submit draw call
    for (auto& batch : batches) {
        bgfx::setTexture(0, sampler, batch.texture);
        bgfx::setVertexBuffer(0, batch.vertex_buffer);
        bgfx::setIndexBuffer(batch.index_buffer);
        bgfx::setState(BGFX_STATE_DEFAULT);
        bgfx::submit(view_id, sprite_shader);
    }
    batches.clear();
}

Camera 2D (Orthographic)

class Camera2D {
    Vec2 position;
    float zoom;

    Mat4 GetViewMatrix() const {
        return Mat4::Translation(-position.x, -position.y, 0);
    }

    Mat4 GetProjectionMatrix(int width, int height) const {
        float halfW = (width / zoom) * 0.5f;
        float halfH = (height / zoom) * 0.5f;
        return Mat4::Ortho(-halfW, halfW, -halfH, halfH, -1, 1);
    }
};

// Usage
bgfx::setViewTransform(view_id,
    camera.GetViewMatrix().data,
    camera.GetProjectionMatrix(screenW, screenH).data
);

PLAN DE DÉVELOPPEMENT

Phase 1 : Core Engine (3-4 semaines)

Semaine 1-2 : Setup bgfx + SDL2

  • Intégrer bgfx, bx, bimg dans projet (git submodules)
  • Build bgfx pour platform cible
  • Window SDL2 + init bgfx
  • Clear screen avec couleur
  • Input basique (keyboard, mouse)

Semaine 3 : Rendering 2D basique

  • Vertex layout sprites
  • Shader simple (texture + color tint)
  • Afficher 1 sprite (quad texturé)
  • Camera 2D orthographique

Semaine 4 : Asset Pipeline

  • Texture loading (stb_image)
  • AssetManager basique
  • Manifest TOML (assets metadata)
  • Load sprite from manifest

Phase 2 : Framework 2D (2-3 semaines)

Semaine 5 : Sprite System

  • Sprite batching (group by texture)
  • DrawSprite API
  • DrawRect (colored quads)
  • Transform system (position, rotation, scale)

Semaine 6 : UI Primitives

  • Text rendering (stb_truetype ou FreeType)
  • Font loading via manifest
  • DrawText API
  • UI elements basiques (Panel, Text, Sprite)

Semaine 7 : Input & Interaction

  • Mouse picking (screen → world coords)
  • Drag & drop basique
  • Button clicks
  • Input manager

Phase 3 : Entity System (2-3 semaines)

Semaine 8 : ECS Core

  • Entity class
  • Component base class
  • Entity manager (create, destroy, query)
  • YAML serialization/deserialization

Semaine 9 : Components Library

  • VisualComponent (sprite rendering)
  • TransformComponent (position, rotation)
  • BalanceComponent (pour Pokrovsk wagons)
  • SlotsComponent (grille placement)

Semaine 10 : Config Integration

  • Load entity from YAML
  • Entity templates system
  • Component factory (deserialize components)

Phase 4 : UI System (2-3 semaines)

Semaine 11 : UI Framework

  • UIElement base class
  • UIManager (screen stack)
  • Layout system (anchors, rects)
  • JSON UI loading

Semaine 12 : UI Widgets

  • UIPanel
  • UIText (with data binding)
  • UIGauge (progress bar, balance gauge)
  • UIButton

Semaine 13 : Advanced UI

  • Data binding system (link UI ↔ game data)
  • Events (onClick, onHover)
  • Theming (colors, fonts from config)

Phase 5 : Validation Pokrovsk (2-3 semaines)

Semaine 14 : Wagon Entity

  • Wagon YAML definition
  • Instantiate wagon from config
  • Render wagon sprite (double slice)
  • Display balance gauges (UI)

Semaine 15 : Train Builder UI

  • Train builder screen (JSON)
  • Grid overlay (slots)
  • Drag & drop elements (atelier, stockage, dortoir)
  • Real-time balance calculation

Semaine 16 : Polish & Validation

  • Balance visualization (wagon tilts if unbalanced)
  • Element placement constraints
  • Save/load train configuration
  • Prototype jouable = validation complète

TOTAL : ~10-16 semaines pour moteur complet + prototype Pokrovsk


AVANTAGES POUR LLM

Ce que LLM peut créer/modifier sans code C++ :

Entities

  • Wagons (YAML) : stats, composants, visuel
  • Drones (YAML) : types, capacités
  • Commandants (YAML) : skills, personnalité
  • Missions (YAML) : events, choix, rewards

UI

  • Screens (JSON) : layouts, elements
  • Widgets (JSON) : gauges, panels, text
  • Themes (JSON) : colors, fonts, styles

Content

  • Dialogues (YAML)
  • Events (YAML)
  • Story beats (YAML)
  • Balance values (TOML)

Assets

  • Manifests (TOML) : sprites metadata
  • Tags, categories, filters
  • Asset relationships

Workflow LLM

Exemple : "Créer un nouveau wagon blindé lourd"

  1. LLM crée entities/wagons/wagon_heavy_armored.yaml
  2. LLM met à jour assets/sprites/wagons.manifest (nouveau sprite)
  3. LLM peut tester en modifiant une mission pour donner ce wagon
  4. Aucun code C++ touché

QUESTIONS OUVERTES

Architecture

  1. Scripting Lua ou config-only ?

    • Lua = plus flexible pour game logic
    • Config = plus simple, assez pour events/missions
    • Décision : À trancher selon complexité game logic
  2. Save system format ?

    • JSON (human-readable, LLM-friendly)
    • Binaire (compact, rapide)
    • Recommandation : JSON pour dev, option binaire pour release
  3. Networking futur ?

    • Pokrovsk = solo only
    • Autres projets ?
    • Impact : Architecture ECS doit supporter network sync ou pas

Performance

  1. Sprite batching strategy ?

    • Batch par texture (standard)
    • Batch par layer (z-order)
    • Décision : Tester performance avec prototype
  2. Entity pooling ?

    • Object pooling pour éviter alloc/dealloc
    • Critical pour drones (100+ entities)
    • Recommandation : Oui, implement dès Phase 3

Tooling

  1. Level editor ?

    • ImGui-based editor in-engine
    • Externe (web-based ?)
    • Recommandation : ImGui in-engine = plus rapide
  2. Asset hot-reload ?

    • Reload YAML/JSON/textures sans restart
    • Crucial pour iteration rapide
    • Recommandation : Oui, implement Phase 2-3

DÉPENDANCES EXTERNES

Obligatoires

Optionnelles


RISQUES & MITIGATION

Risque Impact Probabilité Mitigation
bgfx trop complexe HAUT MOYEN Exemples officiels, communauté active
Scope creep framework HAUT HAUT Lock features après Phase 4, focus prototype
Performance 2D insuffisante MOYEN FAIBLE Batching + profiling dès Phase 2
Config system trop rigide MOYEN MOYEN Itérer avec prototype Pokrovsk
LLM-generated content bugs MOYEN MOYEN Validation schema (JSON schema, YAML schema)
Timeline trop optimiste HAUT MOYEN Buffers 20% par phase

RÉFÉRENCES

bgfx

Architecture ECS

  • "Overwatch Gameplay Architecture" (GDC Talk)
  • "Data-Oriented Design" (Richard Fabian)

2D Rendering bgfx


NEXT STEPS

  1. Setup projet : Créer repo GroveEngine, structure folders
  2. Intégrer bgfx : Submodules + build
  3. Hello Triangle : Première fenêtre + rendering
  4. Suivre plan Phase 1 : 4 semaines pour core engine

Document Version : 1.0 Status : Architecture Design Owner : Alexis Related : Projects/CONCEPT/pokrovsk_iron_line_v2.md