# ROADMAP — Fallout: Venice of Wasteland État au **16 juin 2026**. Projet : moteur de simulation JDR Fallout 2D20 autonome, Louisiane post-nucléaire. --- ## ✅ Phase 1 — Moteur de base (TERMINÉ) - [x] Moteur de tick Python (survie, économie, rencontres) - [x] Système PNJ 4 tiers (Tier 0 Boss / Tier 1 Actifs / Tier 2 PNJ+ / Tier 3 Passage) - [x] Combats 2D20 (combat_engine.py) - [x] Sessions multiples isolées (session_id sur toutes les tables) - [x] Config JSON par session avec deep-merge par mode - [x] Hot-reload config au début de chaque jour (sans redémarrer) - [x] Vérification statut DB dans la boucle principale (stop depuis dashboard) - [x] Zones sûres (safe zones) — pas de rencontres lambda, commerce PNJ-à-PNJ - [x] Système de raids de faction dans les zones sûres (faible probabilité) - [x] Relations factions avec score de volatilité --- ## ✅ Phase 2 — RAG & Lore (TERMINÉ) - [x] ChromaDB avec 1403 chunks (règles 2D20 + lore canon Venice of Wasteland) - [x] Bible Venice of Wasteland v1.1 & v2.0 indexée (lore_canon, 32 chunks) - [x] Correction des 299 chunks avec métadonnée `type` → `category` - [x] Pipeline d'enrichissement lore (lore_enricher.py) - RAG depuis fallout_lore (lore_canon + regles_core + lore_inspiration) - Appel qwen2.5:14b avec prompt structuré JDR - Propositions stockées dans `lore_proposals` (PostgreSQL) - Validation manuelle depuis le PipBoy - Propositions acceptées → `fallout_lore_enriched` (Chroma) --- ## ✅ Phase 3 — Dashboard PipBoy (TERMINÉ) - [x] Dashboard Flask accessible sur fallout.coyoteos.ovh - [x] Onglet **SIM LIBRE** : état temps réel (PNJ, events, world state, factions, rencontres) - [x] Onglet **OUTILS** : génération commandes + stress test LLM avec console live - [x] Onglet **ENRICHISSEMENT** : validation propositions lore (accept/reject/modifier) - [x] Onglet **PARAMÈTRES** : config session, modes, reset jour/tick, statut DB - [x] Switcher de sessions (S1/S2) - [x] Auto-refresh 30s sur l'onglet simulation - [x] Métriques cards (PNJ vivants/morts, combats, rencontres) - [x] Bouton "Exécuter" stress test avec console live (polling 1.5s) - [x] Accès Ollama depuis le container Docker (iptables + host.docker.internal) --- ## ✅ Phase 4 — Tests de performance (TERMINÉ) - [x] Script stress test LLM (llm_crash_test.py) — modes simultane/decale/solo - [x] Script capacity test (capacity_test.py) — simulation N joueurs simultanés - [x] Résultats mesurés : 1/5/10/50 joueurs, tick 35s → 3m32 - [x] Conclusion : 10-15 joueurs actifs simultanés recommandés sur l'infra actuelle --- ## 🔄 Phase 5 — LLM intégré à la simulation (EN COURS / PROCHAIN) ### 5a — Animation PNJ par LLM (priorité haute) - [ ] Appel LLM 7b uniquement sur interaction joueur directe avec Tier 0/1 - [ ] Contexte RAG injecté : lore_canon faction + règles pertinentes - [ ] Mémoire courte terme : 3 derniers échanges du PNJ en contexte - [ ] Réponse stockée en DB (events table) avec attribution actor_id - [ ] Limit : max N appels LLM PNJ simultanés par tick (configurable) ### 5b — MJ narrateur par LLM (priorité haute) - [ ] Synthèse narrative du tick par le 14b (résumé de ce qui s'est passé) - [ ] Stockée comme événement `narrative_tick` en DB - [ ] Affichage dans PipBoy onglet SIM - [ ] Contexte : world_state + top 10 événements du tick + relations factions ### 5c — Onglet SIM LLM dans PipBoy - [ ] Vue dédiée pour les sessions avec LLM actif - [ ] Feed narratif du MJ en temps réel - [ ] Indicateur de charge LLM (requêtes en queue) --- ## 🔮 Phase 6 — Arbitre & Cohérence (CONÇU, NON IMPLÉMENTÉ) Système de vérification automatique entre les ticks, utilisant la marge de 6m30 disponible. ### Architecture ``` Tick N (3m30) → Résultats en DB Arbitre LLM (3m00) → Vérification cohérence + règles ├── Auto-correction (patterns connus) └── File manuelle → PipBoy validation Tick N+1 → Démarre sur une base cohérente ``` ### Tables à créer - `tick_validations` — anomalies détectées par tick - `correction_patterns` — patterns appris, score de confiance ### Logique d'apprentissage - Chaque validation manuelle augmente la confiance du pattern (+delta) - Chaque rejet diminue la confiance (-delta) - Seuil configurable (défaut 0.8) → bascule en auto-correction - Types de patterns : `stat_check` | `location` | `economy` | `narrative` ### Ce que l'arbitre vérifie - **Auto (confiance rapide)** : caps négatifs, HP > max, PNJ mort qui agit, localisation impossible - **Manuel (confiance lente)** : cohérence narrative, comportement faction vs lore, conflits de traités --- ## 🔮 Phase 7 — Ticks temps réel (IDÉE VALIDÉE, NON IMPLÉMENTÉ) Synchroniser les ticks sur l'heure réelle de la Louisiane (UTC-5/UTC-6). ### Principe - 1 tick = 1 heure réelle (timezone `America/Chicago`) - `run.py` calcule le tick courant depuis `datetime.now(tz)` au lieu d'incrémenter - Résout la dérive en cas de redémarrage - Nuit en jeu = vraiment la nuit (20h-8h Louisiana = 2h-14h France) ### Impact joueur - Action possible toutes les X minutes réelles - Le MJ et les PNJ "vivent" même quand le joueur est absent - Journées réelles = journées en jeu ### Config à ajouter dans sim_XXX.json ```json "tick": { "mode": "realtime", "realtime_timezone": "America/Chicago", "fixed_tick_sleep_sec": 60 } ``` ### Considération fuseau horaire - France UTC+2 vs Louisiane UTC-5/6 → 7-8h de décalage - Midi à NOLA = 18h-19h en France → créneau jouable en soirée - Nuit à NOLA se passe pendant les heures de travail en France → cohérent narrativement --- ## 🔮 Phase 8 — Météo procédurale (IDÉE, NON IMPLÉMENTÉ) Système météo calé sur la météo réelle de la Louisiane. - API météo New Orleans → injectée dans le contexte LLM chaque jour - Impact mécanique : pluie = -visibilité, chaleur extrême = drain eau ×1.5 - Événements saisonniers : saison des ouragans (juin-novembre), Mardi Gras - Stocké dans `world_state` par zone avec colonne `weather_json` --- ## 🔮 Phase 9 — Joueurs réels (VISION LONG TERME) Interface pour que de vrais joueurs envoient des actions. - API REST ou bot Discord → reçoit les actions joueur - Action validée par l'arbitre (Phase 6) avant d'être exécutée - Réponse PNJ via LLM 7b dans la foulée (<10s) - Résumé MJ 14b envoyé à la fin du tick - Gestion des absences : le PNJ joueur survit en mode automatique (Tier 1) --- ## Backlog technique (bugs connus / dettes) - [ ] `fallout-visu/app.py` et `dashboard/app.py` sont deux fichiers séparés à synchroniser manuellement → à unifier avec un mount symlink ou CI - [ ] Le container PipBoy se réinstalle à chaque restart (pip install au démarrage) → créer une image Docker dédiée - [ ] `capacity_test.py` écrit en root depuis le container (permission denied) → monter le volume avec le bon uid - [ ] 8 timeouts sur 50 joueurs simultanés → augmenter timeout à 300s ou implémenter une queue avec backpressure - [ ] Pas de persistance de l'iptables après reboot complet du host → vérifier que `netfilter-persistent` est installé --- ## Décisions d'architecture à retenir | Décision | Raison | |----------|--------| | LLM PNJ déclenché sur interaction seulement (pas chaque tick) | Évite de saturer Ollama sur les 100+ PNJ de la sim | | `fallout_lore` en lecture seule | Source de vérité immuable — les enrichissements vont dans `fallout_lore_enriched` | | Validation manuelle avant auto (Phase 6) | Constituer un corpus de corrections avant d'automatiser | | Ticks temps réel en option (pas par défaut) | Handicap pour les joueurs français si activé sans réflexion | | PostgreSQL sur Vigile (OVH) séparé d'Ampère | Résilience — si Ampère tombe, les données persistent | | Sessions isolées par `session_id` | Permet tests en parallèle sans collision de données |