Files
fallout-venice/README.md
T

274 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fallout: Venice of Wasteland — Moteur de simulation JDR
Simulation autonome d'un univers **Fallout 2D20** situé en Louisiane post-nucléaire.
Le moteur simule des PNJ, des factions, des rencontres et une économie — sans MJ humain permanent.
Un LLM joue le rôle de MJ narrateur, un second LLM anime les PNJ.
**Dashboard** → [fallout.coyoteos.ovh](https://fallout.coyoteos.ovh) (PipBoy)
**Gitea** → [git.coyoteos.ovh](https://git.coyoteos.ovh) — repo `Corback/fallout-venice`
---
## Architecture générale
```
┌─────────────────────────────────────────────────────────┐
│ AMPÈRE (Oracle ARM) │
│ 82.70.224.131 │
│ │
│ ┌──────────────┐ ┌───────────────┐ ┌────────────┐ │
│ │ run.py S1 │ │ run.py S2 │ │ PipBoy │ │
│ │ (sim engine)│ │ (sim engine) │ │ Flask │ │
│ └──────┬───────┘ └───────┬───────┘ └─────┬──────┘ │
│ │ │ │ │
│ ┌──────▼───────────────────▼────────────────▼──────┐ │
│ │ Ollama (localhost:11434) │ │
│ │ qwen2.5:14b (MJ) + qwen2.5:7b (PNJ) │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ChromaDB :8800 — collection fallout_lore │ │
│ │ 1403 chunks : règles 2D20, lore canon, ambiance │ │
│ └────────────────────────────────────────────────────┘ │
└────────────────────────────┬────────────────────────────┘
│ SSH tunnel :15432
┌────────────────────────────▼────────────────────────────┐
│ VIGILE (OVH) 79.72.30.231 │
│ PostgreSQL — base "fallout" │
└─────────────────────────────────────────────────────────┘
```
---
## Infra & accès
| Serveur | IP | Rôle | Clé SSH |
|---------|----|------|---------|
| Ampère | 82.70.224.131 | Calcul — LLM, sim, dashboard | `oracle.key` |
| Vigile | 79.72.30.231 | PostgreSQL | `vigile_backup` |
**Tunnel DB actif sur Ampère** : `localhost:15432` → Vigile:5432
**ChromaDB** : `localhost:8800` — API v2 uniquement (`/api/v2/...`)
**Ollama** : `localhost:11434`
**PipBoy (Docker)** accède à Ollama via `host.docker.internal:11434`
---
## Stack technique
| Composant | Technologie | Détail |
|-----------|------------|--------|
| Moteur sim | Python 3.11 | `src/engine/` |
| Dashboard | Flask + Jinja2 | Docker `fallout-visu` |
| LLM MJ | qwen2.5:14b via Ollama | ~30s/réponse warm |
| LLM PNJ | qwen2.5:7b via Ollama | ~5s/réponse warm |
| Base de données | PostgreSQL 15 (Vigile) | SSH tunnel depuis Ampère |
| RAG | ChromaDB v1.0.0 (API v2) | collection `fallout_lore` |
| Proxy | nginx-proxy-manager | SSL Let's Encrypt auto |
| Gitea | git.coyoteos.ovh:2222 | repo Corback/fallout-venice |
---
## Structure du projet
```
fallout-venice/
├── src/
│ ├── engine/
│ │ ├── run.py # Lanceur principal (hot-reload config, status check loop)
│ │ ├── tick.py # Orchestration d'un tick
│ │ ├── encounter.py # Rencontres (safe zones, raids, commerce PNJ)
│ │ ├── combat_engine.py # Résolution combats 2D20
│ │ ├── sim_config.py # Chargement + deep-merge config JSON
│ │ ├── init_pnj.py # Initialisation PNJ en DB
│ │ ├── lore_enricher.py # Enrichissement lore via LLM + RAG Chroma
│ │ └── db.py # Accès PostgreSQL
│ ├── config/
│ │ ├── sim_001.json # Config session 1 (référence des 5 modes)
│ │ ├── sim_002.json # Config session 2
│ │ └── crash_results.json # Résultats derniers tests LLM (lu par PipBoy)
│ └── data/
│ └── encounter_tables.json # Tables rencontres, zones sûres, pools entités
├── dashboard/
│ └── app.py # Source PipBoy — copier dans /home/ubuntu/fallout-visu/
├── tools/
│ ├── llm_crash_test.py # Stress test LLM (modes: simultane/decale/solo)
│ └── capacity_test.py # Test capacité N joueurs simultanés
├── README.md
└── ROADMAP.md
```
> ⚠️ Le dashboard actif est `/home/ubuntu/fallout-visu/app.py` (monté dans Docker).
> `dashboard/app.py` est la source de vérité — toujours synchroniser les deux après modification.
---
## Système de PNJ — 4 tiers
| Tier | Label | Comportement | LLM actuel |
|------|-------|-------------|-----------|
| 0 | BOSS | Immortel, chef de faction | Non (prévu 14b) |
| 1 | ACTIFS SIM | Simulés chaque tick, mémoire persistante | Non (prévu 7b) |
| 2 | PNJ+ | Réagissent aux événements importants | Non (prévu 7b) |
| 3 | PASSAGE | Décor narratif | Jamais |
Actuellement tous les PNJ sont animés par le **moteur Python seul**.
Le LLM PNJ sera déclenché uniquement sur **interaction joueur directe** (V2).
---
## Zones sûres
`independance` | `nola_vieux_carre` | `baton_rouge` | `laplace`
Règles : pas de rencontres lambda/groupe. Seuls les raids de faction (faible probabilité) et le commerce PNJ-à-PNJ sont possibles. Les marchands peuvent s'y retrouver sans rencontrer de bêtes.
---
## Modes de simulation
Configurables depuis le PipBoy — prise en compte au **prochain jour** (hot-reload).
| Mode | Rencontres | Drain | Économie | Usage |
|------|-----------|-------|---------|-------|
| `pacifiste` | ×0.4 | ×0.7 | normal | Test/debug |
| `politique` | ×0.6 | ×1.0 | normal | Intrigues factions |
| `guerre_commerciale` | ×1.2 | ×1.5 | ×1.5 caps | Blocus, routes coupées |
| `guerre` | ×2.0 | ×1.8 | pénurie | Front de guerre actif |
| `survie_extreme` | ×1.8 | ×2.5 | ×0.3 | Stress test pur |
---
## ChromaDB — collection `fallout_lore`
**1403 chunks** — source de vérité en lecture seule.
| Catégorie | Chunks | Contenu |
|-----------|--------|---------|
| `regles_core` | ~934 | Règles 2D20 Fallout (avec 299 chunks migrés depuis `type``category`) |
| `regles_supplement` | 279 | Suppléments et extensions |
| `lore_inspiration` | 86 | Inspiration univers Fallout |
| `ambiance` | 43 | Descriptions atmosphériques |
| `aventure` | 29 | Scénarios de référence |
| `lore_canon` | 32 | **Bible Venice of Wasteland v1.1 & v2.0** |
`fallout_lore_enriched` → reçoit les propositions lore **acceptées** depuis le PipBoy.
---
## Performances LLM mesurées (16/06/2026, Ampère ARM)
| Joueurs simultanés | Tick complet | Actions/heure | Viable tick 10min |
|-------------------|-------------|---------------|-----------------|
| 1 | 35s | 103 | ✓ |
| 5 | 57s | 62 | ✓ |
| 10 | 1m17 | 46 | ✓ |
| 50 | 3m32 | 16 | ✓ (8 timeouts) |
MJ 14b : constant ~30s indépendamment du nombre de joueurs (commence après tous les PNJ).
Cold start : ~90s si Ollama a déchargé les modèles (inactivité prolongée).
**Plafond recommandé V1 : 10-15 joueurs actifs simultanés.**
---
## Lancement des simulations
```bash
# SSH sur Ampère
cd /home/ubuntu/fallout-venice/src/engine
# Session 1
nohup env SESSION_ID=1 TICK_SLEEP_SEC=60 PYTHONUNBUFFERED=1 \
python3 -u run.py > ~/fallout_sim_s1.log 2>&1 &
# Session 2
nohup env SESSION_ID=2 TICK_SLEEP_SEC=60 PYTHONUNBUFFERED=1 \
python3 -u run.py > ~/fallout_sim_s2.log 2>&1 &
tail -f ~/fallout_sim_s1.log
```
**Reset propre d'une session :**
1. PipBoy → Paramètres → **STOP** (attendre max 5 ticks)
2. PipBoy → Paramètres → **Reset Jour/Tick**
3. Relancer via terminal
---
## Enrichissement lore
```bash
cd /home/ubuntu/fallout-venice/src/engine
python3 lore_enricher.py --faction grand_krewe # une faction
python3 lore_enricher.py --faction all # toutes
python3 lore_enricher.py --list-factions # liste
```
Valider les propositions → PipBoy onglet **ENRICHISSEMENT**
Les propositions acceptées sont indexées dans `fallout_lore_enriched` (Chroma).
---
## Tests LLM
```bash
cd /home/ubuntu/fallout-venice/tools
# Stress test simple
python3 llm_crash_test.py --mode simultane --rounds 5 --pnj-count 2
# Test capacité (1 / 5 / 10 / 50 joueurs)
python3 capacity_test.py
python3 capacity_test.py --quick # sans le test 50 joueurs
```
Les résultats sont écrits dans `src/config/crash_results.json` et lisibles depuis le PipBoy (onglet OUTILS → Charger les résultats).
---
## Variables d'environnement clés
| Variable | Défaut | Description |
|----------|--------|-------------|
| `SESSION_ID` | 1 | Session simulée |
| `TICK_SLEEP_SEC` | 60 | Durée d'un tick (secondes) |
| `PYTHONUNBUFFERED` | — | `1` pour logs temps réel |
| `OLLAMA_URL` | `http://localhost:11434` | Endpoint Ollama |
| `MODEL_MJ` | `qwen2.5:14b` | Modèle MJ narrateur |
| `MODEL_PNJ` | `qwen2.5:7b` | Modèle animation PNJ |
| `DB_HOST` / `DB_PORT` | `127.0.0.1` / `15432` | PostgreSQL via tunnel SSH |
| `SIM_CONFIGS_DIR` | `/app/src/config` | Répertoire configs JSON |
| `CRASH_RESULTS_PATH` | `src/config/crash_results.json` | Sortie tests LLM |
---
## ⚠️ Points critiques — à ne jamais oublier
**ChromaDB**
- API v2 uniquement — `/api/v1/` retourne `{"error":"Unimplemented"}`
- Requêtes par **UUID**, pas par nom de collection (récupérer l'UUID d'abord via `GET /collections`)
- La collection `fallout_vst` **n'existe pas** — c'est `fallout_lore`
- 299 chunks avaient le champ `type` au lieu de `category` — corrigé en juin 2026
**Dashboard**
- Le fichier actif est `/home/ubuntu/fallout-visu/app.py` (monté Docker), pas `dashboard/app.py`
- Toujours copier les deux après modification : `scp dashboard/app.py ubuntu@82.70.224.131:/home/ubuntu/fallout-visu/app.py`
**Simulation**
- `run.py` vérifie le statut DB toutes les **5 ticks** — STOP depuis PipBoy n'est pas instantané
- Hot-reload config JSON au **début de chaque jour** (tick 0), pas immédiatement
- `init_pnj.py` lit `SESSION_ID` depuis l'env (plus hardcodé)
**Réseau Docker**
- Le container PipBoy accède à Ollama via `host.docker.internal:11434`
- Une règle iptables autorise 172.20.0.0/16 → port 11434. Si elle disparaît après reboot :
```bash
sudo iptables -I INPUT 1 -s 172.20.0.0/16 -p tcp --dport 11434 -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
```
**Tunnel SSH DB**
- Le container PipBoy crée son propre tunnel au démarrage (clé `/ssh/vigile.key`)
- Si DB inaccessible : `docker restart fallout-visu`