- 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>
15 KiB
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
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.hsrc/process_engine/ProcessEngine.cppsrc/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:
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.cppsrc/process_engine/processors/CraftProcessor.h
2.2 CraftingSystemModule
State:
{
"inventory": {
"scrap_metal": 100,
"ammunition": 500
},
"craft_queue": [
{"recipe": "repair_kit", "time_remaining": 25.3}
]
}
Config (config/systems/crafting_recipes.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.cppsrc/modules/systems/CraftingSystemModule.hconfig/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:
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):
{
"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.cppsrc/process_engine/FormulaEvaluator.h(helper)src/modules/systems/CombatSystemModule.cppconfig/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:
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):
{
"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.cppsrc/modules/systems/EventSystemModule.cppconfig/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é):
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
{
"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
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
- Créer structure ProcessEngine (Phase 1)
- Implémenter CraftProcessor (Phase 2)
- Tester avec CraftingSystemModule (Phase 2)
- Valider hot-reload (Phase 2)
📝 Notes Importantes
Design Decisions
- GameModule reste hardcodé - State machine C++ pour clarté
- Systems sont data-driven - Réutilisabilité MC/WF
- ProcessEngine est stateless - State vit dans modules
- 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