Awoui Universe — le jeu-formation et son Académie.
  • HTML 90.4%
  • JavaScript 4.8%
  • PowerShell 3.6%
  • Shell 0.7%
  • PLpgSQL 0.5%
Aller au fichier
leguideinfo 7ca7727cd9 Première publication
Ce dépôt s'ouvre ici. L'historique qui précède était privé : deux ans de
notes, de tâtonnements et d'infrastructure nommée en clair. Il n'est pas
perdu — il est archivé hors ligne — mais il n'avait rien à apprendre à
personne, et beaucoup à révéler.

Ce commit contient le code tel qu'il tourne, relu ligne à ligne pour qu'il
ne porte ni adresse, ni secret, ni nom de personne.
2026-09-09 23:11:00 +02:00
agent Première publication 2026-09-09 23:11:00 +02:00
assets-src Première publication 2026-09-09 23:11:00 +02:00
client Première publication 2026-09-09 23:11:00 +02:00
deploy Première publication 2026-09-09 23:11:00 +02:00
docs Première publication 2026-09-09 23:11:00 +02:00
la-source Première publication 2026-09-09 23:11:00 +02:00
server Première publication 2026-09-09 23:11:00 +02:00
source Première publication 2026-09-09 23:11:00 +02:00
.gitignore Première publication 2026-09-09 23:11:00 +02:00
LICENSE Première publication 2026-09-09 23:11:00 +02:00
NOTICE Première publication 2026-09-09 23:11:00 +02:00
README.md Première publication 2026-09-09 23:11:00 +02:00
universe.lnk Première publication 2026-09-09 23:11:00 +02:00

Awoui Universe

Le MMO d'apprentissage d'Awoui : un jeu de stratégie spatiale persistant dont la progression est alimentée par la preuve de compétence réelle (formations, TP, labs) — pas par le temps d'attente. Voir la vision complète dans docs/gdd.md.

Structure

universe/
├── docs/
│   ├── gdd.md                     # Game Design Document (vision, économie, roadmap)
│   └── ws-programme-modernise.md  # Programme Windows Server modernisé (1er domaine)
├── assets-src/                    # Sources brutes non déployées (planche awoui-universe-assets.png)
├── client/
│   ├── concept.html               # Version jouable — fichier unique, SOURCE DE VÉRITÉ
│   ├── supervision.html           # Module « Supervision » autonome (2 volets) — voir plus bas
│   ├── hardening.html             # Cours « Hardening Windows Server » autonome (V1) — voir plus bas
│   └── assets/                    # Vidéos, poster, batiments/ (tuiles découpées de la planche)
├── deploy/
│   ├── build.ps1                  # Éclate concept.html -> dist/ + copie les assets
│   ├── build-supervision.ps1      # Éclate supervision.html -> dist/supervision/ (CSP-safe)
│   ├── build-hardening.ps1        # Éclate hardening.html -> dist/hardening/ (CSP-safe)
│   ├── build-source.ps1           # Éclate La Source (dépôt GitHub, hors projet) -> dist/source/
│   ├── crop-assets.ps1            # Découpe la planche assets-src -> client/assets/batiments/
│   ├── serve.ps1                  # Mini serveur local http://localhost:8710 (dist)
│   ├── serve-client.ps1           # Mini serveur local http://localhost:8711 (client/, dev)
│   └── nginx-universe.conf        # Vhost universe.awoui.com (statique + proxy V0 commenté)
└── dist/                          # Généré — ne pas éditer à la main
    ├── index.html
    ├── universe.css
    ├── universe.js
    ├── universe-embed.js          # Le jeu montable en Shadow DOM (scène native de la console)
    ├── source/                    # La Source (module autonome, servi en /source/)
    └── assets/

Workflow

  1. Éditer client/concept.html (style, markup et script dans un seul fichier).

  2. powershell -File deploy\build.ps1 → régénère dist/.

  3. Déployer : powershell -File deploy\deploy-client.ps1 -Vps neoadmin@<EDGE> -Port 4477 -Key "$env:USERPROFILE\.ssh\deploy_universe" (transport et pièges : deploy/README-rsync.md ; vhost déjà prêt, voir

    <EDGE> est un marqueur, pas une adresse : ce dépôt est public. La vraie valeur vit dans apex/deploy/adresses.local.sh, qui n'est pas versionné — apex/deploy/adresses.exemple.sh en donne le modèle et le pourquoi. les prérequis DNS + certbot en tête de deploy/nginx-universe.conf).

Règles du code client

  • Aucun inline handler (onclick="…") : la CSP du vhost est script-src 'self'. Les actions passent par data-act / data-id + un listener délégué unique.
  • Deux contextes d'exécution : standalone (universe.awoui.com) et scène native de la console (Shadow DOM via universe-embed.js, alias /universe/ du vhost console). Le script ne touche que document.getElementById/querySelector(All)/ addEventListener/createElement, location.reload() et setInterval — tous fournis par le shim de l'embed. Toute nouvelle API globale doit y être ajoutée.
  • Pont console : window.UNIVERSE_BRIDGE (openDatacenter(), openCourse(slug, mod)) — présent uniquement dans la console ; le jeu doit toujours dégrader proprement quand BRIDGE est nul (mission simulée par la forge).
  • Palette = tokens officiels Awoui (bleu nuit désaturé, cf. mémoire projet) ; accents cyan / émeraude / iris / or / corail, thème sombre assumé.
  • Icônes et illustrations : SVG vectoriel inline, stroke="currentColor".
  • La production est accélérée en démo via la constante DEMO dans le script.

Module Supervision (in-game, Académie multi-formations)

Le module « Supervision d'une infrastructure répartie » (Ère III) est intégré dans le jeu, concept.html, en formation sélectionnable au panneau Académie. L'Académie héberge désormais plusieurs parcours : le registre FORMATIONS = { "windows-server" (inchangé), "supervision", "hardening" } ; MISSION/VOLETS pointent sur la formation active (applyFormation(id)), le reste (libellés de jour, scellage, verrous, texte de fin, blocs réels) est paramétré par FDEF. Le sélecteur d'ouverture (ACA_INTRO, carte formation:true) propose Supervision + Windows Server + Hardening. Classe séparée respectée : un élève Windows a déjà passé le sélecteur (S.aca.formation fixé) → aucun changement pour lui ; loadGame restaure la formation active. Verrou : Volet 2 après le QCM du Volet 1. Les blocs « réel » supervision affichent les commandes Docker en clair (pas le clonage WS) ; les rouages d'empire restent inertes sur ces blocs.

Le fichier client/supervision.html (+ build-supervision.ps1) reste comme lecteur standalone secondaire (source d'extraction du contenu) — la source de vérité du contenu est maintenant concept.html.

  • 2 volets, 22 blocs. Volet 5 « La Vigie » (déployer la stack d'observabilité full-Docker, superviser le 1ᵉʳ nœud) · Volet 6 « La constellation sous surveillance » (agents distants, sondes blackbox, les 4 incidents, journaux Loki, sécurité, ANSSI, dashboard SLA). Chaque volet finit par un QCM puis un ⭐ TP en autonomie. Le Volet 6 est verrouillé tant que le QCM du Volet 5 n'est pas passé.
  • Stack enseignée : Prometheus + Grafana + Alertmanager + Loki/Promtail + exporters (node/windows/blackbox/snmp), en docker compose up. blackbox = les « sondes » du lore. Cible : conteneur Debian 12 du Datacenter, 30 élèves.
  • Pont console : les blocs real:true appellent window.UNIVERSE_BRIDGE.openDatacenter() si présent (fenêtre Proxmox) ; en autonome, ils révèlent les commandes en clair.
  • Dev : powershell -File deploy\serve-client.ps1 → http://localhost:8711/ (le / sert supervision.html). Sauvegarde locale : localStorage clé awoui-universe-supervision-v1.
  • Déploiement : powershell -File deploy\build-supervision.ps1 → produit dist/supervision/{index.html, supervision.css, supervision.js} (script séparé, conforme à la CSP script-src 'self' du vhost). Servir en /supervision/.

Cours Hardening Windows Server (standalone)

Le cours « Hardening Windows Server » (programme de référence : docs/hardening-windows-programme.md) vit dans client/hardening.html — un lecteur autonome repris du moteur Supervision (blocs cours → visuels → QCM → geste réel → scellage de volet).

Il est aussi intégré au jeu (concept.html) en formation sélectionnable : registre FORMATIONS["hardening"] (HARD_MISSION/HARD_VOLETS/HARD_TECH), carte dans le sélecteur d'ouverture de l'Académie et pilule dans la colonne « Formation ». realSteps:false → les gestes réels s'affichent en clair (l'élève travaille sur SON poste, VMware Workstation — pas au Datacenter) ; la condition isSupReal de renderMissionModal teste !FDEF.realSteps.

  • Cap du cursus (réorienté) : durcir (V2-V3) → auditer (V4 · PingCastle / Purple Knight) → remédier (V5). Hyper-V est hors périmètre (VT-x/EPT décoché — conflits avec les hôtes Windows 11) ; la VM du V1 devient le futur contrôleur de domaine.
  • Volet 1 « La Forge » livré, 11 blocs : enjeux & chaîne de confiance, choix de version (base Server 2025 Datacenter Évaluation, différences 2019/2022 au fil de l'eau), ISO officielle + SHA-256, VM Workstation (UEFI + Secure Boot), réduction de surface, chiffrement VM + vTPM, installation Core, sconfig, preuves (Confirm-SecureBootUEFI, Get-Tpm) + snapshot, QCM de scellage, bloc ⭐ bonus.
  • Volet 2 « Le Bastion » livré, 11 blocs — ordre pensé pour le plateau : défense en profondeur & baseline (+ conseil : lancer l'install de la 2ᵉ VM en arrière-plan), puis tout le durcissement à la console du serveur (comptes & verrouillage, SMBv1 éteint / WannaCry, NTLM niveau 5, pare-feu deny-by-default + journal — preuve du refus par un ping depuis le PC hôte —, tri des services / NetBIOS & télémétrie, Defender prouvé + test EICAR), puis seulement le poste d'admin HARD-ADM-01 et l'accès distant (chaîne PC → RDP → ADM-01 → WinRM → CORE-01, schéma dédié), et enfin le TP à distance (baseline + Test-Baseline.ps1 + dossier de preuves) + snapshot M2, QCM, ⭐ bonus (LAPS, Security Compliance Toolkit, événement 4625). Le poste d'admin est volontairement au bloc 8 : son installation ne bloque plus rien.
  • Volet 3 « La Citadelle » livré, 11 blocs : pourquoi l'annuaire est la cible, le volume de l'annuaire (disque E: dédié, Install-WindowsFeature BitLocker, chiffrement C: au TpmProtector — le vTPM du Volet 1 est enfin payé — puis E: en auto-unlock, clé de récupération hors du domaine : piège circulaire expliqué ; RAID traité en culture, honnêtement écarté du labo), promotion du DC (Install-ADDSForest -DomainName <pseudo>.universe -DatabasePath E:\NTDS -LogPath E:\NTDS -SysvolPath E:\SYSVOL, DSRM, dossiers NTDS et SYSVOL nommés, et la signature SMB serveur qui passe à True d'elle-même — boucle refermée avec le V2), tiering en trois étages, comptes à privilèges (groupes vidés, Utilisateurs protégés), Kerberos vs NTLM (audit avant coupure), GPO (portée LSDOU, politique de mots de passe du domaine — 7 caractères par défaut !), durcissement des contrôleurs par GPO (+ exclusions antivirus sur NTDS/SYSVOL — recommandation Microsoft — et sauvegarde de l'état du système testée), TP + note d'écart + snapshot M3, QCM, ⭐ bonus (LAPS, krbtgt, PSO).
  • Domaine du labo : <pseudo>.universe.awoui.com (ex. durand.universe.awoui.com, NetBIOS DURAND, connexion DURAND\adm-durand, DN DC=pseudo,DC=universe,DC=awoui,DC=com). Sous-domaine d'un domaine réellement possédé : le labo applique la pratique de production que le cours enseigne. Le niveau universe est un conteneur — aucun pseudo ne peut heurter un service réel (un élève surnommé vpn ou www). Un annuaire par élève → pas de collision si les labos communiquent, rapports d'audit identifiables. Trois encadrés couvrent : le choix du nom, les règles durables (NetBIOS ≤ 15, sans accent, on ne renomme pas) + la zone AD ne se publie jamais (les SRV _ldap._tcp.… sont un inventaire des DC), et l'ouverture split DNS + certificats publics par validation DNS (avec la contrepartie des journaux de transparence).
  • Volet 4 « La Salle d'audit » livré et ACTIF, 9 blocs : cadre de l'audit (boucle durcir→auditer→prioriser→remédier, mandat écrit), PingCastle (Netwrix, CLI depuis le poste d'admin, --healthcheck --server forge.lan, compte non privilégié suffisant), lecture du rapport (4 catégories, score global = le PIRE, risque donc bas = bon), Purple Knight (Semperis, GUI — d'où le poste d'admin —, 7 catégories, 210+ indicateurs, conformité donc haut = bon), IOE vs IOC (l'un se planifie, l'autre s'escalade), priorisation impact × effort + risque accepté écrit, TP (2 scans + tableau + synthèse 3 pages) + snapshot M4, QCM, ⭐ bonus (Forest Druid, rescan, BloodHound CE en culture).
  • Deck de l'étudiant (Nextcloud) — un par élève, alimenté par lui. Chaque bloc de mission porte un champ deck:[…] (ce qu'il faut y déposer : 1-2 captures précises, ou un écrit court) ; deckHtml(m, voletShort) rend un encadré or en fin de bloc avec « Liste ‹volet› → carte ‹nom du bloc› », la consigne, l'avertissement jamais de secret dans le Deck, et un bouton 📋 Ouvrir mon Deck → https://cloud.awoui.com/apps/deck/upcoming. Structure du tableau : une liste par volet, une carte par bloc. 42 blocs équipés (33 actifs + les 9 du Volet 4 masqué). Le bouton est un <a target="_blank"> volontairement, et non un appel JS : aucune API globale nouvelle, donc compatible CSP stricte et scène embarquée de la console (dont le shim ne fournit pas window.open). Si le pont expose un jour openDeck(), il suffira de brancher un data-act dans deckHtml. Préparation formateur conseillée : un tableau modèle dupliqué par élève, cartes déjà créées — sinon le temps passe en administration au lieu de technique.
  • Rendus de fin de volet, allégés : le TP3 remplace ses huit captures par un seul transcript (Start-Transcript → C:\Audit\tour-citadelle.txt) et une note d'écart en trois lignes (tableau), puis fait assembler NOM-Prenom_V3.pdf depuis la liste Deck du volet. Le TP4 se réduit à une page recto en six rubriques (en-tête · où nous en sommes · ce que je corrige · ce que j'accepte · compromission · où sont les preuves) plus l'annexe régénérée → NOM-Prenom_AUDIT.pdf. Le PDF du V4 cite celui du V3, il ne le recopie pas. Le tableau de priorisation est passé à cinq lignes et vit désormais dans hard-prioriser (le TP4 ne fait que le relire). Les trois routes de génération (traitement de texte / Markdown / API Deck en PowerShell) sont décrites une seule fois, dans le TP3, et réutilisées au TP4.
  • Le TP du Volet 2 finit par un script : Test-Baseline.ps1 compare l'obtenu à l'attendu (fonction Verifie), affiche OK/ECART par contrôle, compte les écarts et les rend en code de sortie (0 = conforme, exploitable par une tâche planifiée) — avec Set-ExecutionPolicy -Scope Process et le test du testeur (écart provoqué). « Vous venez d'écrire un outil d'audit » : la passerelle vers les outils du métier.
  • Arbre techno & récompenses réelles (in-game) : HARD_TECH = 4 technos par volet (grille pleine, aucune rangée orpheline — « Coffre scellé » a été fondu dans Chaîne de confiance, « Privilèges sous scellés » dans Étages étanches). Chaque redécouverte porte un perk permanent déclaré dans PERK_FX (table unique : dom = formule touchée, v = valeur, l = étiquette affichée — la carte de l'arbre ne peut pas mentir), lu par perkMul() / perkCut() et branché dans les vraies formules : matPerMin/datPerMin, matCap/datCap, uCost/uAdvCost, bTime, fleetMaint, bonMul("commerce"), fleetPower, réputation d'audit et risque de perte. 3 à 6 % chacun, cumulables. armOf() n'arrondit pas (round(4 × 1,08) = 4 aurait avalé le bonus des petites coques) : seul armTxt() arrondit pour l'affichage.
  • Trois plans réservés au parcours (only:()=>FDEF.id==="hardening" — invisibles ailleurs, mais jamais cachés s'ils sont déjà possédés). Les deux bâtiments portent les deux moitiés du combat, un point de calcul chacun (armMul() / atkMul()) pour que les cartes et la résolution ne puissent jamais diverger : bâtiment Coffre cryptographique (coffre, techno Chaîne de confiance, COFFRE_ARM_PCT +3 % de blindage par niveau, cumulé au perk armFleet), bâtiment Bastion d'administration (bastion, techno Poste de commandement, BASTION_ATK_PCT +4 % de dégâts par niveau — appliqué dans atkOf(), donc dans myForce()/combatRoster()/combatForce()/fleetPower() : audits ET affrontements PvP), unité de défense Sentinelle scellée (sentinelle, techno Étages étanches, atk 12 / arm 52).
  • Batterie de révocation (revocation, techno Tickets scellés — le krbtgt reset du cours : une salve et tout ce qui était signé périme). Pièce lourde de défense : atk 90 / arm 40, 140 🔩 · 32 💰. C'est la première défense au sol du jeu à porter un effet mécanique : REVOKE_PER +6 % de fleetPower() par batterie, plafonné REVOKE_MAX +30 % (tir de soutien au départ des task forces). Les autres unités type:"def" n'influencent, elles, que le score du classement et l'entretien — les audits subis sont simulés chez l'attaquant depuis le score public, pas ici. Assets à produire : client/assets/batiments/{coffre,bastion,sentinelle,revocation}.png (PNG 32 bits transparent, ~240 × 185, même facture que tourelle.png).
  • Verrous en chaîne : V2 exige hard-qcm1, V3 hard-qcm2, V4 hard-qcm3 (GATE_QCM côté standalone, voletLocked côté jeu). 42 blocs actifs, 100 questions, 13 schémas. Volet 5 (remédiation + projet final) à venir.
  • Public débutant : chaque bloc = pourquoi → geste → preuve, un schéma SVG par concept (SCHEMAS). Règle de lisibilité : textes des schémas jamais superposés aux tracés — zones dégagées + halo paint-order:stroke sous chaque texte.
  • Sauvegarde locale : localStorage clé awoui-universe-hardening-v1.
  • Dev : ouvrir client/hardening.html directement, ou serve-client.ps1 → http://localhost:8711/hardening.html.
  • Déploiement : powershell -File deploy\build-hardening.ps1 → produit dist/hardening/{index.html, hardening.css, hardening.js} (CSP script-src 'self'). Servir en /hardening/.

Parcours Windows Server avancé — Échos du plateau (missions → jeu)

La formation « Windows Server avancé » (FORMATIONS["socle-ad"] — l'id socle-ad est conservé, les sauvegardes le portent ; seul le nom affiché a changé le 10/08, série AD → PKI → IIS → VPN, Volet 1 livré) est reliée au vrai scénario du jeu par les Échos du plateau : des blocs kind:"plateau" insérés aux articulations du volet, qui envoient l'élève refléter EN JEU le geste qu'il vient de faire au Datacenter. Même contrat que Le Flux : l'Académie décrit l'objectif, le PLATEAU rend le verdict — le bloc se scelle à la fin du chantier ou à l'unité produite, jamais par un bouton de l'Académie (sauf « constat » d'un ouvrage déjà bâti, ordre libre oblige).

Geste réel (Datacenter) Écho (bloc) Recherche Objectif plateau
Install-ADDSForest (sad-foret) sad-p-citadelle Registre souverain · 9 🧠 Citadelle de l'annuaire niv. 1
SRV _msdcs prouvés (sad-dns) sad-p-tour Boussole des royaumes · 7 🧠 Tour de résolution niv. 1
GPO-Securite-Base (sad-gpo) sad-p-nexus Code des lois · 10 🧠 Nexus des politiques niv. 1 (grand ouvrage : 1 500 🔩 + 200 💰)
AGDLP + membre joint (sad-membre) sad-p-defense Chaîne de commandement · 10 🧠 Forge, puis 2 Batteries de missiles

Mécanique (concept.html) :

  • Champ plateau:{ tech, b, lvl } (bâtiment) ou plateau:{ tech, unit, n } (unités) sur le bloc ; plateauOK(m) lit l'état du jeu, plateauSync() scelle le bloc courant quand l'objectif est atteint — appelé depuis completeBuild, tickFleet (chaque unité produite), research et startBuild (rafraîchissement de la check-list). Un ouvrage bâti en avance se constate à l'ouverture du bloc (bouton « Sceller ✓ »), jamais par surprise.
  • La check-list du modal guide sans verrouiller : recherche → (Forge si unités) → ouvrage ; boutons plateauGo(vue, sélecteur) qui rangent la fenêtre Académie à droite (géométrie seule — pas openAcaWin, qui rembobinerait le bloc) et illuminent la carte visée (revealCard).
  • socle-chaine livre unlocks:"forge" en plus des missiles : sans elle, un élève pur-Socle ne pourrait assembler aucune unité (la Forge n'est offerte ailleurs que par WS fondation et Supervision sup-conteneur).
  • Économie du volet vérifiée : 18 blocs = 42 🧠 gagnés pour 36 🧠 de recherches — chaque écho est finançable à l'endroit où il apparaît, dans l'ordre conseillé, sans savoir extérieur. Le Nexus (grand ouvrage) se finance en avançant ; le volet ne se scelle qu'avec la loi debout.
  • Le toast « Volet 3 déverrouillé » de la Tour est désormais réservé à WS (la cinématique d'éveil reste pour tous) ; le score « N/N du premier coup » d'un bloc validé par le jeu n'hérite plus du QCM précédent.
  • 8 schémas SVG (même facture que Hardening : palette officielle, textes en zones dégagées, légende en pied) : socle-ou et socle-agdlp d'origine, plus les 6 du 10/08 — socle-dns-soi (le DNS vers soi), socle-foret (la promotion), socle-boussole (SRV/_msdcs), socle-deux-comptes (séparation des privilèges), socle-gpo-portee (portée + piège d'entretien), socle-jointure (l'accostage en trois gestes).
  • Registre de classe BAI3 26.4 (SOCLE_CLASSE, 18 étudiants, ordre alphabétique FIGÉ) : affiché en tableau dans le bloc « Déploiement au Datacenter » avec la stratégie en encadré. Un seul numéro par étudiant, le rang NN, qui dérive tout : VM du DC 264NN, VM d'INFRA01 265NN, IP 172.16.16.1NN (DC) et .2NN (membre) — passerelle .1 intouchable, même logique que la 26.3 (Supervision, CT 263NN/.1NN ; si ses CT tournent encore, le formateur arbitre les plages d'IP). Version formateur : docs/classe-bai3-26.4.csv (UTF-8 BOM, point-virgule — Excel-ready).

La Source (module autonome, /source/)

« La Source » est la vertical slice du jeu principal : 26 missions, jeu tactile plein écran, conçu et écrit depuis le mobile. C'est le seul module dont la source de vérité n'est pas dans ce dépôt — elle vit sur GitHub :

  • Dépôt : leguideinfo/games, dossier la-source/, sur la branche de travail du module. Cloné en local dans Code/games (à côté de universe/).
  • Boucle de travail : édition sur mobile → push GitHub → git -C ..\games pull → powershell -File deploy\build-source.ps1 → dist/source/ → rsync.
  • Ne jamais recopier index.html dans universe/client/ : deux copies éditables du même jeu, c'est exactement ce qui a produit quatre versions divergentes en août 2026.

Particularités par rapport aux autres modules :

  • Pas de balise <body> dans la source (</head>, puis <style>, puis <div id="app">, puis <script>) : build-source.ps1 extrait donc le corps entre </style> et <script>, là où build-hardening.ps1 cherche <body…>.
  • Images embarquées en base64 (img.src = "data:image/webp;base64," + …) : le déploiement reste 3 fichiers, aucun asset à copier. Compatible avec la CSP du vhost, qui autorise déjà img-src 'self' data:.
  • games/la-source/assets/ (~57 Mo de PNG) est de l'art source — jamais déployé, le build ne le lit même pas. Équivalent du assets-src/ de ce projet.
  • Sauvegarde locale : localStorage clé ls-save-v4 (+ ls-muted). Distincte de celle du jeu principal : les deux cohabitent sans se marcher dessus.
  • Test E2E : games/la-source/test/e2e.mjs (Playwright, viewport mobile 390×780) joue les 26 missions par interactions réelles via le hook window.__api. Il accepte GAME_URL en variable d'environnement → il valide aussi le build, pas seulement la source : GAME_URL=http://localhost:8710/source/index.html node test/e2e.mjs. ⚠️ Node n'est pas installé sur le poste Windows : ce test tourne pour l'instant côté cloud uniquement.
  • Dev : powershell -File deploy\serve.ps1 → http://localhost:8710/source/index.html (index.html explicite — le mini-serveur ne fait pas d'index de répertoire ; nginx, lui, a index index.html, donc /source/ suffit en production).
  • Déploiement : dist/source/ part avec le reste de dist/ par deploy-client.ps1. Aucune modification du vhost n'est nécessaire : root /var/www/universe + try_files $uri $uri/ servent le sous-dossier tel quel.

Statut : module autonome. La scène native dans la console (Shadow DOM, comme le jeu principal) reste possible mais demande trois adaptations au shim de universe-embed.js, qui ne fournit ni window ni document.body ni de purge des requestAnimationFrame : window.addEventListener("resize", …), getComputedStyle(document.body), et les trois boucles de rendu en requestAnimationFrame (frame, tzLoop, drawIntro) qui s'empileraient à chaque remount.

Prochaines étapes (cf. GDD §17)

  • Contenus réels J1–J5 au format formations/ dans le repo apex.
  • J1–J3 livrés (volet 1 = J1, volet 2 = J2 · Citadelle de l'Annuaire, volet 3 = J3 · gouvernement de l'annuaire : OU, import CSV, AGDLP, premières GPO — domaine par défaut mondomaine.local, chaque geste au choix GUI ou PowerShell/Core).
  • Journées 4–5 jouables (DHCP & réarmement, hybride & sauvegarde).
  • V0 moteur : API TypeScript + PostgreSQL + Redis derrière /api et /ws (blocs proxy déjà préparés dans le vhost).