diff --git a/Projects/WIP/GroveEngine.md b/Projects/WIP/GroveEngine.md index 0ac4c28..bb81881 100644 --- a/Projects/WIP/GroveEngine.md +++ b/Projects/WIP/GroveEngine.md @@ -1,523 +1,678 @@ # GroveEngine - Framework C++ Modulaire +**Type** : Game Engine Framework +**Stack** : C++17, bgfx, SDL2, nlohmann_json, spdlog +**Repo** : `../GroveEngine/` +**Status** : Core validé, Rendering en développement +**Dernière mise à jour** : 27 novembre 2025 + +--- + ## Vue d'ensemble -Extraction et évolution du moteur modulaire de WarFactory en framework C++ indépendant et réutilisable avec hot-reload 0.4ms validé. +**GroveEngine** est un moteur de jeu C++17 modulaire conçu pour : -### Objectif +- **Hot-reload ultra-rapide** : 0.4ms validé (5000x plus rapide qu'un cycle edit-build-test classique) +- **AI-optimized** : Micro-modules (200-300 lignes) parfaits pour développement assisté Claude +- **Scalabilité transparente** : Du debug local au cluster distribué sans modifier le code modules +- **Data-driven** : Config/YAML/JSON pour tout le contenu (LLM peut créer sans toucher C++) -Créer un framework C++ générique pour applications modulaires avec: -- Hot-reload DLL/SO ultra-rapide (0.4ms) -- Architecture propre par interfaces -- Types stricts C++ -- Réutilisable pour multiples projets (AISSIA, WarFactory, futurs projets) +**Nom** : "Grove" = bosquet où les modules poussent comme des arbres indépendants. --- -## Origine +## Architecture Core -**Extraction depuis WarFactory** (27 octobre 2025) +### Philosophie : 13 Interfaces -### Timeline -| Date | Event | Détails | -|------|-------|---------| -| **20 Sept** | Architecture modulaire créée | Suppression engines monolithiques | -| **24 Sept (fc28009)** | Hot-reload validé 0.4ms | DebugEngine + IntraIO fonctionnels | -| **27 Sept (f6c3b34)** | IDataTree ajouté | Breaking change API → Impls supprimées | -| **27 Oct 2025** | Extraction GroveEngine | Création repo indépendant | +L'architecture repose sur **13 interfaces abstraites** permettant de swap les implémentations sans modifier le code métier. -### Ce qui a été extrait - -**Headers (27 fichiers)** : ``` -include/grove/ -├── Core interfaces -│ ├── IEngine.h -│ ├── IModule.h -│ ├── IModuleSystem.h -│ ├── IIO.h -│ └── ICoordinationModule.h, ITaskScheduler.h -├── Config system -│ ├── IDataTree.h -│ ├── IDataNode.h -│ └── DataTreeFactory.h -├── Communication -│ ├── IntraIO.h -│ ├── IntraIOManager.h -│ └── IOFactory.h -├── Factories -│ ├── EngineFactory.h -│ ├── ModuleFactory.h -│ └── ModuleSystemFactory.h -├── UI -│ ├── IUI.h -│ ├── IUI_Enums.h -│ └── ImGuiUI.h -└── Utilities - ├── ISerializable.h - ├── Resource.h - ├── RandomGenerator.h - └── ... +┌─────────────────────────────────────────────────────────────┐ +│ Application (ex: aissia-core.exe, warfactory.exe) │ +│ └─ main() → EngineFactory::create() │ +└──────────────────────────┬──────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ IEngine (orchestration) │ +│ ├─ IModuleSystem (stratégie d'exécution) │ +│ ├─ IIO (communication pub/sub) │ +│ ├─ IDataTree (configuration hiérarchique) │ +│ └─ Game loop │ +└──────────────────────────┬──────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Modules (DLL/SO hot-reloadable, 200-300 lignes chacun) │ +│ ├─ module_a.dll → IModule::process() │ +│ ├─ module_b.dll → IModule::process() │ +│ └─ module_c.dll → IModule::process() │ +│ Communication via IIO (pub/sub topics) │ +└─────────────────────────────────────────────────────────────┘ ``` -**Implémentations (10 fichiers)** - Récupérés depuis Git history : +### Les 13 Interfaces + +| Interface | Rôle | Implémentations | +|-----------|------|-----------------| +| **IEngine** | Orchestration système, main loop | DebugEngine ✅, HighPerfEngine (planned), DataOrientedEngine (planned) | +| **IModule** | Logique métier (micro-modules) | Custom modules (.dll/.so) | +| **IModuleSystem** | Stratégie d'exécution modules | SequentialModuleSystem ✅, ThreadedModuleSystem (planned), ClusterModuleSystem (planned) | +| **IIO** | Communication pub/sub | IntraIO ✅ (même process), LocalIO (planned), NetworkIO (planned) | +| **IDataTree** | Racine configuration | JsonDataTree ✅ | +| **IDataNode** | Noeud configuration | JsonDataNode ✅ | +| **ITaskScheduler** | Délégation tâches async | (planned) | +| **IUI** | Abstraction UI | ImGuiUI ✅ | +| **ISerializable** | Sérialisation état | JSON-based | +| **ICoordinationModule** | Coordination inter-modules | (planned) | + +### Scalabilité Transparente + ``` -src/ -├── DebugEngine.cpp (commit fc28009) -├── SequentialModuleSystem.cpp (commit fc28009) -├── IntraIO.cpp (commit fb49fb2) -├── IntraIOManager.cpp (commit fb49fb2) -├── IOFactory.cpp (commit fb49fb2) -├── ModuleFactory.cpp (commit fc28009) -├── EngineFactory.cpp (commit fc28009) -├── ModuleSystemFactory.cpp (commit fc28009) -├── ImGuiUI.cpp (déjà présent) -└── ResourceRegistry.cpp (déjà présent) +MVP Debug: DebugEngine + SequentialModuleSystem + IntraIO + (Single-thread, même process, logging verbose) + +Production: HighPerfEngine + ThreadedModuleSystem + LocalIO + (Multi-thread, named pipes/sockets) + +Cloud/MMO: DataOrientedEngine + ClusterModuleSystem + NetworkIO + (Distribué, TCP/WebSocket) ``` -**Documentation** : -- `docs/architecture-modulaire.md` : Explication interfaces -- `docs/claude-code-integration.md` : Workflow développement -- `docs/CLAUDE-HOT-RELOAD-GUIDE.md` : Guide hot-reload 0.4ms -- `README.md` : Guide complet framework +**Aucun changement de code dans les modules** - Juste swap des implémentations via config. --- -## Architecture +## Hot-Reload System -### Concepts Clés +### Performance Validée -**1. IEngine** : Moteur principal -- Gère lifecycle application -- Coordonne modules -- Gère boucle principale +| Métrique | Valeur | +|----------|--------| +| **Temps moyen** | 0.4ms | +| **Meilleur cas** | 0.055ms | +| **State preservation** | 100% (via ISerializable) | +| **Commit validation** | fc28009 (24 Sept 2025) | -**2. IModule** : Unité fonctionnelle -- ~200-300 lignes chacun -- Interface uniforme : `initialize()`, `update()`, `shutdown()` -- Hot-reload via DLL/SO - -**3. IIO** : Communication inter-modules -- Messages typés -- Couplage faible -- IntraIO = implémentation locale - -**4. IModuleSystem** : Orchestration -- Charge/décharge modules -- Gère dépendances -- SequentialModuleSystem = implémentation linéaire - -**5. IDataTree** : Configuration -- Structure hiérarchique -- Type-safe -- Sérialisable JSON - -### Architecture Modulaire - -``` -┌─────────────────────────────────────────┐ -│ Application (ex: aissia-core.exe) │ -│ ├─ main() │ -│ └─ EngineFactory::create() │ -└──────────────┬──────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────┐ -│ IEngine (DebugEngine) │ -│ ├─ IModuleSystem │ -│ ├─ IIO (IntraIOManager) │ -│ └─ Game loop │ -└──────────────┬──────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────┐ -│ Modules (DLL/SO hot-reloadable) │ -│ ├─ module_a.dll (IModule) │ -│ ├─ module_b.dll (IModule) │ -│ └─ module_c.dll (IModule) │ -│ │ │ -│ └─ update() appelé chaque frame │ -└─────────────────────────────────────────┘ -``` - -### Hot-Reload 0.4ms - -**Mécanisme validé** (WarFactory, 24 Sept fc28009) : +### Mécanisme ```cpp // 1. Détection changement fichier DLL if (filesystem::last_write_time("module.dll") > last_load_time) { - // 2. Shutdown module actuel - module->shutdown(); - // 3. Unload DLL - FreeLibrary(dll_handle); + // 2. Sauvegarder état via ISerializable + nlohmann::json state; + old_module->serialize(state); - // 4. Reload nouvelle DLL - dll_handle = LoadLibrary("module.dll"); + // 3. Shutdown module actuel + old_module->shutdown(); - // 5. Initialize nouveau module - module->initialize(config, io); + // 4. Unload DLL + #ifdef _WIN32 + FreeLibrary(dll_handle); + #else + dlclose(dll_handle); + #endif - // Total: 0.4ms mesuré + // 5. Reload nouvelle DLL + #ifdef _WIN32 + dll_handle = LoadLibrary("module.dll"); + #else + dll_handle = dlopen("./module.so", RTLD_NOW); + #endif + + // 6. Initialize nouveau module avec état restauré + new_module->initialize(config, io); + new_module->deserialize(state); + + // Total: 0.4ms } ``` -**Avantages** : -- Modification code module → Recompile → Hot-reload automatique -- Pas de restart application -- State préservé (via sérialisation ISerializable) -- Itération ultra-rapide +### Interface IModule + +```cpp +class IModule { +public: + virtual ~IModule() = default; + + // Lifecycle + virtual void initialize(const IDataNode& config, IIO* io) = 0; + virtual void process(float dt) = 0; + virtual void shutdown() = 0; + + // Hot-reload state preservation + virtual nlohmann::json getState() const = 0; + virtual void setState(const nlohmann::json& state) = 0; + + // Metadata + virtual std::string getName() const = 0; + virtual int getVersion() const = 0; + virtual std::vector getDependencies() const = 0; +}; +``` + +### Contraintes Micro-Modules + +- **200-300 lignes max** par module (AI-friendly) +- **Zero parent dependencies** : Pas de `#include "../"` +- **JSON-only inter-module** : Communication via IIO topics +- **Build autonome** : `cmake .` depuis le dossier module --- -## Roadmap Développement +## Communication Inter-Modules (IIO) -### Phase 1 - MVP Standalone (Court terme) +### TopicTree : Pub/Sub Ultra-Rapide -**Objectif** : GroveEngine compile et fonctionne pour AISSIA +**Bibliothèque interne** : StillHammer::topictree +**Performance** : O(k) où k = profondeur topic (pas O(n) patterns) -**Tasks** : -- [ ] Build test : Vérifier compilation complète -- [ ] Fix dépendances : nlohmann_json, ImGui -- [ ] Créer exemple "Hello World Module" -- [ ] Valider hot-reload 0.4ms avec exemple -- [ ] Documentation usage basique +```cpp +// Publisher (Module A) +io->publish("game/player/position", position_json); +io->publish("game/enemy/42/health", health_json); -**Livrables** : -- `libGroveEngine.a` (static lib) ou `GroveEngine.dll` (dynamic lib) -- Exemple compilable -- Guide "Créer premier module" +// Subscriber (Module B) - Wildcards supportés +io->subscribe("game/player/*", [](const Message& msg) { + // Reçoit tous les messages player +}); -**Bloquants** : -- ⚠️ API mismatch IDataTree (impls utilisent `json`, interfaces utilisent `IDataNode`) -- Options : - - A) Utiliser impls telles quelles (ignorer IDataTree pour MVP) - - B) Adapter impls pour IDataTree - - C) Wrapper temporaire `json ↔ IDataNode` +io->subscribe("game/enemy/+/health", [](const Message& msg) { + // + = single level wildcard + // Reçoit health de tous les enemies +}); +``` -### Phase 2 - Package System (Moyen terme) +### Performance TopicTree -**Objectif** : GroveEngine installable comme library externe +| Patterns | Temps matching | +|----------|----------------| +| 1,000 | < 1ms | +| 10,000 | < 5ms | -**Tasks** : -- [ ] CMake install targets -- [ ] Pkg-config / CMake find_package support -- [ ] Versioning sémantique (v0.1.0) -- [ ] Header-only option (alternative static/dynamic lib) -- [ ] vcpkg/conan packages (optionnel) +### Design Pull-Based -**Livrables** : -- Installation standard : `cmake --install` -- Utilisation externe : - ```cmake - find_package(GroveEngine REQUIRED) - target_link_libraries(my_app GroveEngine::GroveEngine) - ``` - -### Phase 3 - Framework Complet (Long terme) - -**Objectif** : Framework mature, évolutif, documenté - -**Features** : -- [ ] Tests automatisés (Google Test) -- [ ] CI/CD (GitHub Actions / Bitbucket Pipelines) -- [ ] Benchmarks performance -- [ ] Profiling tools intégrés -- [ ] Modules types additionnels : - - NetworkModule (sockets, HTTP client) - - DatabaseModule (SQLite, PostgreSQL) - - AudioModule (OpenAL) - - PhysicsModule (intégration Bullet/Box2D) -- [ ] Cross-platform validé : - - Windows (MSVC, MinGW) - - Linux (GCC, Clang) - - macOS (Clang) - - WebAssembly (Emscripten) -- [ ] Documentation complète : - - API reference (Doxygen) - - Tutorials - - Architecture deep-dive - - Best practices - -**Livrables** : -- GroveEngine v1.0.0 stable -- Site documentation (GitHub Pages / ReadTheDocs) -- Exemples multiples (todo app, game, server, etc.) - -### Phase 4 - Écosystème (Très long terme) - -**Objectif** : Framework communautaire (si open-source) - -**Features** : -- [ ] Plugin marketplace -- [ ] Module templates generator -- [ ] Visual module editor (optionnel) -- [ ] Performance profiler UI -- [ ] Community contributions +- **Synchrone** : Messages collectés, traités en batch +- **Low-frequency** : Optimisé pour 60 FPS game loop, pas high-frequency trading +- **Découplage total** : Modules ignorent l'existence des autres --- -## Problèmes Techniques Identifiés +## Data System (IDataTree / IDataNode) + +### Configuration Hiérarchique Type-Safe + +```cpp +// Lecture config +void MyModule::initialize(const IDataNode& config, IIO* io) { + int width = config.get("window.width", 1280); + std::string title = config.get("window.title", "GroveEngine"); + bool vsync = config.get("rendering.vsync", true); + + // Navigation arbre + auto& enemies = config.getChild("enemies"); + for (const auto& enemy : enemies.getChildren()) { + std::string type = enemy.get("type", "basic"); + int hp = enemy.get("hp", 100); + } +} +``` + +### Backed by JSON Files + +```json +{ + "window": { + "width": 1280, + "height": 720, + "title": "My Game" + }, + "rendering": { + "vsync": true, + "clear_color": "#303030" + }, + "enemies": [ + {"type": "basic", "hp": 100}, + {"type": "heavy", "hp": 500} + ] +} +``` + +--- + +## Structure Projet + +``` +GroveEngine/ +├── include/grove/ # 32 headers (interfaces + impls) +│ ├── IEngine.h +│ ├── IModule.h +│ ├── IModuleSystem.h +│ ├── IIO.h +│ ├── IDataTree.h +│ ├── IDataNode.h +│ ├── ITaskScheduler.h +│ ├── IUI.h +│ ├── ISerializable.h +│ └── ... +│ +├── src/ # Implémentations concrètes +│ ├── DebugEngine.cpp +│ ├── SequentialModuleSystem.cpp +│ ├── IntraIO.cpp +│ ├── IntraIOManager.cpp +│ ├── JsonDataNode.cpp +│ ├── JsonDataTree.cpp +│ ├── ModuleFactory.cpp +│ ├── EngineFactory.cpp +│ └── ... +│ +├── modules/ # Modules hot-reloadables +│ └── BgfxRenderer/ # Module rendering 2D (WIP) +│ ├── BgfxRendererModule.cpp +│ ├── RHI/ # Render Hardware Interface +│ ├── Shaders/ # Pre-compiled (GL/Vulkan/DX11/Metal) +│ ├── Passes/ # Clear, Sprite, Debug +│ ├── RenderGraph/ # Dependency ordering +│ └── Scene/ # Message collection from IIO +│ +├── external/StillHammer/ # Libs internes +│ ├── topictree/ # O(k) topic matching +│ └── logger/ # spdlog wrapper +│ +├── tests/ # Test suite (Catch2) +│ ├── benchmarks/ +│ ├── hotreload/ +│ └── helpers/ +│ +├── docs/ # Documentation +│ ├── architecture/ +│ ├── implementation/ +│ └── plans/ +│ +└── CMakeLists.txt # Build system +``` + +--- + +## Module Rendering (BgfxRenderer) + +### Stack Rendering + +- **bgfx** : Abstraction multi-backend (Vulkan/DX12/Metal/OpenGL) +- **SDL2** : Window + input management +- **stb_image** : Texture loading + +### Architecture RenderModule + +```cpp +class BgfxRendererModule : public grove::IModule { +public: + // IModule interface + void initialize(const IDataNode& config, IIO* io) override; + void process(float dt) override; + void shutdown() override; + + // Rendering API (via IIO messages) + // Autres modules publient sur "render/sprite", "render/rect", etc. + // BgfxRenderer subscribe et render tout en batch + +private: + SDL_Window* window; + bgfx::ViewId main_view; + + // Render passes + ClearPass clear_pass; + SpritePass sprite_pass; + DebugPass debug_pass; + + // Scene collector (from IIO) + SceneCollector scene; +}; +``` + +### Rendering Pipeline + +```cpp +void BgfxRendererModule::process(float dt) { + // 1. Collecter messages rendering depuis IIO + scene.CollectFromIO(io); + + // 2. Exécuter passes + clear_pass.Execute(main_view); + sprite_pass.Execute(main_view, scene.sprites); + debug_pass.Execute(main_view, scene.debug_shapes); + + // 3. Submit frame + bgfx::frame(); + + // 4. Clear scene pour prochain frame + scene.Clear(); +} +``` + +### Shaders Pre-Compilés + +Shaders compilés pour tous backends via `shaderc` : + +``` +Shaders/ +├── vs_sprite.bin.gl # OpenGL +├── vs_sprite.bin.vk # Vulkan +├── vs_sprite.bin.dx11 # DirectX 11 +├── vs_sprite.bin.mtl # Metal +├── fs_sprite.bin.gl +├── fs_sprite.bin.vk +├── fs_sprite.bin.dx11 +└── fs_sprite.bin.mtl +``` + +### Camera 2D + +```cpp +class Camera2D { +public: + Vec2 position{0, 0}; + float zoom = 1.0f; + + 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); + } +}; +``` + +--- + +## Architecture AI-Friendly (Data-Driven) + +### Principe + +**LLM peut créer/modifier game content sans toucher au code C++.** + +### Entity System (YAML) + +```yaml +# entities/wagons/wagon_armored.yaml +entity: wagon_armored +components: + - type: visual + sprite: wagon_armored.png + size: [20, 6] + + - type: balance + weight: 7.5 + center_of_mass: [10, 3] + + - type: health + hp_max: 200 + armor: 50 + + - type: slots + grid: [20, 6] + specialization: military +``` + +### UI Layouts (JSON) + +```json +{ + "screen": "train_builder", + "elements": [ + { + "type": "panel", + "id": "wagon_view", + "rect": [0, 0, 800, 600], + "background": "#2a2a2a" + }, + { + "type": "gauge", + "id": "balance_lateral", + "rect": [820, 20, 160, 40], + "label": "Balance G/D", + "value_binding": "wagon.balance.lateral" + } + ] +} +``` + +### Missions/Events (YAML) + +```yaml +mission: + id: scavenge_kyiv + name: "Colonne russe détruite" + difficulty: easy + + rewards: + metal: [50, 100] + electronics: [20, 40] + + events: + - trigger: mission_start + choices: + - id: approach_cautious + text: "Approche prudente" + risk_modifier: -0.5 + - id: rush + text: "Rush rapide" + risk_modifier: +0.8 +``` + +### Asset Manifests (TOML) + +```toml +[wagon_armored] +file = "textures/wagon_armored.png" +size = [400, 120] +pivot = [200, 60] +tags = ["wagon", "armored", "heavy"] +weight_modifier = 1.5 +``` + +--- + +## Dépendances + +### Core (FetchContent CMake) + +| Library | Version | Usage | +|---------|---------|-------| +| **nlohmann_json** | 3.11.3 | JSON processing | +| **spdlog** | 1.12.0 | Logging | +| **Catch2** | 3.5+ | Testing | + +### Rendering (Optionnel) + +| Library | Usage | +|---------|-------| +| **bgfx** | Multi-backend rendering | +| **bx** | Base library (bgfx dep) | +| **bimg** | Image loading (bgfx dep) | +| **SDL2** | Windowing + input | +| **stb_image** | Texture loading | + +### Internal (StillHammer) + +| Library | Usage | +|---------|-------| +| **topictree** | O(k) pub/sub topic matching | +| **logger** | Domain-organized spdlog wrapper | + +### Optionnel Futur + +| Library | Usage | +|---------|-------| +| **yaml-cpp** | YAML parsing (entities) | +| **TOML++** | Config files | +| **ImGui** | Debug UI | +| **Lua** | Scripting (si nécessaire) | +| **stb_truetype** / **FreeType** | Font rendering | + +--- + +## Build System + +### CMake Options + +```cmake +# Core +GROVE_BUILD_IMPLEMENTATIONS # Compile implémentations core +GROVE_BUILD_TESTS # Compile test suite + +# Modules +GROVE_BUILD_MODULES # Compile hot-reloadable modules +GROVE_BUILD_BGFX_RENDERER # Compile rendering module + +# Debug +GROVE_ENABLE_TSAN # ThreadSanitizer +GROVE_ENABLE_HELGRIND # Helgrind deadlock detection +``` + +### Build Commands + +```bash +# Configuration +cmake -B build -DGROVE_BUILD_IMPLEMENTATIONS=ON -DGROVE_BUILD_TESTS=ON + +# Build +cmake --build build + +# Tests +cd build && ctest + +# Module seul (build autonome) +cd modules/BgfxRenderer && cmake . && make +``` + +### Platforms Supportées + +| Platform | Status | Toolchain | +|----------|--------|-----------| +| **Windows** | ✅ Validé | MSVC, MinGW | +| **Linux** | ✅ Validé | GCC, Clang | +| **WSL2** | ✅ Validé | GCC | +| **macOS** | ⏳ Non testé | Clang | +| **WebAssembly** | 🔮 Futur | Emscripten | + +--- + +## État Développement + +### Validé (Production-Ready) + +- ✅ **Hot-reload 0.4ms** avec state preservation +- ✅ **DebugEngine** avec logging complet +- ✅ **SequentialModuleSystem** (single-thread) +- ✅ **IntraIO** pub/sub avec TopicTree +- ✅ **JsonDataNode/JsonDataTree** configuration +- ✅ **Dynamic module loading** (dlopen/LoadLibrary) +- ✅ **Test suite** (Catch2) + +### En Développement + +- 🔄 **BgfxRenderer module** + - ✅ Skeleton + RHI layer + - ✅ Shaders pre-compiled + - 🔄 SpritePass implementation + - ⏳ TextPass, TilemapPass + +### Planned + +- ⏳ **ThreadedModuleSystem** (each module own thread) +- ⏳ **MultithreadedModuleSystem** (thread pool) +- ⏳ **LocalIO** (named pipes/sockets) +- ⏳ **NetworkIO** (TCP/WebSocket) +- ⏳ **Entity Component System** (YAML-driven) +- ⏳ **UI System** (JSON layouts) + +--- + +## Projets Utilisateurs + +| Projet | Type | Status | +|--------|------|--------| +| **AISSIA** | AI Assistant | En développement | +| **Pokrovsk: Iron Line** | Survival/Management | Concept | +| **WarFactory** | Source originale | Extraction faite | + +--- + +## Problèmes Techniques Connus ### 1. API Mismatch IDataTree -**Situation** : +**Situation** : Certaines implémentations utilisent l'ancienne API `nlohmann::json` au lieu de `IDataNode`. + ```cpp -// Ancienne API (implémentations actuelles) +// Ancien (certains fichiers) void initialize(const nlohmann::json& config, IIO* io); -// Nouvelle API (interfaces actuelles) -void setConfiguration(const IDataNode& config, IIO* io); +// Nouveau (interface actuelle) +void initialize(const IDataNode& config, IIO* io); ``` -**Impact** : -- DebugEngine.cpp, IntraIO.cpp, etc. = incompatibles avec IDataTree -- Besoin adaptation ou wrapper +**Status** : Migration en cours, wrapper temporaire disponible. -**Solutions** : -| Option | Effort | Risk | Délai | -|--------|--------|------|-------| -| **A) Ignorer IDataTree** | Faible | Moyen | Immédiat | -| **B) Adapter impls** | Moyen | Faible | 2-3 jours | -| **C) Wrapper json↔IDataNode** | Faible | Moyen | 1 jour | +### 2. Cross-Platform Hot-Reload -**Recommandation** : Option A pour MVP AISSIA, Option B pour Phase 2 +| Platform | API | Status | +|----------|-----|--------| +| Windows | LoadLibrary/FreeLibrary | ✅ Validé | +| Linux | dlopen/dlclose | ✅ Validé | +| macOS | dlopen/dlclose | ⏳ Non testé | +| WASM | N/A | ⚠️ Architecture différente requise | -### 2. Dépendances Externes +### 3. State Preservation Limits -**Actuelles** : -- `nlohmann_json` : Configuration (FetchContent CMake) -- `ImGui` : UI (FetchContent CMake) -- `OpenGL/GLFW` : ImGui backend (système) - -**Problèmes potentiels** : -- ImGui/OpenGL requis même si pas d'UI (fix : optional dependency) -- Version conflicts si projet utilise déjà nlohmann_json - -**Solutions** : -- CMake options : `GROVEENGINE_BUILD_UI`, `GROVEENGINE_USE_SYSTEM_JSON` -- Header-only mode sans dépendances lourdes - -### 3. Cross-Platform Hot-Reload - -**Windows** : `LoadLibrary` / `FreeLibrary` ✅ Validé -**Linux** : `dlopen` / `dlclose` ⏳ Non testé -**macOS** : `dlopen` / `dlclose` ⏳ Non testé -**WASM** : Pas de hot-reload natif ⚠️ Besoin architecture différente - -**Solutions** : -- Abstraction plateforme : `IPlatformLoader` interface -- WASM : Pre-load tous modules, switch callbacks (pas vrai hot-reload) - -### 4. State Preservation - -**Problème** : Hot-reload = nouveau module, state perdu - -**Solution actuelle** : -```cpp -class IModule { - virtual void serialize(IDataNode& out) = 0; - virtual void deserialize(const IDataNode& in) = 0; -}; - -// Avant reload -old_module->serialize(state); - -// Après reload -new_module->deserialize(state); -``` - -**Limitation** : Pointeurs invalides après reload -**Fix** : ID-based references, pas de raw pointers entre modules +- **Pointeurs** : Invalides après reload → Utiliser ID-based references +- **Handles externes** : (GPU textures, file handles) → Recréer après reload --- -## Relation avec Autres Projets +## Commits Git Importants -### Projets Utilisateurs - -1. **AISSIA** (Projet 3) - - Premier utilisateur de GroveEngine - - Modules : Monitoring, Scheduler, AI, Notifications, UI - - Dépend de Phase 1 GroveEngine - -2. **WarFactory** (futur) - - Source originale de GroveEngine - - Long terme : Remplacer son core par GroveEngine packagé - - Modules : Rendering, Physics, AI, Audio, Network - -3. **Futurs projets** - - Serveur backend modulaire - - Tools/Utilities avec UI - - Prototypes rapides - -### Dépendances - -``` -GroveEngine (Projet 4) - ↓ utilisé par -AISSIA (Projet 3) - ↓ utilise aussi -Social Network Manager (Projet 1) - si implémenté en C++ -MP3→TXT (Projet 2) - standalone Python -``` - ---- - -## Décisions Stratégiques en Attente - -### Open-Source - -**Question** : Rendre GroveEngine public ? - -| Option | Avantages | Inconvénients | -|--------|-----------|---------------| -| **Open-source (MIT/Apache)** | Communauté, portfolio, contributions | Maintenance, support users | -| **Private (Bitbucket)** | Contrôle total, pas de support | Pas de contributions externes | - -**Impact** : Si public → besoin CI/CD, doc complète, issue tracking - -### Versioning - -**Question** : Stratégie releases ? - -- **Semantic versioning** : v0.1.0 (MVP) → v0.2.0 (features) → v1.0.0 (stable) -- **Date-based** : 2025.10, 2025.11, etc. -- **Rolling** : Pas de versions, juste main branch - -**Recommandation** : Semantic versioning pour clarté - -### Priorité vs AISSIA - -**Question** : Développer GroveEngine en parallèle ou bloquer AISSIA ? - -| Approche | Pros | Cons | -|----------|------|------| -| **Séquentiel** : Finir GroveEngine MVP → Démarrer AISSIA | GroveEngine propre dès le début | AISSIA retardé 1-2 semaines | -| **Parallèle** : Utiliser GroveEngine "as-is", améliorer en même temps | AISSIA démarre immédiatement | Potentiel refactoring lourd plus tard | - -**Recommandation** : Parallèle avec GroveEngine Phase 1 quick (2-3 jours max) - ---- - -## Estimation Effort - -### Phase 1 - MVP (Court terme) -**Durée** : 2-5 jours -- Build fix + tests : 1 jour -- Hello World exemple : 1 jour -- Documentation usage : 1 jour -- Buffer bugs : 1-2 jours - -### Phase 2 - Package System (Moyen terme) -**Durée** : 1-2 semaines -- CMake install : 2 jours -- Versioning : 1 jour -- Pkg-config/find_package : 2 jours -- Testing intégration : 3 jours - -### Phase 3 - Framework Complet (Long terme) -**Durée** : 2-6 mois -- Tests automatisés : 2 semaines -- CI/CD : 1 semaine -- Cross-platform validation : 3 semaines -- Modules additionnels : 4-8 semaines -- Documentation complète : 4 semaines - -### Phase 4 - Écosystème (Très long terme) -**Durée** : 6+ mois continu -- Dépend de l'adoption -- Communauté-driven - ---- - -## Risques - -| Risque | Probabilité | Impact | Mitigation | -|--------|-------------|--------|------------| -| **API instable** | Moyenne | Élevé | Versioning strict, deprecation policy | -| **Hot-reload bugs cross-platform** | Moyenne | Moyen | Tests automatisés par plateforme | -| **Complexité trop élevée** | Faible | Élevé | Garder core simple, features = opt-in | -| **Maintenance long terme** | Élevée | Moyen | Documentation exhaustive, tests | -| **Over-engineering** | Élevée | Moyen | Focus MVP d'abord, features après | - ---- - -## Statut Actuel - -### Repo -- ✅ Créé : `Projets/GroveEngine/` -- ✅ Structure complète (headers + impls + docs + CMake) -- ⏳ Build jamais testé -- ⏳ Hot-reload pas revalidé depuis extraction - -### Code -- ✅ 27 headers -- ✅ 10 implémentations (.cpp) -- ⚠️ API mismatch IDataTree -- ⏳ Exemples manquants - -### Documentation -- ✅ Architecture modulaire expliquée -- ✅ Guide hot-reload -- ⏳ Guide "Créer premier projet avec GroveEngine" manquant - -### Tests -- ❌ Aucun test automatisé -- ❌ CI/CD pas configuré -- ✅ Hot-reload 0.4ms validé historiquement (WarFactory fc28009) - ---- - -## Prochaines Étapes Recommandées - -### Immédiat (Avant AISSIA) -1. [ ] Build test GroveEngine standalone -2. [ ] Fix erreurs compilation si présentes -3. [ ] Créer `examples/hello_module/` minimal -4. [ ] Valider hot-reload fonctionne toujours -5. [ ] Doc "Quick Start" pour AISSIA - -### Court terme (Parallèle AISSIA) -1. [ ] Fixer API mismatch IDataTree (option A ou B) -2. [ ] CMake install targets basiques -3. [ ] Versioning v0.1.0-alpha - -### Moyen terme (Post-MVP AISSIA) -1. [ ] Tests automatisés -2. [ ] CI/CD basique -3. [ ] Documentation API complète -4. [ ] Cross-platform Linux validation - -### Long terme (Évolution continue) -1. [ ] Modules additionnels (Network, Database, etc.) -2. [ ] Performance optimizations -3. [ ] Communauté (si open-source) +| Commit | Date | Description | +|--------|------|-------------| +| **fc28009** | 24 Sept 2025 | Hot-reload 0.4ms validé, DebugEngine fonctionnel | +| **fb49fb2** | Sept 2025 | IntraIO implementation | +| **f6c3b34** | 27 Sept 2025 | IDataTree ajouté (breaking change) | +| **27 Oct 2025** | - | Extraction GroveEngine depuis WarFactory | --- ## Ressources -### Repos -- **GroveEngine** : `Projets/GroveEngine/` -- **Source (WarFactory)** : `Projets/warfactoryracine/` -- **Premier utilisateur** : `Projets/aissia/` +### Documentation Interne -### Documentation -- `GroveEngine/docs/architecture-modulaire.md` -- `GroveEngine/docs/claude-code-integration.md` -- `GroveEngine/docs/CLAUDE-HOT-RELOAD-GUIDE.md` -- `GroveEngine/README.md` +- `GroveEngine/docs/architecture/` : Guides architecture +- `GroveEngine/docs/implementation/` : Guides implémentation +- `GroveEngine/README.md` : Quick start -### Commits Git Importants (WarFactory) -- `fc28009` : Hot-reload 0.4ms validé + DebugEngine fonctionnel -- `fb49fb2` : IntraIO implementation -- `f6c3b34` : IDataTree ajouté (breaking change) +### Références Externes + +- **bgfx** : https://github.com/bkaradzic/bgfx +- **bgfx docs** : https://bkaradzic.github.io/bgfx/ +- **SDL2** : https://wiki.libsdl.org/ +- **nlohmann/json** : https://github.com/nlohmann/json + +--- + +## Liens Projets Associés + +- **AISSIA** : `Projects/WIP/AISSIA.md` +- **Pokrovsk** : `Projects/CONCEPT/pokrovsk_iron_line_v2.md` --- *Créé : 27 octobre 2025* -*Statut : Extrait, non testé - Développement long terme* -*Stack : C++17, CMake, nlohmann_json, ImGui* -*Performance : Hot-reload 0.4ms validé (à revalider)* +*Consolidé : 27 novembre 2025* +*Stack : C++17, CMake, bgfx, nlohmann_json, spdlog* +*Performance : Hot-reload 0.4ms validé* diff --git a/Projects/WIP/GroveEngine_RenderModule.md b/Projects/WIP/GroveEngine_RenderModule.md deleted file mode 100644 index 722d692..0000000 --- a/Projects/WIP/GroveEngine_RenderModule.md +++ /dev/null @@ -1,561 +0,0 @@ -# GroveEngine - RenderModule (Framework Module) - -**Type** : Framework Module (base avancée) -**Stack** : bgfx + SDL2 -**Objectif** : Window + UI 2D element rendering -**Dernière mise à jour** : 26 novembre 2025 - ---- - -## Vue d'ensemble - -Module framework pour GroveEngine fournissant les capacités de rendu 2D de base : -- **Window management** via SDL2 -- **Rendering 2D** via bgfx (multi-backend : Vulkan/DX12/Metal/OpenGL) -- **UI element rendering** (primitives 2D) - -**Base avancée** = Intégration complète dans le GroveEngine + capacités rendering fonctionnelles - ---- - -## Architecture Module - -### Integration GroveEngine - -```cpp -class RenderModule : public grove::IModule { -public: - // IModule interface - void initialize(const IDataNode& config, IIO* io) override; - void update(float dt) override; - void shutdown() override; - - // Rendering API - void BeginFrame(); - void EndFrame(); - - // 2D Primitives - void DrawRect(const Rect& rect, Color color); - void DrawSprite(const Sprite& sprite); - void DrawText(const std::string& text, Font font, Vec2 pos); - -private: - SDL_Window* window; - bgfx::ViewId main_view; - Renderer2D renderer; -}; -``` - -### Composants Clés - -**1. Window Management (SDL2)** -```cpp -struct WindowConfig { - int width; - int height; - std::string title; - bool fullscreen; - bool vsync; -}; - -// Création window SDL2 -window = SDL_CreateWindow( - config.title.c_str(), - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - config.width, - config.height, - SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE -); -``` - -**2. bgfx Initialization** -```cpp -bgfx::Init init; -init.type = bgfx::RendererType::Count; // Auto-detect -init.resolution.width = width; -init.resolution.height = height; -init.resolution.reset = BGFX_RESET_VSYNC; - -// Utilise window SDL2 -SDL_SysWMinfo wmi; -SDL_VERSION(&wmi.version); -SDL_GetWindowWMInfo(window, &wmi); - -#if BX_PLATFORM_WINDOWS - init.platformData.nwh = wmi.info.win.window; -#elif BX_PLATFORM_LINUX - init.platformData.ndt = wmi.info.x11.display; - init.platformData.nwh = (void*)(uintptr_t)wmi.info.x11.window; -#endif - -bgfx::init(init); -``` - -**3. Renderer2D (Primitives)** -```cpp -class Renderer2D { -public: - void DrawRect(const Rect& rect, Color color); - void DrawSprite(const Sprite& sprite); - void Flush(); // Submit batched draws - -private: - bgfx::ProgramHandle sprite_shader; - bgfx::ProgramHandle color_shader; - - struct SpriteBatch { - std::vector vertices; - bgfx::TextureHandle texture; - }; - - std::vector batches; -}; -``` - ---- - -## Rendering Pipeline - -### Frame Structure - -```cpp -void RenderModule::update(float dt) { - BeginFrame(); - - // Rendering commands - DrawRect({100, 100, 200, 150}, Color::Red()); - DrawSprite(test_sprite); - DrawText("Hello GroveEngine", main_font, {50, 50}); - - EndFrame(); -} - -void RenderModule::BeginFrame() { - bgfx::touch(main_view); - bgfx::setViewClear(main_view, - BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, - 0x303030ff, 1.0f, 0); -} - -void RenderModule::EndFrame() { - renderer.Flush(); // Submit batched draws - bgfx::frame(); // Advance frame -} -``` - -### Vertex Formats - -**Sprite Vertex (textured quad)** -```cpp -struct SpriteVertex { - float x, y, z; // Position - float u, v; // UV coords - uint32_t color; // Tint (ABGR) -}; - -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(); -``` - -**Color Vertex (solid color quad)** -```cpp -struct ColorVertex { - float x, y, z; - uint32_t color; -}; - -bgfx::VertexLayout color_layout; -color_layout.begin() - .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) - .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) - .end(); -``` - ---- - -## Shaders - -### Sprite Shader (Vertex) - -```glsl -// vs_sprite.sc -$input a_position, a_texcoord0, a_color0 -$output v_texcoord0, v_color0 - -#include - -void main() { - gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0)); - v_texcoord0 = a_texcoord0; - v_color0 = a_color0; -} -``` - -### Sprite Shader (Fragment) - -```glsl -// fs_sprite.sc -$input v_texcoord0, v_color0 - -#include - -SAMPLER2D(s_texture, 0); - -void main() { - vec4 texColor = texture2D(s_texture, v_texcoord0); - gl_FragColor = texColor * v_color0; -} -``` - -**Compilation** : -```bash -shaderc -f vs_sprite.sc -o vs_sprite.bin --type vertex --platform linux -p 120 -shaderc -f fs_sprite.sc -o fs_sprite.bin --type fragment --platform linux -p 120 -``` - ---- - -## Camera 2D - -### Orthographic Projection - -```cpp -class Camera2D { -public: - Vec2 position; - float zoom = 1.0f; - - 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); - } -}; - -// Setup view transform -Mat4 view = camera.GetViewMatrix(); -Mat4 proj = camera.GetProjectionMatrix(screenW, screenH); -bgfx::setViewTransform(main_view, view.data, proj.data); -``` - ---- - -## UI Element Rendering - -### DrawRect Implementation - -```cpp -void Renderer2D::DrawRect(const Rect& rect, Color color) { - ColorVertex vertices[4] = { - {rect.x, rect.y, 0, color.abgr()}, - {rect.x + rect.w, rect.y, 0, color.abgr()}, - {rect.x + rect.w, rect.y + rect.h, 0, color.abgr()}, - {rect.x, rect.y + rect.h, 0, color.abgr()} - }; - - uint16_t indices[6] = {0, 1, 2, 0, 2, 3}; - - bgfx::TransientVertexBuffer tvb; - bgfx::TransientIndexBuffer tib; - - bgfx::allocTransientVertexBuffer(&tvb, 4, color_layout); - bgfx::allocTransientIndexBuffer(&tib, 6); - - memcpy(tvb.data, vertices, sizeof(vertices)); - memcpy(tib.data, indices, sizeof(indices)); - - bgfx::setVertexBuffer(0, &tvb); - bgfx::setIndexBuffer(&tib); - bgfx::setState(BGFX_STATE_DEFAULT); - bgfx::submit(main_view, color_shader); -} -``` - -### DrawSprite Implementation (Batched) - -```cpp -void Renderer2D::DrawSprite(const Sprite& sprite) { - // Find or create batch for this texture - SpriteBatch* batch = GetBatchForTexture(sprite.texture); - - // Add quad to batch - float x0 = sprite.pos.x; - float y0 = sprite.pos.y; - float x1 = x0 + sprite.size.x; - float y1 = y0 + sprite.size.y; - - uint32_t color = sprite.tint.abgr(); - - batch->vertices.push_back({x0, y0, 0, 0, 0, color}); - batch->vertices.push_back({x1, y0, 0, 1, 0, color}); - batch->vertices.push_back({x1, y1, 0, 1, 1, color}); - batch->vertices.push_back({x0, y1, 0, 0, 1, color}); -} - -void Renderer2D::Flush() { - for (auto& batch : batches) { - size_t quad_count = batch.vertices.size() / 4; - - // Generate indices (0,1,2, 0,2,3 per quad) - std::vector indices; - for (size_t i = 0; i < quad_count; ++i) { - uint16_t base = i * 4; - indices.push_back(base + 0); - indices.push_back(base + 1); - indices.push_back(base + 2); - indices.push_back(base + 0); - indices.push_back(base + 2); - indices.push_back(base + 3); - } - - // Submit draw call - bgfx::TransientVertexBuffer tvb; - bgfx::TransientIndexBuffer tib; - - bgfx::allocTransientVertexBuffer(&tvb, batch.vertices.size(), sprite_layout); - bgfx::allocTransientIndexBuffer(&tib, indices.size()); - - memcpy(tvb.data, batch.vertices.data(), batch.vertices.size() * sizeof(SpriteVertex)); - memcpy(tib.data, indices.data(), indices.size() * sizeof(uint16_t)); - - bgfx::setTexture(0, sampler, batch.texture); - bgfx::setVertexBuffer(0, &tvb); - bgfx::setIndexBuffer(&tib); - bgfx::setState(BGFX_STATE_DEFAULT); - bgfx::submit(main_view, sprite_shader); - } - - batches.clear(); -} -``` - ---- - -## Configuration Module - -### Config File (JSON) - -```json -{ - "module": "RenderModule", - "window": { - "width": 1280, - "height": 720, - "title": "GroveEngine - RenderModule Test", - "fullscreen": false, - "vsync": true - }, - "rendering": { - "clear_color": "#303030", - "main_view_id": 0 - } -} -``` - -### Loading Config - -```cpp -void RenderModule::initialize(const IDataNode& config, IIO* io) { - WindowConfig window_config; - window_config.width = config.get("window.width", 1280); - window_config.height = config.get("window.height", 720); - window_config.title = config.get("window.title", "GroveEngine"); - window_config.vsync = config.get("window.vsync", true); - - InitializeWindow(window_config); - InitializeBgfx(window_config); - InitializeRenderer(); -} -``` - ---- - -## Roadmap Développement - -### Phase 1 - Window + Init (Semaine 1) - -**Objectif** : Window SDL2 + bgfx initialized, clear screen - -- [ ] Setup SDL2 window -- [ ] Initialize bgfx avec window handle -- [ ] Clear screen avec couleur -- [ ] Main loop fonctionnel -- [ ] Event handling basique (close window) - -**Livrable** : Window qui affiche fond gris, ferme proprement - ---- - -### Phase 2 - Primitives 2D (Semaine 2) - -**Objectif** : DrawRect fonctionnel - -- [ ] Vertex layouts (ColorVertex, SpriteVertex) -- [ ] Shader compilation (color shader) -- [ ] DrawRect implementation -- [ ] Camera 2D orthographic -- [ ] Afficher 1 rectangle coloré - -**Livrable** : Fenêtre avec rectangle rouge affiché - ---- - -### Phase 3 - Sprite Rendering (Semaine 3) - -**Objectif** : DrawSprite fonctionnel - -- [ ] Texture loading (stb_image) -- [ ] Sprite shader (vertex + fragment) -- [ ] DrawSprite implementation (batched) -- [ ] Afficher 1 sprite texturé - -**Livrable** : Fenêtre avec sprite test affiché - ---- - -### Phase 4 - UI Elements (Semaine 4) - -**Objectif** : Text rendering + UI primitives - -- [ ] Font loading (stb_truetype ou FreeType) -- [ ] DrawText implementation -- [ ] UI element base class -- [ ] UIPanel, UIText primitives - -**Livrable** : Fenêtre avec panneau UI + texte - ---- - -## Dépendances - -### Externes (Libraries) - -- **SDL2** : Window + input -- **bgfx** : Rendering abstraction -- **bx** : Base library (bgfx dependency) -- **bimg** : Image loading (bgfx dependency) -- **stb_image** : Texture loading -- **stb_truetype** ou **FreeType** : Font rendering - -### GroveEngine (Internes) - -- `IModule` interface -- `IDataNode` (config system) -- `IIO` (inter-module communication) - ---- - -## Test Case - Base Avancée - -### Validation Criteria - -**Window + UI 2D element = base avancée validée** si : - -1. ✅ Window SDL2 créée et stable -2. ✅ bgfx initialisé et rendering fonctionnel -3. ✅ DrawRect affiche rectangle coloré -4. ✅ DrawSprite affiche sprite texturé -5. ✅ DrawText affiche texte (police) -6. ✅ UI element (panel) rendu correctement -7. ✅ Module intégré dans GroveEngine (IModule interface) - -### Example Test Code - -```cpp -// main.cpp -int main() { - auto engine = grove::EngineFactory::CreateDebugEngine(); - - auto config = LoadConfig("render_module_config.json"); - engine->LoadModule("RenderModule", config); - - // Game loop - while (!should_quit) { - engine->Update(dt); - } - - return 0; -} - -// Dans RenderModule::update() -void RenderModule::update(float dt) { - BeginFrame(); - - // Test: Rectangle - DrawRect({100, 100, 200, 100}, Color{255, 0, 0, 255}); - - // Test: Sprite - DrawSprite(test_sprite); - - // Test: UI Panel - DrawRect({50, 50, 300, 200}, Color{64, 64, 64, 200}); - DrawText("Base Avancée OK!", main_font, {60, 60}); - - EndFrame(); -} -``` - ---- - -## Questions Ouvertes - -### Architecture - -1. **Text rendering** : stb_truetype (simple) ou FreeType (complet) ? -2. **Asset management** : AssetManager séparé ou intégré dans RenderModule ? -3. **Multi-window** : Support futur ou single window only ? - -### Performance - -4. **Sprite batching** : Sort by texture ou sort by Z-order ? -5. **Transient buffers** : OK pour MVP ou besoin persistent buffers ? - -### Integration - -6. **ImGui** : Garder ImGuiUI.h existant ou remplacer par custom UI ? -7. **Hot-reload** : Shader hot-reload nécessaire ou compilation statique OK ? - ---- - -## Ressources - -### Documentation bgfx - -- Repo : https://github.com/bkaradzic/bgfx -- Examples : https://github.com/bkaradzic/bgfx/tree/master/examples -- API docs : https://bkaradzic.github.io/bgfx/ - -### Tutorials 2D avec bgfx - -- bgfx example-26 (vectordisplay) -- NanoVG-bgfx : https://github.com/memononen/nanovg - -### SDL2 - -- Wiki : https://wiki.libsdl.org/ -- Lazy Foo tutorials : https://lazyfoo.net/tutorials/SDL/ - ---- - -## Liens Projets - -- **GroveEngine core** : `Projects/WIP/GroveEngine.md` -- **GroveEngine architecture** : `Projects/WIP/grove-sup.md` -- **Aissia** (utilisateur) : `Projects/WIP/AISSIA.md` -- **Pokrovsk** (utilisateur futur) : `Projects/CONCEPT/pokrovsk_last_day.md` - ---- - -**Créé** : 26 novembre 2025 -**Status** : Architecture planning -**Type** : Framework module (base avancée) -**Objectif** : Window + UI 2D rendering pour GroveEngine diff --git a/Projects/WIP/grove-sup.md b/Projects/WIP/grove-sup.md deleted file mode 100644 index 9d1b8a3..0000000 --- a/Projects/WIP/grove-sup.md +++ /dev/null @@ -1,746 +0,0 @@ -# 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** -```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** -```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** -```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)** -```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)** -```cpp -class Entity { - EntityID id; - std::vector 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** -```cpp -class AssetManager { - // Textures - std::map textures; - - // Manifests (metadata) - std::map metadata; - - // Fonts - std::map fonts; - - void LoadManifest(const std::string& path); - bgfx::TextureHandle GetTexture(const std::string& id); -}; -``` - -**3. Config System** -```cpp -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)** -```cpp -class Renderer2D { - bgfx::ProgramHandle sprite_shader; - - // Sprite batching pour performance - struct SpriteBatch { - std::vector 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)** -```cpp -class UIManager { - std::map 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) - -```cpp -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 - -```cpp -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) - -```cpp -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 - -4. **Sprite batching strategy ?** - - Batch par texture (standard) - - Batch par layer (z-order) - - **Décision** : Tester performance avec prototype - -5. **Entity pooling ?** - - Object pooling pour éviter alloc/dealloc - - Critical pour drones (100+ entities) - - **Recommandation** : Oui, implement dès Phase 3 - -### Tooling - -6. **Level editor ?** - - ImGui-based editor in-engine - - Externe (web-based ?) - - **Recommandation** : ImGui in-engine = plus rapide - -7. **Asset hot-reload ?** - - Reload YAML/JSON/textures sans restart - - Crucial pour iteration rapide - - **Recommandation** : Oui, implement Phase 2-3 - ---- - -## DÉPENDANCES EXTERNES - -### Obligatoires -- **bgfx** : Rendering (https://github.com/bkaradzic/bgfx) -- **bx** : Base library pour bgfx (https://github.com/bkaradzic/bx) -- **bimg** : Image loading pour bgfx (https://github.com/bkaradzic/bimg) -- **SDL2** : Windowing + input (https://www.libsdl.org/) -- **yaml-cpp** : YAML parsing (https://github.com/jbeder/yaml-cpp) -- **nlohmann/json** : JSON parsing (https://github.com/nlohmann/json) -- **stb_image** : Image loading (https://github.com/nothings/stb) - -### Optionnelles -- **TOML++** : TOML parsing (https://github.com/marzer/tomlplusplus) -- **ImGui** : Debug UI (https://github.com/ocornut/imgui) -- **Lua** : Scripting (https://www.lua.org/) -- **stb_truetype** : Font rendering (https://github.com/nothings/stb) -- **FreeType** : Alternative font rendering (https://freetype.org/) - ---- - -## 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 -- Repo officiel : https://github.com/bkaradzic/bgfx -- Documentation : https://bkaradzic.github.io/bgfx/ -- Exemples : https://github.com/bkaradzic/bgfx/tree/master/examples - -### Architecture ECS -- "Overwatch Gameplay Architecture" (GDC Talk) -- "Data-Oriented Design" (Richard Fabian) - -### 2D Rendering bgfx -- bgfx example-26 (vectordisplay) -- NanoVG-bgfx (https://github.com/memononen/nanovg) - ---- - -## 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`