05 — Le backoffice éditeur
Le principe
L'éditeur n'est pas un outil interne, c'est la moitié du produit.
Le moteur sera terminé en quelques semaines. Les fils narratifs, eux, ne seront
jamais terminés — et ils seront écrits à plusieurs (cf.
09-collaborators.md). Donc l'éditeur doit être
utilisable par quelqu'un qui n'écrira jamais une ligne de code, et agréable dès
le prototype.
Corollaire : si une mécanique de jeu ne peut pas être exprimée dans l'éditeur, elle n'existe pas. Pas de contenu écrit en dur dans le code, jamais, même « juste pour tester ». C'est la règle qui garde le moteur générique.
1. Les rôles
D'après le cadrage : moi + quelques auteur·rice·s invité·e·s (comptes).
| Rôle | Peut | Ne peut pas |
|---|---|---|
| owner (Gabriel) | tout, y compris publier un pack et gérer les comptes | |
| author (Dom, Claire, invités) | créer/modifier du contenu, lancer des parties de test, commenter | publier, supprimer un pack, toucher aux réglages moteur |
| reviewer | lire, commenter, marquer « validé métier » | modifier |
| playtester | jouer les packs en review, laisser un retour daté | voir l'éditeur |
Le rôle reviewer est spécifiquement là pour l'expertise métier : Dom valide
tout ce qui touche VFX, Claire tout ce qui touche production. Un incident marqué
ready sans validation métier reste signalé dans le tableau de bord — pas
bloqué, juste visible.
2. La chaîne de contenu
Rappel de 01-architecture.md : git est la source de vérité, PocketBase est
la surface d'édition.
content/<pack>/**/*.json ──import──► PocketBase ──export──► content/ ──► commit
▲ ▲ │
│ │ │
relecture en PR l'éditeur web content:build
│
▼
dist/content-<hash>.json
Deux commandes, un cycle :
npm run content:import # git → PocketBase (avant une session d'écriture)
npm run content:export # PocketBase → git (après ; sortie déterministe, clés triées)
npm run content:lint # validation, sans base
npm run content:build # validation + résolution + bundle figé + hash
L'export est déterministe (un fichier par entité, clés triées, indentation stable) pour que les diffs soient lisibles ; il refuse de tourner sur un arbre de travail sale.
3. Les écrans
3.1 Tableau de bord du pack
La page d'accueil de l'éditeur. Ce qu'elle montre :
- l'avancement par type d'entité (12 personnes prêtes / 3 en revue / 8 brouillons) ;
- les erreurs de validation en tête, avec le lien direct vers l'entité ;
- les avertissements de contenu : incidents jamais déclenchables, scènes sans besoin, personnes que rien ne référence, options sans conséquence ;
- l'état des validations métier en attente ;
- un bouton « jouer ce pack » qui lance une partie de test en un clic.
3.2 Éditeur de scène + dépouillement
L'écran le plus utilisé. Le même composant que celui du joueur, avec la vérité affichée — c'est un choix fort : on écrit avec l'outil du joueur, donc on teste l'outil en permanence.
- le texte de la scène à gauche, surlignable au stabilo par poste ;
- la liste des besoins à droite, générée par les surlignages ;
- un bouton « proposer un dépouillement » (LLM local, cf. §5) qui pré-remplit, l'auteur corrige ;
- l'en-tête de scène (INT./EXT., jour/nuit, décor, personnages, longueur) ;
- les critères et leurs pondérations, avec un aperçu : « cette scène se juge
surtout sur
jeuetemotion» ; - l'importance narrative et l'attachement du réalisateur, réglés séparément (c'est le couple qui fabrique les choix cornéliens).
3.3 Éditeur de graphe narratif
Le cœur de l'outillage. Détaillé dans
data-model/events.md ; ce qu'on en attend côté
ergonomie :
- une vue graphe : les nœuds d'incidents, les arêtes de conséquence, le temps en abscisse (acte I / II / III) ;
- un filtre par fil narratif — on ne travaille jamais sur le graphe entier, on travaille sur « le fil du chef op au rabais » ;
- un inspecteur de nœud : conditions, canal de présentation, options, effets ;
- l'éditeur de conditions en arbre de prédicats, pas en texte libre : on choisit un sujet, un opérateur, une valeur ; ça reste sérialisable, diffable et vérifiable statiquement ;
- la coloration des nœuds par accessibilité : atteignable / jamais atteignable / orphelin / trop probable.
3.4 Bibliothèques
Personnes, éléments, traits, incidents génériques : des bibliothèques réutilisables entre packs. Un « pack matériel caméra standard » ou un « vivier de chefs op » ne se réécrit pas à chaque scénario. Un pack déclare ses dépendances de bibliothèques et peut surcharger une entité localement.
3.5 Le bac à sable de simulation
L'écran qui distingue un éditeur jouet d'un éditeur utile.
- Poser un état arbitraire : « on est au jour 14, le chef op est sous-payé, il pleut, le budget est à −8 % » — et voir ce que le directeur d'aléas déclencherait.
- Tester un fil sans jouer la partie : dérouler les nœuds, vérifier les conditions une à une, voir où ça bloque.
- Lancer N parties automatiques (
npm run sim) et lire les distributions : taux de déclenchement par incident, dépassement médian, durée médiane, incidents jamais vus, incidents fatals. Les statistiques remontent dans l'éditeur, à côté de chaque incident : « déclenché dans 3 % des parties » est l'information dont un auteur a besoin. - Rejouer une partie réelle depuis son journal, et s'arrêter à un tour.
4. La validation statique, exigence de premier ordre
Le contenu doit être vérifiable sans jouer. content:lint échoue sur :
| Vérification | Pourquoi |
|---|---|
référence cassée (personRef inexistante) | évidente |
| condition non satisfiable (prédicat contradictoire, champ inconnu) | un nœud mort ne se voit jamais en jouant |
| incident sans issue (aucune option) ou option sans effet | trou de gameplay |
| scène sans besoin, ou dont les besoins n'existent pas dans le pack | le joueur ne peut pas la tourner |
| chapitre de devis inconnu | le budget ne se boucle plus |
| texte non traduit quand une locale est déclarée obligatoire | i18n |
chiffre hors bornes (un Rated à 140, une proba à 1.4) | classique |
| cycle dans le graphe des conséquences (A arme B arme A) | boucle infinie en partie |
| atteignabilité : aucun chemin réaliste ne mène à ce nœud | le travail d'écriture est perdu |
L'atteignabilité est la vérification qui vaut le plus cher à écrire et qui rapporte le plus : elle réutilise l'évaluateur de conditions du moteur, sur des états échantillonnés par la simulation.
5. L'assistance LLM, à sa place
Le cadrage demande explicitement de la génération procédurale / LLM. La ligne de
partage posée en 02-event-sourcing.md §5 tient :
Le LLM écrit le contenu ; la graine choisit dans ce contenu.
Dans l'éditeur, avec le LM local du lab (brain / LM Studio) :
| Fonction | Statut |
|---|---|
| Proposer le dépouillement d'une scène à partir de son texte | ✅ gain de temps majeur, l'auteur corrige |
| Décliner un incident en 3 variantes de formulation (SMS, mail, appel) | ✅ |
| Générer un lot de personnes crédibles (noms, parcours, traits, tarifs) | ✅ en lot, relu, figé |
| Écrire une scène de scénario à partir d'un synopsis | ✅ pour un pack généré |
| Traduire FR→EN le contenu validé | ✅ avec relecture |
| Générer les portraits, les photos de plateau, les repérages | ✅ pipeline d'images, commité |
| Générer un pack complet (scénario + casting + aléas) | ⚠️ oui, mais en cuisson : produit → validé → figé avec un hash → ensuite jouable |
| Générer un aléa pendant une partie | ❌ casse le déterminisme, invérifiable, injouable hors ligne |
Le mode « pack généré » mérite son propre écran : un formulaire de brief (genre, budget, époque, contraintes), une génération, puis une passe de relecture obligatoire avant publication. C'est la seule façon que Dom et Claire puissent valider ce qu'un modèle a écrit avant qu'un étudiant le joue.
6. i18n dans l'éditeur
FR d'abord, EN ensuite, mais le modèle est bilingue dès le début (cf.
03-data-model.md §6.b).
- Chaque champ traduisible s'édite avec un onglet FR / EN.
- Un indicateur de couverture par pack (« EN : 34 % »).
- La locale de référence est le FR ; l'EN peut manquer sans bloquer, sauf si le
pack déclare
locales: ['fr','en']comme obligatoires. - Les identifiants ne se traduisent pas :
slug,tag,poste,type d'événementrestent en français technique. C'est du vocabulaire métier, et il fait partie du produit — même la version anglaise dira HMC et dépouillement, avec une infobulle.
7. Boucle de relecture experte
Un bouton « demander une validation métier » sur toute entité :
- l'auteur marque l'entité
reviewet choisit un domaine (VFX / production / général) ; - le reviewer concerné reçoit une notification et voit sa file d'attente ;
- il commente ligne à ligne, ou valide ;
- le tableau de bord affiche ce qui est validé, ce qui ne l'est pas.
Sans ça, l'expertise de Dom et Claire arrive par mail, se perd, et le jeu dérive vers du plausible plutôt que du juste. Avec ça, elle est attachée à l'objet qu'elle valide.
8. Ce qui reste à trancher
- Éditeur = route de l'app de jeu, ou application séparée ? (partagé au début, séparé quand il grossit — mais quand ?)
- Édition simultanée à plusieurs : verrou optimiste, ou temps réel PocketBase ? (verrou simple suffit à 3 auteurs)
- Le graphe se dessine-t-il vraiment (arêtes manuelles), ou se déduit-il des
conditions ? Cf. le débat hybride dans
data-model/events.md. - Faut-il un mode « écriture linéaire » (un fil narratif écrit comme un document, converti en nœuds) pour les auteur·rice·s qui n'aiment pas les graphes ?
- Import de scénario : quel format ? (Final Draft
.fdx, Fountain, PDF + OCR, copier-coller) — Fountain est le plus simple et suffit probablement.