Apparence
Journal des décisions
Chaque entrée : la décision, l'alternative écartée, la raison. À consulter avant de reproposer une option — la plupart des « bonnes idées » listées ici ont déjà été examinées et rejetées pour des motifs précis.
D-01 · Mode de jeu : synchrone temps réel
Écarté : asynchrone tour par tour, ou les deux. Raison : l'asynchrone interdit toute mécanique réactive et casse le rythme d'un duel. Le coût est un service stateful (WebSocket), assumé.
D-02 · Combat : attaque libre + Provocation
Écarté : modèle Magic (déclaration d'attaque puis assignation de bloqueurs). Raison : le blocage double la complexité du moteur et de l'UI pour une profondeur dont un jeu de guilde n'a pas besoin au lancement.
D-03 · Ressource : « Ferveur », auto-ramp, plafond 10
Écarté : cartes-terrain façon Magic (diluent le deck, créent le mana screw) ; le terme « Cristal » (générique) ; « Élan », « Cohésion », « Renom ». Raison : la triade Sceaux / Ferveur / PV ne présente aucun chevauchement sémantique. Le plafond (10) est le bouton de rythme à ajuster en premier si les parties traînent.
D-04 · Avantage du second joueur : +1 Ferveur temporaire, tour 1 uniquement
Écarté : +1 Ferveur permanent (le J2 gagnerait ~65 % des parties — un tour d'avance sur la courbe est l'avantage le plus décisif du genre) ; une carte « Pièce » (collision de vocabulaire avec les Sceaux). Implémentation : alimente ferveurActuelle, ne touche pas à ferveurMax.
D-05 · Deck de 30, 3 copies max (2 épique, 1 légendaire)
Écarté : 20 cartes / 2 copies (envisagé pour un pool de 35 cartes, rendu caduc par le passage à 120). Vigilance : 3-of sur 30 cartes = très forte consistance. Les combos à deux cartes sont bien plus fiables qu'en Hearthstone.
D-06 · Trois types de cartes : Créature / Sort / Permanent
Écarté : faire des permanents un sous-type de sort (moins lisible en code comme pour le joueur) ; armes et équipements (doublent les règles de combat) ; terrains ; cartes-héros alternatives.
D-07 · Mot-clé « Fougue » plutôt que « Charge »
Écarté : Charge (attaquer le héros dès l'arrivée). Raison : transforme n'importe quel buff en dégâts directs incontrables et rend les combos létales inanticipables. Fougue (attaquer une créature seulement) en garde 90 % de la sensation. Si un effet Charge est souhaité un jour, une seule légendaire.
D-08 · « Piège / Secret » reporté en extension
Raison : exige un système de priorité au milieu de la résolution adverse, et une information cachée dont l'existence est publique — risque réel de fuite via l'API, et opacité pour un débutant. Le système trigger + condition permet de l'ajouter plus tard sans refonte.
D-09 · Héros = un vrai personnage WoW du joueur
Contraintes fermes :
- Aucune donnée de puissance en jeu (ilvl, hauts faits, score M+, progression raid) — cosmétique uniquement, sinon les raiders écrasent les casuals et l'objectif social est mort.
- La race est cosmétique (un bonus racial forcerait le choix et viderait de son sens le « c'est mon perso »).
- Snapshot à la liaison : transferts, renommages et suppressions cassent les liens Battle.net.
- Duel amical = toute classe libre ; tournoi = perso réel. Évite le mur du reroll.
D-10 · Terrain non ordonné en v1
Conséquence à respecter : aucune carte « adjacent » ou « à gauche/droite » dans le set de lancement. Le champ position existe, nullable. Ajouter le positionnement plus tard est indolore côté données, coûteux côté UI.
D-11 · Set de lancement de 120 cartes
Écarté : 35 cartes (deckbuilding illusoire, collection complétée en trois semaines, Sceaux sans usage). Méthode de production : designer par cycles (un effet décliné sur plusieurs coûts — 10 à 12 cycles couvrent la moitié du set) et par archétypes (4 × ~20 cartes + 40 flexibles). Règle de coupe : si le set est trop gros, couper en haut de courbe. L'erreur systématique des sets maison est le sommet trop lourd.
D-12 · Sous-types à deux axes : rang × rôle
Rangs (hiérarchie réelle de la guilde, vouée à évoluer) : Disciple · Membre · Champion · Conseiller · Haut Conseiller. Rôles : Tank · Soigneur · DPS · Artisan. Non-membres : Boss · Monstre · Mascotte · PNJ.
Écarté : les tags PUG et CASU — les seuls de la liste initiale lisibles comme des piques. Les créatures non-membres couvrent déjà le besoin de remplissage sans viser personne.
Implémentation : les rangs sont une table de configuration, jamais une enum. Deux champs distincts — rankId (référence vivante, pour les synergies) et rankLabel (texte figé à l'impression). Si un rang est renommé, les cartes publiées gardent leur libellé : c'est de l'histoire de guilde, pas une donnée à rafraîchir.
D-13 · Le rang détermine le coût, pas la rareté
| Rang | Coût |
|---|---|
| Disciple | 1-3 |
| Membre | 3-5 |
| Champion | 4-6 |
| Conseiller | 5-8 |
| Haut Conseiller | 7-10 |
Écarté : faire corréler aussi le rang avec la rareté. Coût et rareté sont deux axes indépendants ; les lier tous deux au rang interdirait à jamais une légendaire à 2 Ferveur ou une commune à 8. La rareté reste libre — un Disciple peut être légendaire.
Bénéfice : les synergies tribales de rang sont automatiquement cohérentes avec la courbe.
D-14 · Deux légendaires par set
Chaque extension en apporte deux nouvelles. Peu de légendaires les rend désirables, et cela étale l'honneur sur plusieurs années au lieu d'avoir à justifier un classement d'entrée.
D-15 · Évolution des membres entre extensions
Le rang imprimé est un instantané daté. « Kaelis, Disciple » (set 1) reste un Disciple ; le set 3 peut ajouter « Kaelis, Conseiller ».
Trois règles :
- La carte évoluée ne domine jamais strictement l'ancienne — coût supérieur, rôle différent dans la courbe. Sinon c'est du power creep et l'ancienne meurt.
- Les deux versions coexistent légalement dans un deck (et peuvent synergiser entre elles).
- Champ
evolutionOfdans le modèle → affichage « historique de ce membre » sur le site.
D-16 · Numérotation façon Magic
Nom d'extension · code à 3 lettres · symbole · numéro de collection (042/120) · cadre par set. Le numéro de collection est le déclencheur de collectionnite le plus efficace : on ne possède plus « des cartes », on possède « 87 / 120 ». Couleurs de rareté : qualité d'objet WoW (gris / vert / bleu / violet / orange) — zéro apprentissage.
D-17 · Classes/factions reportées, mais préparées
Règle future : deck = cartes neutres + cartes de la classe du héros. Champ factions[] (tableau, pas chaîne) dès maintenant.
Le piège majeur : ne pas brûler les identités mécaniques dans le pool neutre. Si la résurrection, la contre-magie, le vol de créature et le burn de zone sont déjà neutres, il ne reste rien pour le Prêtre ou le Mage. Le pool neutre fait des choses génériques ; tout le reste part dans 03-backlog-classes.md.
D-18 · Ordre de développement : schéma → générateur → moteur
Raison : le générateur de cartes est la brique la moins risquée, la plus rapide à livrer, la seule qui produit de l'attente avant que le jeu existe, et il débloque le prototypage de mécaniques sur table (cartes imprimées, zéro moteur).
D-19 · Multi-prototypes : l'actif durable est la donnée
Schéma, corpus et kit de conformité vivent dans data/, en JSON pur, indépendants de toute stack. Un prototype est fonctionnel quand il passe le kit. Discipline : un prototype = une variable. Changer la stack et les mécaniques en même temps n'apprend rien. Séparer prototype de mécanique (cartes imprimées, vraie table) et prototype technique (moteur + client minimal).
D-20 · Cartes « Enluminées » (shiny) — cosmétique, non achetables
Nom retenu : Enluminée. Registre du manuscrit médiéval, cohérent avec Le Grand Conseil. Écarté : Dorée (vocabulaire Hearthstone, mais §10 réservait déjà « doré » à autre chose) ; Brillante (compris de tous mais plat) ; Scellée / Sceau d'or (collision sémantique avec la monnaie Sceaux, que D-03 s'attache justement à éviter).
Quatre règles fermes :
- Rigoureusement cosmétique — aucune stat, aucun effet, aucun bonus, y compris hors partie. Application directe de D-09 : ni la chance ni l'ancienneté ne doivent peser sur une partie. Écarté : un micro-bonus méta (gain de Sceaux, badge chiffré) — il transformerait l'enluminure en objectif de farm.
- Propriété de l'exemplaire, pas de la carte — même
id,versionetcollectorNumber. Écarté : une entrée de collection séparée, qui doublerait le corpus à 240 entrées et obligerait à appliquer chaque nerf deux fois. - Compte comme une copie normale pour les limites de deck (D-05).
- Ne s'achète pas — drop en pack (~5 %, pity 10 packs) et récompense d'événement uniquement. Écarté : le craft en Sceaux, pourtant tentant comme puits (une enluminée doit dire « j'ai eu de la chance » ou « j'étais là », jamais « j'ai payé ») ; et l'attribution automatique de sa propre carte-membre (décorer 100 % des membres ne signale rien).
Conséquence d'architecture : le moteur ne voit jamais foil — absent de l'état de partie, du kit de conformité et du seed RNG. Simple option de rendu. Un replay rejoué sans les données d'enluminure doit produire la partie identique.
Deux pièges :
- Le taux de drop est un bouton à sens unique : on peut le monter, jamais le baisser sans dévaluer les enluminées déjà distribuées.
- Pas d'échange entre membres : un marché interne rendrait les Sceaux spéculatifs et réintroduirait le pay-to-win exclu par §10.
Puits de Sceaux inchangé : les alt-arts IA restent le sink infini. L'alt-art se choisit, l'enluminée se gagne — les deux cohabitent sans se cannibaliser.
P0 — décisions de schéma
Les sept entrées suivantes ont été prises en écrivant data/schema/. Elles précisent ou corrigent §8.1 de la spec, qui donnait un modèle indicatif et non un schéma exécutable.
D-21 · Identifiants techniques en anglais, libellés en français
Clés JSON et valeurs d'enum en anglais (cost, atk, hp, keywords: ["TAUNT"], subtypes: ["CRAFTER"]). Les libellés français vivent dans data/schema/taxonomy.json et dans les champs de texte (name, flavor, rulesText, text de capacité).
Écarté : les enums en français, et a fortiori les clés en français. §8.1 utilisait déjà TAUNT : le mélange serait devenu permanent. Séparer identifiant technique et libellé rend en outre un futur i18n indolore, et permet de renommer un rôle sans toucher au corpus.
Conséquence : aucune chaîne française en dur dans un prototype. Le générateur (P1) lit ses libellés dans taxonomy.json.
D-22 · Versioning : un fichier par version
Convention de nommage : <id>.v<version>.json — crea_gorak_forgeron.v1.json. L'id est la lignée, stable ; la version est le tirage. Champs supersedes et changeNote, ce dernier obligatoire dès la version 2.
Écarté : une version courante écrasée avec un dossier archive/ (deux chemins de chargement) ; un tableau versions[] dans un fichier unique (fichiers qui gonflent, schéma alourdi).
Raison : le diff git est explicite, et un moteur peut charger une version arbitraire pour rejouer un replay d'époque — c'est exactement ce que la règle d'architecture 5 achète.
D-23 · Une capacité porte une SÉQUENCE d'effets
{ trigger, condition, effects: [ {action, target, params, condition}, … ] }, exécutés dans l'ordre.
Écarté : le modèle de §8.1 (une action par capacité). « Infliger 4 dégâts et piocher une carte » aurait exigé deux capacités ON_PLAY empilées, avec un ordre de résolution implicite et une condition dupliquée.
Bénéfice imprévu : la condition au niveau de l'effet résout « 1 dégât ; 3 dégâts si vous avez 8+ Ferveur » (pouvoir de l'Évocateur) par deux effets à conditions inversées, sans action DEAL_DAMAGE_CONDITIONAL ni code spécifique.
D-24 · Le rang sort de subtypes
§6.1 plaçait le rang à la fois dans subtypes: ["DPS", "CHAMPION"] et dans rankId/rankLabel. Le rang ne vit désormais que dans rankId (référence vivante) + rankLabel (libellé figé). subtypes ne porte que le rôle (membres) ou le type non-membre (BOSS, MONSTER, PET, NPC).
Raison : une même information en deux endroits finit toujours par désynchroniser — et ici l'un des deux (subtypes) était une enum figée, l'autre (rankId) une table de configuration vouée à changer. Le DSL de ciblage expose les deux axes séparément : filter.hasSubtype et filter.hasRank.
D-25 · L'extension n'est référencée que par son id
Une carte stocke set: "set_01" et rien d'autre. Le nom, le code à 3 lettres, le symbole, le cadre et la composition cible vivent dans data/schema/sets.json.
Écarté : dupliquer setCode sur chaque carte comme le suggérait §7.5.
Raison : le nom de l'extension de lancement n'est pas tranché. Le décider — ou le changer — ne doit pas réécrire 120 fichiers.
D-26 · GAIN_MANA renommée GAIN_FERVOR, avec un mode
L'action porte { amount, mode } où mode vaut CURRENT (alimente ferveurActuelle sans toucher au plafond) ou MAX (relève ferveurMax).
Raison : « mana » n'existe pas dans le vocabulaire du jeu (D-03). Surtout, la distinction CURRENT/MAX est exactement celle que D-04 impose pour l'avantage du second joueur : elle devait être dans le modèle, pas dans une exception du moteur.
D-27 · La durée AURA est imposée par le schéma
duration vaut PERMANENT, END_OF_TURN ou AURA. Le schéma exige AURA dès que le déclencheur est CONTINUOUS, et l'interdit partout ailleurs.
Raison : c'est la règle d'architecture 4 rendue mécaniquement invérifiable à contourner. Un moteur qui appliquerait un buff d'aura comme une mutation de stats stockées laisserait des créatures buffées après la disparition de la source — le bug qui tue les moteurs de TCG maison. La donnée ne peut plus exprimer ce cas : deux fixtures négatives (invalid_aura_hors_continuous, invalid_continuous_sans_aura) le vérifient à chaque exécution.
D-28 · Un dossier tools/ en Node, hors de l'actif durable
data/ reste 100 % JSON pur. tools/ contient validate.mjs (ajv) et lint.mjs (règles arithmétiques et globales). Ce dossier est jetable et remplaçable ; data/ ne l'est pas.
Raison : JSON Schema ne sait pas faire d'arithmétique. Le budget de stats (ATK + PV = 2 × coût + 1), la fourchette de coût par rang (données dans un autre fichier), l'unicité des numéros de collection, la limite de deux légendaires et l'intégrité des références entre cartes ne sont vérifiables qu'en code. Sans ce linter, chacune de ces règles est une discipline humaine qui cède au bout de 40 cartes.
Bloc design : les cartes portent un objet design (abilityBudget, effectPoints, archetype, cycle, vanilla, notes) qui sert la comptabilité d'équilibrage. Le moteur l'ignore — il n'entre ni dans l'état de partie ni dans le kit de conformité, même règle que le cosmétique (D-20).
Lacunes de règles révélées par P0
Six trous que l'écriture du schéma a mis au jour. Tranchés avant P1 plutôt que reportés en P2 : trois d'entre eux changeaient la définition d'un pouvoir héroïque, et deux la façon d'écrire les cartes. La spec est amendée en v1.1 en conséquence — ce ne sont pas des corrections contre elle mais des précisions qu'elle ne portait pas.
D-29 · Le héros est passif : il n'attaque jamais (v1)
Le héros n'a pas de caractéristique d'attaque, ne se déclare jamais attaquant, et ne peut pas recevoir de mot-clé. Il ne blesse l'adversaire que par ses créatures, ses sorts et son pouvoir héroïque.
Écarté : le héros attaquant à la façon de Hearthstone. Il aurait fallu trancher le malaise d'invocation héroïque, l'attaque par tour, les dégâts en retour, l'interaction avec Provocation, et l'affichage d'une valeur d'ATK sur un portrait — soit un second système de combat pour un gain de profondeur faible.
Conséquences immédiates :
- Les pouvoirs du Druide (« +1 ATK et 1 Armure ») et du Chasseur de démons (« +1 ATK ») ne faisaient plus rien. Redessinés en « Croissance » (une créature alliée gagne +1/+1) et « Métamorphose » (1 Ferveur : 1 dégât à une créature). Le Chasseur de démons reste le seul pouvoir à 1 Ferveur ; le Druide frôle désormais le Moine, et c'est le maillon faible de la liste — à re-différencier au prochain jet.
- Le schéma interdit
BUFF,SET_STATSetGRANT_KEYWORDsurkind: HERO(et surANY, qui pourrait le résoudre). Les seules actions autorisées sur un héros sontDEAL_DAMAGE,HEALetGAIN_ARMOR. La donnée ne peut plus exprimer une règle qui n'existe pas — fixtureinvalid_buff_sur_heros. - L'identité druidique du backlog (choix entre deux effets, accélération de Ferveur) n'est pas dépensée pour boucher le trou : elle reste réservée à l'extension. Une accélération de Ferveur répétable sur un pouvoir héroïque atteindrait le plafond de 10 immédiatement, de toute façon.
Réversible : rendre le héros actif plus tard est une extension (armes, cartes-héros), pas une migration. L'inverse ne l'aurait pas été.
D-30 · Un seul choix de cible par capacité
Dans une même capacité, tous les sélecteurs de scope CHOSEN partageant le même couple (side, kind) désignent la même entité. Le joueur choisit une fois, au début de la résolution, et ce choix vaut pour toute la séquence.
Écarté : un scope PREVIOUS_TARGET explicite. Il aurait permis d'exprimer la même chose deux fois dans la donnée — donc de l'exprimer de façon ambiguë. Une règle générale vaut mieux qu'un mot-clé optionnel qu'on oublie.
Conséquence : « +0/+2 et Provocation » (pouvoir du Moine) touche forcément la même créature. Deux couples (side, kind) distincts dans une même capacité provoquent bien deux invites successives : c'est légal, mais assez rare pour que lint.mjs le signale en avertissement.
Scénario de conformité obligatoire : une capacité à deux effets CHOSEN dont la cible meurt entre le premier et le second effet. Le second doit être perdu, pas redirigé.
D-31 · Les seuils de Ferveur lisent ferveurMax
« Si vous avez 8 Ferveur ou plus » signifie « si votre plafond est à 8 ». La condition est nommée FERVOR_MAX_AT_LEAST pour qu'aucun moteur ne puisse se tromper : le nom porte la sémantique.
Écarté : lire ferveurActuelle. Trois raisons — le seuil ne dépendrait plus que de l'ordre de jeu dans le tour (« lance ce sort avant de dépenser »), ce qui est une contrainte cachée ; le +1 temporaire du second joueur pourrait franchir un seuil un tour trop tôt, alors que D-04 s'attache justement à ce que cet avantage reste sans conséquence structurelle ; et le joueur devrait calculer au lieu de lire son plafond affiché.
Conséquence : les 3 dégâts de l'Évocateur arrivent au tour 8 et ne repartent jamais. C'est un pouvoir qui change de nature en fin de partie — l'effet voulu.
D-32 · Aucun dégât de zone dans le pool neutre
Toute forme d'AoE, même modeste, est réservée aux classes. tools/lint.mjs refuse tout DEAL_DAMAGE frappant plusieurs créatures adverses sur une carte NEUTRAL (scope ALL, ou count > 1).
Écarté : l'AoE modeste en neutre, que §7.3 prévoyait pourtant dans l'archétype Contrôle du set de lancement. La contradiction avec 03-backlog-classes.md est tranchée en faveur du backlog : une fois l'AoE générique installée, le Mage et le Chaman n'ont plus rien de distinctif à dire, et c'est l'erreur qui rend une extension de classes décevante (D-17).
Le prix, assumé et à surveiller : le Contrôle du set de lancement n'a plus de réponse propre à un terrain large, face à un archétype Agro/large qui existe explicitement. Soupapes de rechange : corps à Provocation à forte endurance, créatures Létal, permanents à Rituel infligeant 1 dégât à une créature adverse aléatoire (répétable mais mono-cible, donc hors du domaine réservé), renvoi en main ciblé.
Condition de révision, fixée d'avance : si l'agro large domine au premier test de table, on ouvre un AoE neutre volontairement faible et cher (1 dégât à toutes les créatures à 4 Ferveur), on n'attend pas l'extension.
D-33 · Invocation sur terrain plein : les surnuméraires sont perdus
Les invocations se résolvent une par une. Si le terrain est plein au moment de placer une créature, elle n'apparaît pas et l'effet continue. La carte reste jouable même terrain plein.
Écarté : refuser l'invocation, ou refuser de jouer la carte. Il aurait fallu définir par carte le nombre de places nécessaires à sa légalité, et certaines cartes seraient devenues injouables sans raison lisible pour le joueur.
Raison : le joueur voit ce qu'il perd, donc c'est un choix de timing et non un piège. Et c'est la règle la moins chère à implémenter correctement.
Conséquence : Convocation générale n'invoque qu'un Disciple s'il ne reste qu'une place. Scénario de conformité obligatoire, avec sa variante inverse : une invocation qui libère une place en cours de séquence (le premier jeton meurt d'un Râle d'agonie enchaîné) doit-elle permettre au second d'arriver ? Oui — l'état est réévalué à chaque placement, jamais en amont.
D-34 · Étalon de valeur d'effet : 1,5 × coût + 1
Remplace le taux linéaire de 2,5 points d'effet par Ferveur du premier jet, pour les sorts et les permanents. Détail et table de conversion en §9.1 de la spec.
Deux raisons :
- Le sommet devenait absurde. 2,5 × coût autorisait 20 points d'effet à 8 Ferveur. L'efficacité par unité de ressource décroît en haut de courbe dans les TCG qui tiennent : une carte chère arrive tard et doit déjà mériter son tour. Une formule affine reproduit cette décroissance, une formule linéaire ne peut pas.
- Les cartes écrites à l'instinct contredisaient systématiquement l'ancien étalon — 60 à 72 % de la cible. Elles atteignent 75 à 109 % de la nouvelle. Quand la règle contredit systématiquement le jugement, c'est presque toujours la règle qui a tort.
Non bloquant, et volontairement. Le linter rapporte l'écart avec une tolérance de 70 à 115 %, mais n'échoue jamais dessus : l'échantillon est de quatre cartes. Le budget de caractéristiques des créatures, lui, reste bloquant — il est vérifié, pas estimé. Le premier test de table sur cartes imprimées tranchera (§13.3).
Garde-fou conservé : un sort ne doit jamais dominer une créature de même coût sur la puissance immédiate. À 3 Ferveur, une créature reçoit 7 points de caractéristiques et un corps qui persiste ; un sort reçoit 5,5 points consommés d'un coup. L'écart paie la permanence.
Publication
D-35 · Le site de documentation est le même projet que P1, dans le même dépôt
La documentation devient consultable en ligne, avec navigation et recherche, dans le même site que le générateur de cartes. Un seul dépôt, un seul build, un seul déploiement.
Le site est un rendu, jamais un stockage
docs/*.md reste la source de vérité et ne bouge pas. Le site les affiche, il ne les héberge pas.
Écarté : un wiki au sens outil — GitHub Wiki, Notion, Wiki.js, Outline. Tous stockent le contenu chez eux, ce qui crée une seconde source de vérité et impose un mécanisme de synchronisation. Ces mécanismes se dégradent, et le jour où les deux côtés divergent, plus personne ne sait lequel fait foi.
C'est aussi une régression pour le travail avec un agent, qui est un critère explicite du projet : des fichiers markdown versionnés sont le meilleur format possible — lisibles, cherchables, diffables, avec l'historique et le motif de chaque changement dans git. Un contenu en base de données n'est pas accessible sans passer par une API.
Un seul dépôt, pour la donnée avant la doc
Écarté : un dépôt séparé synchronisé.
La raison n'est pas le confort mais data/. Le générateur lit taxonomy.json, ranks.json, sets.json et tout data/cards/. Dans le même dépôt, c'est un import relatif et une carte ajoutée apparaît au build suivant. Dans un dépôt séparé, il faut un sous-module git ou un paquet npm à republier à chaque carte — le problème de synchronisation réapparaît sur l'actif durable, ce qui est bien pire que sur la documentation.
site/ a le même statut que tools/ : jetable et clôturé
Il lit docs/ et data/, il n'écrit jamais, il ne contient aucun contenu propre. Le test : si le supprimer fait perdre une information, il est cassé et il faut remonter le contenu dans docs/ ou data/.
README.md et CLAUDE.md restent à la racine, hors du site : ils s'adressent au dépôt et à l'agent, pas aux lecteurs.
Stack : VitePress
Écarté : Astro (plus flexible, mais navigation et recherche à construire) ; MkDocs Material (superbe en doc, hostile à une application interactive) ; Docusaurus (plus lourd, orienté doc produit versionnée).
Raison : VitePress génère la navigation, la recherche plein texte et le sommaire directement depuis les fichiers markdown existants, sans configuration — c'est exactement la demande. Et comme il repose sur Vue, le générateur de cartes s'y intègre en page applicative de plein droit plutôt qu'en greffon.
Réversibilité : le jour où le générateur devient l'essentiel et la doc une simple section, changer de socle ne coûte que le socle. Les fichiers markdown et data/ ne bougent pas — c'est précisément à ça que sert la séparation actif durable / code jetable (D-19).
Ce que le site apporte que le markdown ne peut pas
La galerie des 120 cartes rendues, la complétion (« 87 / 120 · dont 12 enluminées »), la courbe du set calculée en direct depuis data/, le glossaire cherchable, la bascule normale / enluminée. C'est là qu'est la valeur produit : les membres voient leur carte des mois avant que le jeu existe (D-18).
Site statique, donc hébergeable n'importe où, y compris en sous-domaine de guilde-lgc.fr. Il n'a rien à voir avec le service stateful qu'imposera le duel en temps réel (P3) et ne préempte pas cette décision.