Consolidate GroveEngine documentation
- Merge GroveEngine.md, GroveEngine_RenderModule.md, grove-sup.md into single comprehensive doc - Add detailed architecture (13 interfaces, hot-reload, IIO pub/sub, data system) - Document known technical issues (API mismatch, cross-platform, state preservation) - Remove redundant files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2dc14573f2
commit
a141f01744
File diff suppressed because it is too large
Load Diff
@ -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<SpriteVertex> vertices;
|
|
||||||
bgfx::TextureHandle texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<SpriteBatch> 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 <bgfx_shader.sh>
|
|
||||||
|
|
||||||
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 <bgfx_shader.sh>
|
|
||||||
|
|
||||||
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<uint16_t> 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
|
|
||||||
@ -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<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**
|
|
||||||
```cpp
|
|
||||||
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**
|
|
||||||
```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<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)**
|
|
||||||
```cpp
|
|
||||||
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)
|
|
||||||
|
|
||||||
```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`
|
|
||||||
Loading…
Reference in New Issue
Block a user