Add data-driven architecture implementation plan

- Created DATA_DRIVEN_IMPLEMENTATION_PLAN.md with 8-phase roadmap
- Architecture: ProcessEngine for data-driven systems (MC + WF compatible)
- GameModule stays hardcoded, systems become JSON-configurable
- Estimated timeline: 23 days (4-5 weeks)
- Phases: ProcessEngine, Crafting, Combat, Events, Storage, Integration

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
StillHammer 2025-12-03 07:14:10 +08:00
parent 4fd540dde6
commit 9b19242a99

View File

@ -0,0 +1,605 @@
# Mobile Command - Data-Driven Implementation Plan
**Date**: 2 décembre 2025
**Architecture**: Data-driven process engine (WarFactory-inspired)
**Status**: Planning phase - Replacing hardcoded module logic
---
## 🎯 Vision
Créer un système data-driven où:
- **GameModule** reste hardcodé (state machine C++, orchestration)
- **Systèmes de jeu** sont data-driven (crafting, combat, events définis en JSON)
- **ProcessEngine** interprète et exécute les process JSON
- **WarFactory compatibility** - Architecture réutilisable entre projets
---
## 📐 Architecture Cible
```
GameModule.so (C++ hardcodé)
├─ State machine (MainMenu → TrainBuilder → Expedition → Combat)
├─ Appelle les systèmes via IIO pub/sub
└─ Coordonne le flow du jeu
ProcessEngine (lib statique partagée)
├─ Registry: "craft_recipe" → CraftProcessor
├─ Registry: "resolve_combat" → CombatProcessor
├─ Registry: "trigger_event" → EventProcessor
└─ execute(process_type, params_json, state)
CraftingSystemModule.so (data-driven)
├─ CraftingState (local)
├─ Utilise ProcessEngine
├─ Config: recipes.json
└─ IIO: "craft:start" → publish "craft:complete"
CombatSystemModule.so (data-driven)
├─ CombatState (local)
├─ Utilise ProcessEngine
├─ Config: combat_scenarios.json
└─ IIO: "combat:start" → publish "combat:ended"
EventSystemModule.so (data-driven)
├─ EventState (local)
├─ Utilise ProcessEngine
├─ Config: events.json
└─ IIO: "event:check" → publish "event:triggered"
```
---
## 🗂️ Structure du Projet
```
project-mobile-command/
├── src/
│ ├── main.cpp # GroveEngine mainloop
│ ├── process_engine/ # Core data-driven engine
│ │ ├── ProcessEngine.h
│ │ ├── ProcessEngine.cpp
│ │ ├── IProcessor.h # Interface pour processors
│ │ └── processors/ # Process implementations
│ │ ├── CraftProcessor.cpp
│ │ ├── CombatProcessor.cpp
│ │ └── EventProcessor.cpp
│ │
│ └── modules/
│ ├── GameModule.cpp # Orchestrator (hardcodé)
│ │
│ ├── systems/ # Data-driven systems
│ │ ├── CraftingSystemModule.cpp
│ │ ├── CombatSystemModule.cpp
│ │ ├── EventSystemModule.cpp
│ │ └── StorageSystemModule.cpp
│ │
│ └── mc_specific/ # MC-only modules
│ ├── TrainBuilderModule.cpp
│ └── ExpeditionModule.cpp
├── config/
│ ├── game.json # GameModule config
│ ├── systems/ # System definitions
│ │ ├── crafting_recipes.json
│ │ ├── combat_scenarios.json
│ │ ├── events.json
│ │ └── storage.json
│ │
│ └── mc_specific/ # MC-specific configs
│ ├── train.json
│ └── expeditions.json
└── tests/
├── ProcessEngineTest.cpp
├── CraftingSystemTest.cpp
└── IntegrationTest.cpp
```
---
## 📋 Phase 1: ProcessEngine Foundation
**Objectif**: Créer le moteur générique qui interprète les process JSON
### Tasks
#### 1.1 ProcessEngine Core
```cpp
class ProcessEngine {
public:
using ProcessFunc = std::function<void(
const IDataNode& params, // JSON config
IDataNode& state, // Module state
IIO* io // Pub/sub
)>;
void registerProcess(const std::string& type, ProcessFunc func);
void execute(const std::string& processType,
const IDataNode& params,
IDataNode& state,
IIO* io);
};
```
**Fichiers**:
- [ ] `src/process_engine/ProcessEngine.h`
- [ ] `src/process_engine/ProcessEngine.cpp`
- [ ] `src/process_engine/IProcessor.h` (interface commune)
**Tests**:
- [ ] `tests/ProcessEngineTest.cpp`
- [ ] Test registry (register/execute)
- [ ] Test unknown process type handling
#### 1.2 CMake Integration
- [ ] Créer lib statique `ProcessEngine`
- [ ] Link dans chaque module data-driven
- [ ] Headers publics exposés
**Durée estimée**: 1-2 jours
---
## 📋 Phase 2: Crafting System (Data-Driven)
**Objectif**: Premier système data-driven complet
### 2.1 CraftProcessor
**Logic**:
```cpp
void CraftProcessor::execute(const IDataNode& params, IDataNode& state, IIO* io) {
// 1. Parse params (recipe_id, inputs, outputs, duration)
// 2. Check inventory in state
// 3. Consume inputs
// 4. Add craft job to queue
// 5. Publish "craft:started"
}
```
**Fichiers**:
- [ ] `src/process_engine/processors/CraftProcessor.cpp`
- [ ] `src/process_engine/processors/CraftProcessor.h`
### 2.2 CraftingSystemModule
**State**:
```json
{
"inventory": {
"scrap_metal": 100,
"ammunition": 500
},
"craft_queue": [
{"recipe": "repair_kit", "time_remaining": 25.3}
]
}
```
**Config** (`config/systems/crafting_recipes.json`):
```json
{
"recipes": {
"repair_kit": {
"process": "craft_recipe",
"inputs": {"scrap_metal": 5, "electronics": 1},
"outputs": {"repair_kit": 1},
"duration": 30.0
},
"drone_recon": {
"process": "craft_recipe",
"inputs": {"drone_parts": 3, "electronics": 2},
"outputs": {"drone_recon": 1},
"duration": 120.0
}
}
}
```
**Topics**:
- Subscribe: `"craft:start"` → {recipe_id}
- Publish: `"craft:started"` → {recipe_id, duration}
- Publish: `"craft:complete"` → {recipe_id, outputs}
- Publish: `"inventory:changed"` → {resource_id, delta, total}
**Fichiers**:
- [ ] `src/modules/systems/CraftingSystemModule.cpp`
- [ ] `src/modules/systems/CraftingSystemModule.h`
- [ ] `config/systems/crafting_recipes.json`
**Tests**:
- [ ] `tests/CraftingSystemTest.cpp`
- [ ] Test craft avec resources suffisantes
- [ ] Test craft avec resources insuffisantes
- [ ] Test craft queue progression
- [ ] Test hot-reload state preservation
**Durée estimée**: 2-3 jours
---
## 📋 Phase 3: Combat System (Data-Driven)
**Objectif**: Système de combat avec formules configurables
### 3.1 CombatProcessor
**Logic**:
```cpp
void CombatProcessor::execute(const IDataNode& params, IDataNode& state, IIO* io) {
// 1. Parse scenario (enemy stats, formulas)
// 2. Setup combatants
// 3. Resolve rounds (hit calculation, damage, casualties)
// 4. Determine outcome (victory/defeat)
// 5. Publish "combat:ended" avec loot/casualties
}
```
**Config** (`config/systems/combat_scenarios.json`):
```json
{
"scenarios": {
"scavenger_ambush": {
"process": "resolve_combat",
"enemy": {
"firepower": 30,
"armor": 10,
"morale": 60,
"count": 8
},
"formulas": {
"hit_chance": "accuracy * (1.0 - cover)",
"damage": "max(0, firepower - armor * 0.5)",
"morale_loss": "casualties / total * 100"
},
"loot": {
"scrap_metal": {"min": 10, "max": 30},
"ammunition": {"min": 20, "max": 100}
}
}
}
}
```
**Formula Parser**:
- [ ] Simple expression evaluator (pour prototype)
- [ ] Variables: `accuracy`, `cover`, `firepower`, `armor`, etc.
- [ ] Opérations: `+`, `-`, `*`, `/`, `max()`, `min()`
**Fichiers**:
- [ ] `src/process_engine/processors/CombatProcessor.cpp`
- [ ] `src/process_engine/FormulaEvaluator.h` (helper)
- [ ] `src/modules/systems/CombatSystemModule.cpp`
- [ ] `config/systems/combat_scenarios.json`
**Tests**:
- [ ] Test formulas parsing
- [ ] Test combat resolution
- [ ] Test loot distribution
- [ ] Test casualties
**Durée estimée**: 3-4 jours
---
## 📋 Phase 4: Event System (Data-Driven)
**Objectif**: Système d'événements scriptés avec conditions et outcomes
### 4.1 EventProcessor
**Logic**:
```cpp
void EventProcessor::execute(const IDataNode& params, IDataNode& state, IIO* io) {
// 1. Evaluate conditions (game_time, location, resources)
// 2. Trigger event si conditions met
// 3. Handle player choice
// 4. Apply outcomes (resources, flags, trigger_combat)
}
```
**Config** (`config/systems/events.json`):
```json
{
"events": {
"scavenger_encounter": {
"process": "trigger_event",
"title": "Scavengers Spotted",
"description": "Your scouts report a small group nearby.",
"conditions": {
"game_time_min": 600,
"location_type": "urban_ruins"
},
"choices": [
{
"id": "attack",
"text": "Attack immediately",
"outcomes": {
"trigger_combat": "scavenger_ambush",
"morale": -5
}
},
{
"id": "negotiate",
"text": "Attempt to trade",
"requirements": {"reputation": 20},
"outcomes": {
"resources": {"ammunition": -50, "food": +30},
"morale": +5
}
},
{
"id": "avoid",
"text": "Move on quietly",
"outcomes": {
"time_cost": 60
}
}
]
}
}
}
```
**Fichiers**:
- [ ] `src/process_engine/processors/EventProcessor.cpp`
- [ ] `src/modules/systems/EventSystemModule.cpp`
- [ ] `config/systems/events.json` (5 events minimum)
**Tests**:
- [ ] Test conditions evaluation
- [ ] Test event triggering
- [ ] Test outcomes application
- [ ] Test choice requirements
**Durée estimée**: 2-3 jours
---
## 📋 Phase 5: GameModule Integration
**Objectif**: GameModule orchestre tous les systèmes data-driven
### 5.1 GameModule Updates
**State Machine** (reste hardcodé):
```cpp
enum class GameState {
MainMenu, TrainBuilder, Expedition, Combat, Event, Pause
};
void GameModule::updateExpedition(float dt) {
// Publish event checks
auto checkEvent = make_unique<JsonDataNode>("check");
checkEvent->setDouble("game_time", m_gameTime);
checkEvent->setString("location", m_currentLocation);
m_io->publish("event:check", move(checkEvent));
// Handle incoming events
if (m_io->hasMessages()) {
auto msg = m_io->pullMessage();
if (msg.topic == "event:triggered") {
transitionToState(GameState::Event);
}
}
}
```
**Topics Orchestration**:
- Subscribe à tous les `*:complete` / `*:ended`
- Publish vers systèmes via `craft:start`, `combat:start`, etc.
- Gère transitions d'état
**Fichiers**:
- [ ] Update `src/modules/GameModule.cpp`
- [ ] Subscribe tous les nouveaux topics
- [ ] Wire systems ensemble
**Durée estimée**: 2 jours
---
## 📋 Phase 6: Storage System
**Objectif**: Save/load de tous les états data-driven
### 6.1 Storage Format
```json
{
"version": "0.1.0",
"timestamp": "2025-12-02T10:30:00Z",
"game_state": "Expedition",
"game_time": 3600.5,
"modules": {
"GameModule": {...},
"CraftingSystem": {...},
"CombatSystem": {...},
"EventSystem": {...}
}
}
```
**Fichiers**:
- [ ] `src/modules/systems/StorageSystemModule.cpp`
- [ ] Collect states via IIO broadcast
- [ ] Save to JSON
- [ ] Restore states on load
**Durée estimée**: 2 jours
---
## 📋 Phase 7: MC-Specific Modules
**Objectif**: Modules spécifiques Mobile Command (pas data-driven)
### 7.1 TrainBuilderModule
**Responsabilités**:
- Balance train (latéral/longitudinal)
- Wagon management
- Performance malus
**Topics**:
- Publish: `"train:composition_changed"`
- Publish: `"train:performance_updated"`
**Config**: `config/mc_specific/train.json`
### 7.2 ExpeditionModule
**Responsabilités**:
- Lancer expéditions
- Team composition (humains + drones)
- Return avec loot
**Topics**:
- Subscribe: `"craft:complete"` (drones)
- Publish: `"expedition:started"`, `"expedition:returned"`
**Config**: `config/mc_specific/expeditions.json`
**Durée estimée**: 3-4 jours
---
## 📋 Phase 8: Integration & Testing
**Objectif**: Loop complet fonctionnel
### 8.1 Integration Tests
- [ ] Full loop test: craft → expedition → combat → event → return
- [ ] Save/load cycle complet
- [ ] Hot-reload tous modules
- [ ] Pub/sub message flow validation
### 8.2 Main.cpp Updates
```cpp
std::vector<std::pair<std::string, std::string>> moduleList = {
// Game orchestrator
{"GameModule", "game.json"},
// Data-driven systems
{"CraftingSystemModule", "systems/crafting_recipes.json"},
{"CombatSystemModule", "systems/combat_scenarios.json"},
{"EventSystemModule", "systems/events.json"},
{"StorageSystemModule", "systems/storage.json"},
// MC-specific
{"TrainBuilderModule", "mc_specific/train.json"},
{"ExpeditionModule", "mc_specific/expeditions.json"}
};
```
**Durée estimée**: 2-3 jours
---
## 📊 Timeline Estimé
| Phase | Durée | Cumul | Livrable |
|-------|-------|-------|----------|
| Phase 1: ProcessEngine | 2 jours | 2j | Core engine fonctionnel |
| Phase 2: Crafting | 3 jours | 5j | Premier système data-driven |
| Phase 3: Combat | 4 jours | 9j | Combat data-driven |
| Phase 4: Events | 3 jours | 12j | Events data-driven |
| Phase 5: GameModule | 2 jours | 14j | Orchestration complète |
| Phase 6: Storage | 2 jours | 16j | Save/load |
| Phase 7: MC Modules | 4 jours | 20j | Train + Expeditions |
| Phase 8: Integration | 3 jours | 23j | Loop complet |
**Total: ~23 jours de dev (4-5 semaines)**
---
## 🎯 Critères de Succès
### Technique
- [ ] ProcessEngine avec 3+ processors (craft, combat, event)
- [ ] 3+ systèmes data-driven fonctionnels
- [ ] Hot-reload préserve état
- [ ] Pub/sub communication fluide
- [ ] Tests unitaires pass
### Gameplay
- [ ] Craft 5+ items
- [ ] Combat 3+ scenarios différents
- [ ] Trigger 5+ events
- [ ] Save/load fonctionne
- [ ] Loop complet 30+ minutes jouable
### Réutilisabilité
- [ ] ProcessEngine utilisable pour WarFactory
- [ ] Pas de hardcode MC-specific dans systems/
- [ ] JSON configs clairs et documentés
---
## 🔄 Comparaison Avant/Après
### Avant (Architecture actuelle)
```
ResourceModule.cpp (478 lignes)
├─ Logic craft hardcodée
├─ Formulas en C++
└─ Config JSON minimal
→ Changer formule = recompiler
→ Pas réutilisable WF
```
### Après (Architecture data-driven)
```
CraftingSystemModule.cpp (150 lignes)
├─ Utilise ProcessEngine
└─ Config recipes.json complet
CraftProcessor.cpp (100 lignes)
└─ Logic générique réutilisable
→ Changer formule = edit JSON
→ ProcessEngine réutilisable WF
```
---
## 🚀 Prochaines Étapes Immédiates
1. **Créer structure ProcessEngine** (Phase 1)
2. **Implémenter CraftProcessor** (Phase 2)
3. **Tester avec CraftingSystemModule** (Phase 2)
4. **Valider hot-reload** (Phase 2)
---
## 📝 Notes Importantes
### Design Decisions
1. **GameModule reste hardcodé** - State machine C++ pour clarté
2. **Systems sont data-driven** - Réutilisabilité MC/WF
3. **ProcessEngine est stateless** - State vit dans modules
4. **IIO pour tout** - Découplage maximal
### Risks
- **Formula parser complexity** - Garder simple pour prototype
- **JSON configs verbeux** - Trade-off accepté pour flexibilité
- **Hot-reload edge cases** - Tester intensivement
### Future Enhancements
- Expression parser avancé (Lua?)
- Visual process editor
- Process debugging tools
- Performance profiling
---
*Plan créé le 2 décembre 2025*
*Architecture inspirée de WarFactory worldgen*