# Session du 29 mai 2026 — Escape Dimensions

## 🎯 État du projet en fin de session

Le jeu fonctionne avec :
- Carte spatiale complète (39 zones, coordonnées 2D, altitudes)
- Perception déterministe (qui voit quoi, à quelle distance, dans quel cône)
- Narration LLM par-dessus (Ollama qwen3:8b @ 192.168.1.240)
- Plusieurs couches d'anti-hallucination

---

## ✅ Ce qu'on a fait aujourd'hui

### 1. Nettoyage initial des fuites de noms d'AIC
- Suppression des 3 références `classe` dans `game_api.php` (système de classes abandonné)
- Champ `classe` retiré de `schedule_aics.json` (donnée morte)
- Post-traitement `masquerNomsAic()` ajouté pour remplacer les noms d'AIC par des termes génériques (`un individu`, `une silhouette`, etc.)
- Règles GM 7-8 contre l'usage de noms propres dans la perception du joueur

### 2. Nettoyage UI
- Suppression de "Les lourdes portes s'entrouvrent" et "Sept personnages s'éveillent…" dans `player-app.jsx`
- Suppression de "et sept âmes décident de leur sort…" dans le message d'attente

### 3. Suppression de 9 fichiers obsolètes
- `uploads/` : `chateau_heist -AIC.json`, `chateau_heist_old.json`, `game_api - Copie.php`, `game_api_old.php`, `web_cli_interface_old.html`, `chateau_heist.json` (doublon), `schedule_aics.json` (doublon)
- `escape-dimensions_Data/` : `chateau_heist_old.json`, `chateau_heist -AIC.json`

### 4. Phase 1a TERMINÉE — Refonte spatiale du château
- **39 zones** complètes dans `chateau_heist.json` avec nouveau schéma :
  - `altitude`, `dimensions {x, y}`, `entree_defaut`, `objets[]` (avec positions), `ports[]` (avec types)
- Types de ports : `passage / door / window / balcony / trappe / meurtriere / stairs`
- États : `ouverte / fermee / verrouillee / fixe`
- 5 niveaux d'effort : `facile / moyen / difficile / athletique / impossible`
- World layout : enceinte 100×80m, plafonds 4m, 8 directions, cône 90°, vision 80m, audition 150m
- Zones réparties en 5 groupes :
  - **Bâtiment royal (19)** : N4 toiture, N3 (balcons + trône + chambre royale + pièce secondaire + couloir), N2 (apparat + couloir + 3 chambres), N1 (salle bal + couloir + cage escalier), N0 (réception + couloir + cuisine), passage secret
  - **Caserne (4)** : entrée, chambre capitaine, dortoir, lavoir
  - **Annexes militaires (4)** : entrée, salle d'armes, cantine, écurie
  - **Taverne (2)** : salle commune, chambres étage
  - **Habitations est (3)** : 2 maisons marchands + bijoutier
  - **Extérieurs (7)** : marché, cour, pont-levis, douves, forêt, chemin de ronde, tour sud
- `schedule_aics.json` mis à jour : positions de départ vers nouvelles zones, schedules
- `game_api.php` : `buildGameMasterPrompt()` lit le nouveau schéma (ports[] et objets[] objets)

### 5. Phase 1b TERMINÉE — Module de perception déterministe
- Nouveau fichier `perception.php` (~350 lignes)
- Fonctions : `computePerception(entity, monde)`, `formatPerceptionForPrompt(perc, mask)`, `initPositionInZone()`, `relativeDirection()`, `describePort()`
- Branchement dans `handleInit` (perception initiale) et `handleProcessTick` PHASE 0
- État runtime étendu : chaque entité a maintenant `(zone, x, y, direction)`
- Prompts AIC et GM réécrits avec règles strictes anti-hallucination
- Position se met à jour automatiquement à `entree_defaut` lors d'un changement de zone

### 6. Phase 1c PARTIELLE — Affinages perception
- **Distinctness filtering** : 3 catégories
  - `DISTINCTIF` : armure visible / couronne / arme dégainée / tablier / comportement notable (vol, course, combat)
  - `FOULE` : NPC ambiance avec `count > 1`
  - `PASSANTS` : silhouette ordinaire en vêtements normaux qui ne fait rien — fondu dans l'ambiance, pas singularisé
- **Distance-appropriate descriptions** :
  - FULL (0-5m) : physique + apparence complète
  - CLEAR (5-15m) : silhouette + tenue
  - DISTANT (15-30m) : silhouette + 1 signe le plus voyant
  - BLURRY (30-80m) : "silhouette lointaine indistincte"
- Nouveaux champs JSON par AIC : `silhouette`, `apparence`, `pos_initiale`
- Pour chaque AIC : silhouette et apparence explicites pour éviter toute fuite de métier
- **Option B implémentée** : appel LLM à l'init pour narration immersive (au lieu d'afficher les faits structurés bruts)
- **Sorties TOUJOURS connues** du joueur (pas filtrées par le cône de vision — c'est de la métadonnée de zone, pas de la perception cone-based)
- **Direction relative** : `devant vous / à votre droite / derrière vous / etc.` calculée depuis l'angle absolu et la direction du joueur
- **describePort() par type** :
  - door → *la façade du bâtiment X, porte en bois fermée*
  - passage → *passage à ciel ouvert qui mène à X*
  - window → *fenêtre de X*
  - balcony → *balcon donnant sur X*
  - stairs → *escalier qui mène à X*
- **Header ARCHITECTURE VISIBLE** dans les faits (au lieu de "SORTIES") pour bien expliquer au LLM que ce sont des bâtiments réels qu'il perçoit
- **Filtre `masquerNomsAic` étendu** au premier mot des noms et métiers (catche "le roi", "la reine", "le pickpocket" seuls)
- **Plus de noms/métiers dans la liste players du GM** : uniquement `ID:uuid_xxx (santé X)`
- **Règle GM #6 corollaire** : si question sur un personnage absent des faits → réponse "Vous ne voyez personne correspondant ici", JAMAIS inventer
- **Règle GM #11** : si question sur l'environnement → énumère TOUTES les sorties visibles
- **Affichage des `interactions` désactivé côté joueur** : trop confus (le GM listait des scènes dans d'autres pièces), la perception narrative suffit

---

## 📝 État des fichiers principaux

| Fichier | Statut |
|---------|--------|
| `chateau_heist.json` | ✅ Réécrit (39 zones nouveau schéma) |
| `schedule_aics.json` | ✅ Réécrit (positions zones nouvelles, sans `classe`) |
| `perception.php` | ✅ Nouveau (~350 lignes) |
| `game_api.php` | ✅ Adapté Phase 1a/1b/1c partielle |
| `player-app.jsx` | ✅ Texte hardcodé retiré, interactions désaffichées |
| `config.php` | Inchangé |
| `admin-app.jsx` | Inchangé |

---

## 🚧 Ce qu'il reste à faire

### Phase 1c — Finir la perception complète
- [ ] **Vision à travers les ports** (fenêtres, balcons, portes ouvertes, meurtrières) avec niveaux DISTANT/BLURRY selon altitude et angle. Permettra : voir le marché depuis la fenêtre du trône, voir la forêt depuis le balcon royal
- [ ] **Système d'audition complet** avec atténuation par les murs/portes (`facteur_porte_fermee: 0.5`, `facteur_porte_verrouillee: 0.3`, `facteur_fenetre_fermee: 0.4` — déjà en place dans le JSON mais pas implémenté)
- [ ] **Obstacles intra-zone** (line-of-sight) — pour qu'une grosse caisse / un trône bloque la vue de ce qu'il y a derrière
- [ ] **Mini-carte 2D dans l'interface joueur** — SVG dans `player-app.jsx`, position joueur + angle vue + silhouettes vues + cercle audition + brouillard de guerre

### AIC enrichment — Donner une vraie "vie" aux personnages
6 manques identifiés ensemble :
- [ ] **Missions actionnables** — sous-objectifs par période de la journée (au lieu de "Gouverner le royaume")
- [ ] **Relations entre AIC** — Map `player_id → relation` (e.g., George respecte Marcus, Brigitte glisse du pain à George, Roger surveille JoJo)
- [ ] **Secrets / peurs / désirs personnels** — pour chaque AIC, ajouter une couche d'intériorité
- [ ] **Schedules granulaires** — créneaux plus serrés (toutes les 30 min), pas juste 1-4 entrées
- [ ] **Mémoire d'événements** — pas juste les 3 dernières actions ; garder les rencontres et événements marquants
- [ ] **État émotionnel évolutif** — `vigilance`, `suspicion`, `fatigue_mentale` qui évoluent au fil des ticks selon les événements perçus

### Bugs connus / Améliorations potentielles
- [ ] **Hallucinations résiduelles** : si qwen3:8b continue à inventer malgré les règles, envisager filtre encore plus brutal (détection de noms absents des faits + remplacement par disavowal)
- [ ] **Marché plus riche** : ajouter des NPCs nommés à chaque étal (boulanger, boucher, marchand d'épices) avec leurs positions précises pour plus d'interactions possibles
- [ ] **Texte de perception initial trop long** : la narration LLM à l'init peut être verbeuse ; éventuellement tronquer ou demander plus concis
- [ ] **Direction du joueur** : pas de mécanisme côté joueur pour changer son angle de vue. Il faudrait que les actions "regarde à l'est" / "tourne-toi" modifient `direction`
- [ ] **Tester le rubis** : vérifier que la chaîne "voler le rubis" fonctionne avec les nouvelles zones (`n3_salle_trone` au lieu de `niveau_1_salle_trone`)

### Phase 2 — Suite naturelle
- [ ] **Carte d'admin avec affichage des positions** des AIC en temps réel
- [ ] **Métriques de partie** : ticks utilisés, suspicion globale, distance au rubis
- [ ] **Sauvegarde / chargement** d'une partie en cours

---

## 🗂 Architecture rappel

```
Y:\escape-dimensions\
├── joueur.html          (UI joueur)
├── admin.html           (UI admin)
├── game_api.php         (backend, 6 endpoints)
├── perception.php       (module spatial déterministe)
├── config.php           (LLM + chemins)
├── assets/
│   ├── player-app.jsx
│   ├── admin-app.jsx
│   ├── admin-panels.jsx
│   └── theme.css
└── uploads/             (anciens fichiers PHP login conservés pour futur)

Y:\escape-dimensions_Data\
├── chateau_heist.json   (le monde — 39 zones)
├── schedule_aics.json   (8 joueurs : 7 AIC + humain, npcs ambiance)
└── *.md                 (docs conceptuelles, à garder)
```

## 🧠 Boucle de jeu (par tick = 10 min de jeu)

```
1. Le joueur tape son intention dans joueur.html
   ↓
2. PHASE 0 (PHP, perception déterministe)
   • computePerception() pour chaque AIC vivant + joueur
   • formatPerceptionForPrompt() → bloc texte structuré (FAITS)
   ↓
3. PHASE 1 (LLM, parallèle)
   • 7 appels AIC en curl_multi (qwen3:8b)
   • Chaque AIC reçoit SES faits + sa mission + sa routine → renvoie une intention
   ↓
4. PHASE 2 (LLM, 1 seul appel)
   • Game Master reçoit toutes les intentions + tous les faits + règles strictes
   • Produit JSON : tick_results (perception narrative + position) + interactions + npc_updates
   ↓
5. PHASE 3 (PHP, état autoritaire)
   • Met à jour positions, sant é, status
   • Anonymisation défensive (masquerNomsAic) sur la perception du joueur
   • Suivi déterministe du rubis (hors LLM)
   ↓
6. Réponse au frontend → affichage narratif au joueur
```

## 🔐 Anti-hallucination : 4 couches

1. **Faits déterministes pré-calculés** côté PHP (le LLM n'invente pas qui voit qui)
2. **Prompts ultra-stricts** : *"n'invente JAMAIS un personnage/objet/sortie absent des faits"*
3. **Liste joueur sans noms ni métiers** : le LLM ne VOIT plus les rôles dans son input
4. **Post-traitement `masquerNomsAic`** : remplace tout nom/métier d'AIC dans la perception du joueur par "un individu / une silhouette / quelqu'un"

---

Bonne nuit. À demain. 🌙
