Add GroveEngine supplementary design document
- Complete technical stack (bgfx, SDL2, YAML/JSON/TOML) - AI-friendly architecture (data-driven entities, UI, missions) - Rendering 2D implementation details (sprite batching, camera) - 16-week development plan (5 phases) - ECS architecture + component examples - LLM workflow capabilities (create/modify without C++ code) - Questions ouvertes + risk mitigation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0c152b7364
commit
fc45332c1c
746
Projects/WIP/grove-sup.md
Normal file
746
Projects/WIP/grove-sup.md
Normal file
@ -0,0 +1,746 @@
|
||||
# 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`
|
||||
130
food/barres_proteinees_haricot_rouge.md
Normal file
130
food/barres_proteinees_haricot_rouge.md
Normal file
@ -0,0 +1,130 @@
|
||||
# Barres Protéinées Haricot Rouge - Batch Petit-déjeuner
|
||||
|
||||
**Type** : Batch hebdomadaire
|
||||
**Prep** : Dimanche (nécessite purée haricot rouge préparée)
|
||||
**Conservation** : 1 semaine frigo, 1 mois congélateur
|
||||
**Portions** : 12-16 barres
|
||||
|
||||
## Caractéristiques
|
||||
|
||||
- **High protein** : Œufs + haricot rouge
|
||||
- **Glucides complexes** : Avoine + haricot rouge
|
||||
- **Texture** : Dense, type granola bar / energy bar
|
||||
- **Portable** : Mange avec les mains, pratique
|
||||
- **Réchauffage** : Optionnel (bon froid ou réchauffé)
|
||||
|
||||
## Ingrédients
|
||||
|
||||
- 200g purée haricot rouge maison (voir recette séparée)
|
||||
- 150g flocons avoine
|
||||
- 4 œufs
|
||||
- 50g miel (ou sirop d'érable, ou sucre)
|
||||
- 50g graines mélangées (tournesol, courge, chia, lin)
|
||||
- Optionnel : 1 cc cannelle, baies de goji, fruits secs hachés
|
||||
|
||||
## Process Dimanche
|
||||
|
||||
### 1. Préparation
|
||||
- Préparer purée haricot rouge si pas déjà fait (voir recette `puree_haricot_rouge.md`)
|
||||
- Préchauffer four à 180°C
|
||||
|
||||
### 2. Mélange
|
||||
1. Dans grand bol : purée haricot rouge + 4 œufs + miel
|
||||
2. Mélanger bien jusqu'à homogène
|
||||
3. Ajouter flocons avoine + graines (+ optionnels)
|
||||
4. Mélanger jusqu'à pâte épaisse et collante
|
||||
5. **Consistance** : Doit être compacte, pas liquide
|
||||
- Si trop liquide : + 20-30g avoine
|
||||
- Si trop sec : + 1 œuf ou un peu de lait
|
||||
|
||||
### 3. Cuisson
|
||||
1. Huiler/beurrer plat rectangulaire (type 20x30cm)
|
||||
2. Verser mélange dans plat
|
||||
3. **Presser fermement** avec spatule ou dos de cuillère (bien compacter)
|
||||
4. Étaler uniformément (~2cm épaisseur)
|
||||
5. Optionnel : Parsemer graines de sésame dessus
|
||||
6. **Four 180°C, 20-25 min**
|
||||
7. Test : Surface ferme au toucher, bords légèrement dorés
|
||||
8. **Ne pas trop cuire** (sinon trop sec)
|
||||
|
||||
### 4. Refroidissement IMPORTANT
|
||||
1. Sortir du four
|
||||
2. **Laisser refroidir COMPLÈTEMENT dans le plat** (2-3h ou frigo 1h)
|
||||
3. ⚠️ **Ne PAS découper tant que chaud** (va s'effriter)
|
||||
|
||||
### 5. Découpe & Stockage
|
||||
1. Découper en 12-16 barres/carrés
|
||||
2. Stocker frigo boîte hermétique
|
||||
3. Papier cuisson entre couches pour pas coller
|
||||
4. Ou congeler individuellement (papier alu/film)
|
||||
|
||||
## Process Matin
|
||||
|
||||
**Option A : Froid**
|
||||
- Sortir 1-2 barres par personne
|
||||
- Manger directement
|
||||
|
||||
**Option B : Réchauffé**
|
||||
- Four 150°C, 5 min
|
||||
- Texture plus moelleuse
|
||||
|
||||
**Pratique :** Peut se manger en déplacement, emporter bureau, etc.
|
||||
|
||||
## Notes & Ajustements
|
||||
|
||||
### Si barres s'effritent
|
||||
- Prochaine fois : Presser plus fort avant cuisson
|
||||
- Ou ajouter 1 œuf supplémentaire (meilleur liant)
|
||||
|
||||
### Si trop sec
|
||||
- Prochaine fois : Réduire temps cuisson 2-3 min
|
||||
- Ou ajouter 20ml lait dans mélange
|
||||
|
||||
### Si pas assez sucré
|
||||
- Augmenter miel à 70-80g
|
||||
- Ou ajouter fruits secs sucrés (dattes hachées, raisins)
|
||||
|
||||
### Si texture trop dense
|
||||
- Ajouter 1 cc levure chimique dans mélange
|
||||
- Texture sera plus "cake bar" que "granola bar"
|
||||
|
||||
## Variantes
|
||||
|
||||
**Version chocolat :**
|
||||
- Ajouter 30g cacao non sucré dans mélange
|
||||
- + 20g sucre supplémentaire
|
||||
|
||||
**Version fruits secs :**
|
||||
- Ajouter 50g dattes hachées + 30g noix hachées
|
||||
- Réduire miel à 30g (dattes sucrent)
|
||||
|
||||
**Version goji-cannelle :**
|
||||
- 2 cc cannelle + 40g goji dans mélange
|
||||
|
||||
**Version protéines++ :**
|
||||
- Ajouter 30-50g poudre protéine (whey/soja)
|
||||
- Peut nécessiter + liquide (lait)
|
||||
|
||||
**Version salée (expérimental) :**
|
||||
- Retirer miel
|
||||
- Ajouter sel, herbes, fromage râpé
|
||||
- Style savory protein bar
|
||||
|
||||
## Calcul Portions
|
||||
|
||||
- **12-16 barres total**
|
||||
- 1-2 par personne/jour = 2-4 par jour
|
||||
- = Suffit pour 3-5 jours
|
||||
- **Batch double** : Utiliser 2 plats, doubler recette → semaine complète
|
||||
|
||||
## Comparaison avec galettes
|
||||
|
||||
| | Barres | Galettes |
|
||||
|---|---|---|
|
||||
| Texture | Dense, compact | Moelleux, aéré |
|
||||
| Portable | Très (mains) | Moins |
|
||||
| Goût | Haricot rouge + avoine | Œufs dominant |
|
||||
| Protéines | Moyen-élevé | Très élevé |
|
||||
| Sucre naturel | Oui (haricot) | Peu (sauf ajout) |
|
||||
|
||||
**Bon pour variété** : Alterner avec galettes protéinées
|
||||
92
food/galettes_proteinees.md
Normal file
92
food/galettes_proteinees.md
Normal file
@ -0,0 +1,92 @@
|
||||
# Galettes Protéinées - Batch Petit-déjeuner
|
||||
|
||||
**Type** : Batch hebdomadaire
|
||||
**Prep** : Dimanche
|
||||
**Conservation** : 5-7 jours frigo, 1 mois congélateur
|
||||
**Portions** : 12-16 morceaux (2-3 jours pour 2 personnes)
|
||||
|
||||
## Caractéristiques
|
||||
|
||||
- **High protein** (12 œufs pour 240g farine)
|
||||
- **Texture** : Type pancake épais / frittata moelleuse
|
||||
- **Réchauffage four** : Retrouve texture agréable
|
||||
- **Remplace** : Œufs + maïs du matin
|
||||
|
||||
## Ingrédients
|
||||
|
||||
- 12 œufs
|
||||
- 240g farine complète
|
||||
- 150ml lait (ajuster selon consistance)
|
||||
- 2 cc levure chimique
|
||||
- 2 cc sucre (ou miel)
|
||||
- 1 pincée sel
|
||||
- **Options** : baies de goji, cannelle, graines
|
||||
|
||||
## Process Dimanche (Batch Prep)
|
||||
|
||||
1. **Préchauffer** four à 180°C
|
||||
|
||||
2. **Mélange** :
|
||||
- Battre 12 œufs dans grand bol
|
||||
- Ajouter lait + sucre + sel, mélanger
|
||||
- Ajouter farine + levure chimique
|
||||
- Mélanger jusqu'à homogène (pâte assez liquide)
|
||||
|
||||
3. **Cuisson** :
|
||||
- Huiler/beurrer grande plaque four (ou papier cuisson)
|
||||
- Verser toute la pâte
|
||||
- Étaler uniformément (~2cm épaisseur)
|
||||
- **Four 180°C, 25-30 min**
|
||||
- Test couteau : doit ressortir propre
|
||||
- Si trop doré dessus mais pas cuit dedans → baisser à 160°C
|
||||
|
||||
4. **Stockage** :
|
||||
- Laisser refroidir complètement
|
||||
- Découper en carrés/rectangles (12-16 portions)
|
||||
- Stocker frigo dans boîte hermétique
|
||||
- Optionnel : papier cuisson entre couches si stack
|
||||
|
||||
## Process Matin (Lundi-Vendredi)
|
||||
|
||||
1. Sortir 2-3 morceaux par personne (4-6 total)
|
||||
2. **Four 150-160°C, 5-8 min** (réchauffer)
|
||||
3. Manger
|
||||
|
||||
**Temps matin** : ~8 min (walkaway pendant que four chauffe)
|
||||
|
||||
## Notes & Ajustements
|
||||
|
||||
### Si texture trop sèche
|
||||
- Prochaine batch : + 50ml lait dans la pâte
|
||||
|
||||
### Si pas assez moelleux
|
||||
- + 1 cc levure chimique
|
||||
- Ou battre blancs en neige à part, incorporer délicatement
|
||||
|
||||
### Si trop fragile
|
||||
- + 20-30g farine
|
||||
|
||||
### Pour tenir toute la semaine
|
||||
- Doubler les quantités
|
||||
- Utiliser 2 plaques ou cuire en 2 fois
|
||||
|
||||
## Variantes
|
||||
|
||||
**Sucré :**
|
||||
- + Baies de goji
|
||||
- + Cannelle
|
||||
- + Miel au lieu du sucre
|
||||
- + Fruits secs
|
||||
|
||||
**Salé :**
|
||||
- Retirer sucre
|
||||
- + Fromage râpé
|
||||
- + Herbes (basilic, ciboulette)
|
||||
- + Légumes finement coupés
|
||||
|
||||
## Calcul Portions
|
||||
|
||||
- **12-16 portions total**
|
||||
- 2-3 par personne/jour = 4-6 par jour
|
||||
- **Batch simple** = 2-3 jours
|
||||
- **Batch double** = 5-6 jours (toute semaine)
|
||||
149
food/puree_haricot_rouge.md
Normal file
149
food/puree_haricot_rouge.md
Normal file
@ -0,0 +1,149 @@
|
||||
# Purée de Haricot Rouge Maison (红豆沙)
|
||||
|
||||
**Type** : Base pour autres recettes
|
||||
**Prep** : 2-3h (surtout passif)
|
||||
**Conservation** : 1 semaine frigo, 2-3 mois congélateur
|
||||
**Rendement** : ~400-500g de purée
|
||||
|
||||
## Usage
|
||||
|
||||
**Utilisations :**
|
||||
- Garniture tarte haricot rouge
|
||||
- Base barres protéinées
|
||||
- Tartinade sur galettes/pain
|
||||
- Garniture baozi/mantou maison
|
||||
- Desserts traditionnels chinois
|
||||
|
||||
## Ingrédients
|
||||
|
||||
- 200g haricots rouges secs (红豆 ou 赤豆)
|
||||
- Eau (pour trempage et cuisson)
|
||||
- 50-100g sucre (ajuster selon goût)
|
||||
- 50g = peu sucré
|
||||
- 100g = traditionnel sucré
|
||||
- Optionnel : 1-2 cc huile neutre (texture plus lisse)
|
||||
|
||||
## Équipement
|
||||
|
||||
**Obligatoire :**
|
||||
- Casserole ou cocotte-minute
|
||||
- Mixeur plongeur ou blender
|
||||
|
||||
**Optionnel :**
|
||||
- Passoire fine (texture ultra-lisse)
|
||||
|
||||
## Process
|
||||
|
||||
### 1. Trempage (4-8h ou overnight)
|
||||
1. Rincer haricots rouges
|
||||
2. Mettre dans bol, couvrir largement d'eau froide
|
||||
3. Laisser tremper 4-8h (ou toute la nuit)
|
||||
4. **Pourquoi** : Réduit temps cuisson, meilleure digestion
|
||||
|
||||
### 2. Cuisson
|
||||
|
||||
**Option A : Casserole classique**
|
||||
1. Égoutter haricots trempés
|
||||
2. Mettre casserole, couvrir eau fraîche (3-4cm au-dessus)
|
||||
3. Porter à ébullition
|
||||
4. Réduire feu moyen-doux, couvrir
|
||||
5. Cuire **1h30-2h** jusqu'à très mous (doivent s'écraser facilement)
|
||||
6. Vérifier eau régulièrement, ajouter si besoin
|
||||
|
||||
**Option B : Cocotte-minute (plus rapide)**
|
||||
1. Égoutter haricots
|
||||
2. Cocotte-minute avec eau (même niveau)
|
||||
3. Fermer, cuire **25-30 min** après sifflement
|
||||
4. Laisser dépressuriser naturellement
|
||||
|
||||
**Test cuisson** : Écraser haricot entre doigts, doit être complètement mou
|
||||
|
||||
### 3. Égouttage
|
||||
1. Égoutter haricots cuits
|
||||
2. **Garder 100-150ml eau de cuisson** (pour ajuster consistance après)
|
||||
3. Laisser haricots refroidir légèrement (5-10 min)
|
||||
|
||||
### 4. Mixage
|
||||
1. Mettre haricots dans blender/récipient mixeur
|
||||
2. Ajouter sucre
|
||||
3. Ajouter 50ml eau de cuisson gardée
|
||||
4. Mixer jusqu'à purée lisse
|
||||
5. **Ajuster consistance** :
|
||||
- Trop épais : + eau de cuisson petit à petit
|
||||
- Trop liquide : Passer étape 5 (réduction)
|
||||
|
||||
**Texture cible** : Purée épaisse type pâte à tartiner, pas liquide
|
||||
|
||||
### 5. Réduction (optionnel mais recommandé)
|
||||
1. Mettre purée dans casserole
|
||||
2. Feu moyen-doux
|
||||
3. Remuer constamment 10-15 min
|
||||
4. **Objectifs** :
|
||||
- Évaporer excès d'eau
|
||||
- Épaissir
|
||||
- Caraméliser légèrement le sucre
|
||||
- Développer saveur
|
||||
5. Ajouter huile si utilisée (rend plus lisse, brillant)
|
||||
6. Arrêter quand consistance épaisse, se détache de la casserole
|
||||
|
||||
### 6. Refroidissement & Stockage
|
||||
1. Verser dans récipient propre
|
||||
2. Laisser refroidir complètement
|
||||
3. Couvrir, stocker frigo
|
||||
4. **Conservation** :
|
||||
- Frigo hermétique : 1 semaine
|
||||
- Congélateur portions : 2-3 mois
|
||||
|
||||
## Notes & Ajustements
|
||||
|
||||
### Texture ultra-lisse (optionnel)
|
||||
- Après mixage, passer au tamis fin/passoire
|
||||
- Presser avec spatule
|
||||
- Jeter peaux/morceaux restants
|
||||
- **Effort++** mais texture professionnelle
|
||||
|
||||
### Sucre
|
||||
- **Réduire** : 30-50g pour version moins sucrée (utilisation salée/santé)
|
||||
- **Traditionnel** : 100g pour goût classique chinois
|
||||
- **Tester** : Commencer 50g, goûter, ajuster
|
||||
|
||||
### Sans sucre
|
||||
- Possible de faire SANS sucre du tout
|
||||
- Utile si utilisation dans recettes protéinées (contrôler sucre total)
|
||||
- Goût haricot plus prononcé
|
||||
|
||||
### Variantes aromatiques
|
||||
- + Zeste d'orange pendant réduction
|
||||
- + Cannelle (1 cc)
|
||||
- + Pâte de lotus mélangée (mix 50/50)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Haricots pas assez cuits** (durs après mixage)
|
||||
- Recuire avec eau 30 min supplémentaires
|
||||
- Puis re-mixer
|
||||
|
||||
**Purée trop liquide**
|
||||
- Recuire feu doux en remuant 10-15 min
|
||||
- Évapore l'eau
|
||||
|
||||
**Purée trop épaisse**
|
||||
- Ajouter eau de cuisson ou lait, mixer
|
||||
|
||||
**Goût fade**
|
||||
- Ajouter sucre
|
||||
- Ou pincée sel (rehausse saveur sucrée)
|
||||
|
||||
## Batch & Organisation
|
||||
|
||||
**Faire grande quantité :**
|
||||
- Doubler/tripler recette facilement
|
||||
- Diviser en portions après refroidissement
|
||||
- Congeler portions individuelles (sachets ou moules à muffins)
|
||||
- Décongeler veille au frigo avant usage
|
||||
|
||||
**Planning dimanche :**
|
||||
1. Samedi soir : Tremper haricots
|
||||
2. Dimanche matin : Cuire haricots (passif)
|
||||
3. Dimanche midi : Mixer + réduire
|
||||
4. Dimanche après-midi : Utiliser pour recettes batch (tartes, barres)
|
||||
111
food/tarte_haricot_rouge.md
Normal file
111
food/tarte_haricot_rouge.md
Normal file
@ -0,0 +1,111 @@
|
||||
# Tarte Haricot Rouge Protéinée - Batch Petit-déjeuner
|
||||
|
||||
**Type** : Batch hebdomadaire
|
||||
**Prep** : Dimanche (nécessite purée haricot rouge préparée)
|
||||
**Conservation** : 5-7 jours frigo
|
||||
**Portions** : 12-16 carrés
|
||||
|
||||
## Caractéristiques
|
||||
|
||||
- **Protéines** : Œufs dans la pâte
|
||||
- **Glucides** : Haricot rouge + farine
|
||||
- **Texture** : Pâte moelleuse + garniture crémeuse haricot rouge
|
||||
- **Goût** : Sucré naturel (haricot rouge), asiatique traditionnel
|
||||
- **Réchauffage** : Four 150-160°C, 5-8 min
|
||||
|
||||
## Ingrédients
|
||||
|
||||
### Pâte de base
|
||||
- 6 œufs
|
||||
- 200g farine complète
|
||||
- 100ml lait
|
||||
- 2 cc levure chimique
|
||||
- 1 pincée sel
|
||||
- Optionnel : 1 cc sucre
|
||||
|
||||
### Garniture
|
||||
- 200-300g purée haricot rouge maison (voir recette séparée)
|
||||
|
||||
## Process Dimanche
|
||||
|
||||
### 1. Préparation (si purée pas déjà faite)
|
||||
- Préparer purée haricot rouge en premier (voir recette `puree_haricot_rouge.md`)
|
||||
- Laisser refroidir pendant que vous préparez la pâte
|
||||
|
||||
### 2. Pâte de base
|
||||
1. Préchauffer four à 180°C
|
||||
2. Battre 6 œufs dans grand bol
|
||||
3. Ajouter lait + sel (+ sucre si utilisé)
|
||||
4. Ajouter farine + levure chimique
|
||||
5. Mélanger jusqu'à pâte lisse et épaisse
|
||||
|
||||
### 3. Assemblage - Option A (Tarte ouverte)
|
||||
1. Huiler/beurrer grande plaque four (ou papier cuisson)
|
||||
2. Verser TOUTE la pâte sur la plaque
|
||||
3. Étaler uniformément (~1.5-2cm épaisseur)
|
||||
4. **Pré-cuire 10-12 min à 180°C** (pâte commence à prendre mais pas dorée)
|
||||
5. Sortir du four
|
||||
6. Tartiner purée haricot rouge uniformément dessus
|
||||
7. Remettre au four **15-20 min** (jusqu'à pâte cuite et bords dorés)
|
||||
|
||||
### 4. Assemblage - Option B (Tourte fermée)
|
||||
1. Huiler/beurrer grande plaque
|
||||
2. Verser MOITIÉ de la pâte, étaler
|
||||
3. Tartiner purée haricot rouge
|
||||
4. Verser reste de pâte par-dessus délicatement (cuillères espacées, étaler doucement)
|
||||
5. **Four 180°C, 30-35 min** (jusqu'à dorée)
|
||||
|
||||
### 5. Stockage
|
||||
1. Laisser refroidir complètement
|
||||
2. Découper carrés/rectangles (12-16 portions)
|
||||
3. Stocker frigo boîte hermétique
|
||||
4. Papier cuisson entre couches si besoin
|
||||
|
||||
## Process Matin
|
||||
|
||||
1. Sortir 2-3 carrés par personne
|
||||
2. **Four 150-160°C, 5-8 min** (réchauffer)
|
||||
3. Manger
|
||||
|
||||
**Peut aussi se manger froid** directement du frigo
|
||||
|
||||
## Notes & Ajustements
|
||||
|
||||
### Quelle option choisir ?
|
||||
- **Tarte ouverte (A)** : Plus facile, visuel joli, haricot visible
|
||||
- **Tourte fermée (B)** : Plus "enfermé", tient mieux, moins salissant
|
||||
|
||||
### Si pâte trop liquide
|
||||
- Ajouter 20-30g farine
|
||||
|
||||
### Si purée haricot rouge trop liquide
|
||||
- Recuire à feu doux 5-10 min pour épaissir avant d'utiliser
|
||||
|
||||
### Si trop sucré
|
||||
- Réduire sucre dans purée haricot rouge la prochaine fois
|
||||
|
||||
### Si pas assez sucré
|
||||
- Ajouter 1-2 cc miel/sucre dans la pâte
|
||||
|
||||
## Variantes
|
||||
|
||||
**Ajouts pâte :**
|
||||
- Cannelle (1 cc)
|
||||
- Zeste d'orange
|
||||
- Vanille
|
||||
|
||||
**Ajouts garniture :**
|
||||
- Mélanger goji dans purée haricot rouge
|
||||
- Parsemer graines de sésame dessus avant cuisson finale
|
||||
|
||||
**Version marbrée :**
|
||||
- Mélanger grossièrement purée haricot dans pâte (pas uniformément)
|
||||
- Cuire en une seule fois
|
||||
- = Effet marbré
|
||||
|
||||
## Calcul Portions
|
||||
|
||||
- **12-16 portions total**
|
||||
- 2-3 par personne/jour = 4-6 par jour
|
||||
- = Suffit pour 2-3 jours
|
||||
- **Combiner avec autres batchs** pour variété semaine
|
||||
Loading…
Reference in New Issue
Block a user