171 lines
16 KiB
Markdown
171 lines
16 KiB
Markdown
Fiche CG2-CART-01 — Niveau N3 — Modèle prévu opus xhigh | utilisé claude-opus-5-5 — Session Medium-xHigh · CG2 — Skills demandés lp-lot, sk-orchestrate, sk-protocol (gabarits CART et TACHES relus dans `lp-doc\gabarits.md`)
|
||
# CG2-CART-01 : défauts du générateur de personnage, périmètre de la build 1 (2026-10-19)
|
||
|
||
Lot CG2, tâche F1 de `Docs\37_Feuille_De_Route_Alpha2.md` § 1.1 et § 3. Lecture de fichiers seulement : aucune copie UE,
|
||
aucun MCP, aucun code ni git écrit. Règle de publication (doc 27, PUB1 / PUB2) : ce livrable ne cite aucun contenu ; les
|
||
noms de régions et de champs réservés restent dans le référentiel de l'addon.
|
||
|
||
## 1. Objet et périmètre
|
||
|
||
Objet : dresser la liste des défauts relevés par l'audit du générateur de personnage (CharGen), dire où ils se trouvent,
|
||
leur coût de correction et ce qui tient dans la build 1 (alpha 2026.10.2.2a, IMPL au J2).
|
||
|
||
Sources lues :
|
||
- **R04** : `D:\Game\LifePlay-Sandbox-5.8\Docs\CG\REF\04-defauts\04-defauts.md` (D1 à D29).
|
||
- **R06** : `…\REF\06-rapport-audit\06-rapport-audit.md` (§ 3 faiblesses, § 5.4, § 5.5 décisions de l'utilisateur du
|
||
2026-10-16).
|
||
- `…\REF\README.md` et `CONTEXT.md` (trous non lus).
|
||
- **H3i** : `etat\ST\STE\STE-H3i-DIAG.md` (378 Accessed None `chargen`).
|
||
- Code C++ du module de l'addon : `D:\Game\LifePlay-Sandbox-5.8\Plugins\LPSandbox\Source\LPSandbox\LPSandboxCharGenMod.cpp`.
|
||
- Registre `CGREF1-TACHES.md` de l'addon (T74 à T78 : onglet Shape livré, rien sur le format).
|
||
|
||
## 2. Commandes et lectures (compte brut)
|
||
|
||
- `cat` de R04 (29 défauts : D1-D17 § 1.1, D18-D24 § 1.2, D25-D29 § 1.3) et de README, CONTEXT.
|
||
- `awk` sur R06 § 3 (9 faiblesses) et `sed` sur R06 § 5.3 à § 5.5 (4 décisions).
|
||
- `sed -n '1,80p'` sur H3i (verdict § 4 : 378 occurrences, une par `VisualMorph` construit).
|
||
- `grep -n` sur `LPSandboxCharGenMod.cpp` : 2987 lignes ; `CharGenFilePath` l. 1697-1704, `SaveCharacter` l. 1706-1729,
|
||
`LoadCharacter` l. 1731 et suivantes.
|
||
- `grep` sur `CGREF1-T3c-MCP.md:19, :58` : `LoadDefaultTextures` est dans `GI` (`EventGraph:CustomEvent_96`).
|
||
- `ls` de `Content\UI\` et `Content\BPs\` (copie 5.8) : `CharGen`, `CharGenSlider`, `VisualMorph`, `BodyShapeMenu`, `Preset`,
|
||
`GI`, `Person` et `PC` sont présents en `.uasset`.
|
||
|
||
## 3. Constats : liste numérotée des défauts
|
||
|
||
Légende :
|
||
- **Où** : `BP` = Blueprint du jeu (`Content\…`, dépôt du jeu) ; `C++` = module de l'addon.
|
||
- **Effort** : S ≤ 30 min de MCP (quelques nœuds, compilation, relecture) ; M 0,5 à 2 h ; L > 2 h.
|
||
- **Besoin** : `MCP-É` = écriture MCP (lp-mcp-bp, instantané) ; `MCP-L` = lecture MCP ; `build` = compilation C++ ;
|
||
`déc.` = décision avant correction.
|
||
- **Build** : B1 (alpha 2026.10.2.2a), B1 opt. (si le créneau UE le permet), B2 (2026.11.3.1a), ou rien / hors lot.
|
||
|
||
| # | Source | Symptôme | Cause présumée | Où | Gravité | Effort | Besoin | Build |
|
||
|---|---|---|---|---|---|---|---|---|
|
||
| 1 | D1 R04 | aucun en jeu : broches `StatOnly` / `IncludeStat` d'entrée non reliées | relecture de variables homonymes | BP `GI.SavePreset` | information | S | MCP-É | B2 |
|
||
| 2 | D2 R04 | garde de fin de chemin jamais vraie | littéral à antislash, chemins en `/` | BP `GI.SavePreset` | faible | S | MCP-É, déc. (rôle de la garde) | B2 |
|
||
| 3 | D3 R04 | trace de débogage morte | reste de débogage | BP `GI.SavePreset` | faible | S | MCP-É | B1 opt. |
|
||
| 4 | D4 R04 | le nom saisi devient un chemin : `..` ou sous-dossier acceptés, écriture hors de `Modules` possible | aucune normalisation | BP `GI.SavePreset` ← `CharGen.FilenameEntry` | moyenne | M | MCP-É, déc. (règle du nom) | B1 opt. |
|
||
| 5 | D5 R04 | `MaxValue` d'un champ de variance non protégé contre 0 (lien ERR-057) | non lu | BP `CharGen` | incertain | S | MCP-L d'abord | B2 |
|
||
| 6 | D6 R04 | Accessed None `GI` du journal dans `SpinBox_0`, alors que le graphe le garde | journal antérieur ou autre nœud | BP `CharGen.SpinBox_0` | faible | S | contrôle en jeu, avec n° 18 | B1 (contrôle) |
|
||
| 7 | D7 R04 | `SetMorphTarget` appelé deux fois par composant | reste ; branche morte | BP `Person.setMorphTarget` | faible | S | MCP-É, mesure (chemin chaud) | B2 |
|
||
| 8 | D8 R04 | conflits de morphs résolus sur le corps seul ; à égalité, « Max » annulé | conception | BP `GI.ResolveConflictingMorphs` | information | — | déc. | B2 / rien |
|
||
| 9 | D9 R04 | tirage sans alternative retenue : morph remis à 0 au lieu de laissé (62 lignes du corpus) | pas de cas par défaut ; câblage établi par CGREF1-T7 | BP `GI` (application des valeurs) | moyenne | M | déc. de l'utilisateur (R06 § 5.5 n° 2), MCP-É | B2 |
|
||
| 10 | D10 R04 | `BlendPreset` retient le premier fichier qui finit par `<nom>.lpcharacter` (collision `x` / `ax`) ; `Split` sans garde | recherche par suffixe | BP `GI.BlendPreset` | faible | M | déc., MCP-É | B2 |
|
||
| 11 | D11 R04 | `SavePerson` n'écrit rien si l'emplacement vaut 0 ou moins | voulu (estimé) | BP `GI.SavePerson` | information | — | — | rien |
|
||
| 12 | D12 R04 | `StatOnly` sans effet au chargement | trace morte | BP `GI.LoadPreset` | information | S | MCP-É | B2 |
|
||
| 13 | D13 R04 | la superposition ne remet pas à zéro | voulu (R06 § 1.3) | BP `GI.LoadPreset` | information | — | — | rien |
|
||
| 14 | D14 R04 | coiffure introuvable : échec muet | sortie d'échec non reliée | BP `Person.setBHairstyle` | faible | S | MCP-É (journaliser) | B2 |
|
||
| 15 | D15 R04 | ancienne implémentation morte | reste | BP `Person.setTattoo` | faible | S | MCP-É | B2 |
|
||
| 16 | D16 R04 | six remises à zéro d'étiquettes d'origine codées en dur | liste fermée | BP `Person.saveEthnicity` | faible | L | déc. 4 (R06 § 5.5 : pas dans ce lot) | hors lot |
|
||
| 17 | D17 R04 | texture par défaut absente du registre : non chargée, sans message | `bIncludeOnlyOnDiskAssets = true`, aucun journal | BP `GI.LoadDefaultTextures` | moyenne | S | MCP-É (journaliser) | B2 |
|
||
| 18 | D18 R04 | à chaque changement du réglage anti-déformation : morph fixe appliqué et texte de débogage **à l'écran** | reste de débogage | BP `CharGen.SpinBox_0` | faible, visible | S | MCP-É, déc. (n° 18 Q1) | B1 |
|
||
| 19 | D19 R04 | « Hello » + valeur **à l'écran** 2 s à chaque mouvement d'un curseur | reste de débogage | BP `CharGenSlider.MorphSlider` | faible, visible | S | MCP-É | B1 |
|
||
| 20 | D20 R04 | `Construct` : personnage édité lu sans `IsValid` ; échec du cast vers `GI` non relié | garde absente | BP `CharGen.Construct` | moyenne | S | MCP-É | B1 |
|
||
| 21 | D21 R04 | liste de préréglages : entrée vide si chemin sans `Content/` ; doublons si appel répété | `Split` non testé ; liste non vidée au début | BP `CharGen.PopulatePresets` | faible | S | MCP-É | B1 opt. |
|
||
| 22 | D22 R04 | en mode constructeur, le clic d'un préréglage ne transmet ni `Blend` ni `StatOnly` | deux comportements selon le mode | BP `Preset` | faible | M | déc. | B2 |
|
||
| 23 | D23 R04 | curseur de morph : `PlayerCharacter` lu sans `IsValid`, Accessed None à chaque mouvement | garde absente | BP `CharGenSlider.MorphSlider` | moyenne | S | MCP-É | B1 |
|
||
| 24 | D24 R04 | `Map.Find` non testé ; tous les types non-texture classés en un seul | conception | BP `Person.getMidsAndParameter` | information | S | MCP-É (journaliser) | B2 |
|
||
| 25 | D25 R04 | 8 boutons (`Randomize*`, `ChangeAnimal`, `ChangeBreed`) : personnage édité lu sans `IsValid`, Accessed None à chaque clic | garde absente (même motif que n° 20) | BP `CharGen` | moyenne | M | MCP-É, déc. (n° 25 Q6) | B1 |
|
||
| 26 | D26 R04 | fin de liste des races animales : retour à l'index 2 au lieu de 0 ; hors limites si moins de 3 entrées | broche `B` non reliée (littéral 2) | BP `CharGen` (`ChangeBreed`) | faible | S | MCP-É | B1 |
|
||
| 27 | D27 R04 | nœuds orphelins (`ShowTutorial`, `PrintString`) | reste | BP `GI` | faible | S | MCP-É | B1 opt. |
|
||
| 28 | D28 R04 | l'action d'ouverture du générateur ne fait rien et ne dit rien hors de ses conditions | conception | BP `PC` | information | S | déc. | B2 |
|
||
| 29 | D29 R04 | `SwitchEnum` sans sortie ; saisie au clavier sans effet tant qu'une porte reste fermée | reste ; conception | BP `CharGenSlider.MorphSpin` | information | S-M | MCP-L (appelants de `UnlockSpinChange`) | B2 |
|
||
| 30 | H3i § 4 | 378 Accessed None `chargen` à l'ouverture du menu de forme du corps sans passage par CharGen ; curseurs à 0 | `VisualMorph` lit `GI.CharGen` sans garde ; `GI.CharGen` vaut None tant que CharGen n'a pas été ouvert, jamais remis à None | BP `VisualMorph` (+ `GI`) | moyenne | M | MCP-L (nœud exact, non dumpé) puis MCP-É, déc. (n° 30 Q2) | B1 |
|
||
| 31 | R06 § 3.8 | « inclure les stats » : relecture puis seconde écriture du même fichier | conception | BP `CharGen` → `GI.SavePreset` | faible | M | déc. | B2 |
|
||
| 32 | R06 § 3.8 | `ReadLine` sans branche d'erreur : 2 lignes mal formées du corpus lisent l'indice 1 d'un tableau d'un élément | pas de validation (effet estimé, non rejoué) | BP `GI.ReadLine` | faible | S | MCP-É, essai | B2 |
|
||
| 33 | R06 § 5.4, § 5.5 n° 1 | la Sandbox écrit un `.lpcharacter` « V8 » que le jeu ne lit pas ; décision : écrire le format du jeu | format propre au module | C++ `LPSandboxCharGenMod.cpp:1697-1800` (`CharGenFilePath`, `SaveCharacter`, `LoadCharacter`) | moyenne | L (≈ 1 j : écrivain et lecteur de la grammaire `CATÉGORIE Clé: p% valeur`, correspondance des champs, essais) | build C++ (jeton UE pour compiler), pas de MCP | B2 (n° 33 Q4) |
|
||
| 34 | R06 § 5.5 n° 3 | Sandbox : enregistrement limité à `Saved\Chargen` ; décision : l'utilisateur choisit l'endroit | conception | C++ `CharGenFilePath` (l. 1697-1704) | faible | M-L | build C++, déc. (forme du choix en jeu empaqueté) | B2 |
|
||
|
||
Hors défaut, consignés pour mémoire :
|
||
|
||
| # | Source | Sujet | Où | Suite |
|
||
|---|---|---|---|---|
|
||
| 35 | R06 § 3.4, § 5.5 n° 4 | listes fermées : races, corps et textures par défaut dans des valeurs de Blueprint | BP `GI`, `Person` | décision de l'utilisateur : ouvrir petit à petit, pas dans ce lot (hors lot) |
|
||
| 36 | R06 § 3.9 | une clé fautive ne se distingue pas d'une clé rare (aucun schéma) | données, outillage | outil de contrôle hors jeu : B2, sans jeton UE |
|
||
| 37 | README « Trous » | graphes non lus : `FinalPage`, `ReturnFromChargen`, `GeneratePerson`, corps des `Randomize*`, widget d'un curseur de région réservée, `DuplicateCharacters` | BP `CharGen`, `GI`, `Person` | MCP-L en B2 ; ils peuvent cacher d'autres défauts |
|
||
|
||
### 3.1 Comptes
|
||
|
||
| Gravité | Défauts | Numéros |
|
||
|---|---|---|
|
||
| moyenne | 8 | 4, 9, 17, 20, 23, 25, 30, 33 |
|
||
| faible | 17 | 2, 3, 6, 7, 10, 14, 15, 16, 18, 19, 21, 22, 26, 27, 31, 32, 34 |
|
||
| information | 8 | 1, 8, 11, 12, 13, 24, 28, 29 |
|
||
| incertain | 1 | 5 |
|
||
| **total** | **34** | (+ 3 sujets hors défaut, n° 35 à 37) |
|
||
|
||
Où : 32 en Blueprint du jeu (30 dans `GI`, `CharGen`, `CharGenSlider`, `Person`, `Preset`, `PC`, plus 2 qui touchent
|
||
`VisualMorph` et le couple `CharGen` → `GI`) ; 2 en C++ de l'addon (n° 33, 34) ; aucun en données seules.
|
||
|
||
### 3.2 Dépendances
|
||
|
||
- **Jeton UE** : toutes les corrections B1 sont des écritures MCP dans la copie 5.8 (instantané des `.uasset` d'abord) ;
|
||
aucune ne demande de compilation C++.
|
||
- **n° 30** : il faut d'abord un dump ou un `find_nodes` de `VisualMorph` pour le nœud exact (H3i § 5), dans la même
|
||
session MCP, avant l'écriture.
|
||
- **n° 20 avant n° 25** : même motif ; la SPEC fixe une seule forme de garde.
|
||
- **n° 6 suit n° 18** : même widget ; le contrôle en jeu après n° 18 dira si l'Accessed None du journal revient.
|
||
- **n° 9** attend la décision de l'utilisateur (R06 § 5.5 n° 2, non tranchée) ; **n° 33** attend son accord sur B2 ; n° 16
|
||
et 35 sont exclus par la décision 4.
|
||
- **n° 37** : la lecture des graphes non lus peut révéler d'autres défauts. Elle n'entre en B1 que si le créneau MCP le
|
||
permet.
|
||
- **Preuve en jeu** : ouvrir CharGen, bouger un curseur et le réglage anti-déformation, cliquer les 8 boutons ; ouvrir le
|
||
menu de forme du corps sans passer par CharGen ; compter `Accessed None` et les textes à l'écran
|
||
(`Tools\LogStats.ps1 -Pattern`). Ce test est fait par l'utilisateur, au J3 ou en REL2.
|
||
|
||
## 4. Niveaux de preuve
|
||
|
||
- **Établi** :
|
||
- la liste D1-D29, leur gravité et leur emplacement (R04, lectures MCP de CGREF1) ;
|
||
- H3i (378 occurrences, chemin, pile) ;
|
||
- le format V8 du C++ (`LPSandboxCharGenMod.cpp:1706-1729`, relu) ;
|
||
- les décisions 1 à 4 (R06 § 5.5) ;
|
||
- la présence des `.uasset` (`ls`).
|
||
- **Estimé** :
|
||
- les efforts S / M / L et le total du § 5 ;
|
||
- le déclenchement en jeu de n° 20, 23 et 25 ;
|
||
- l'effet de n° 32 ;
|
||
- n° 11 « voulu » ;
|
||
- pour n° 33 : l'absence d'autre écrivain V8 que `SaveCharacter` (grep limité au fichier).
|
||
- **Incertain** :
|
||
- n° 5 ;
|
||
- le nœud exact de n° 30 ;
|
||
- le contenu des graphes du n° 37.
|
||
|
||
## 5. Proposition de périmètre pour la build 1 (IMPL au J2)
|
||
|
||
| Groupe | Numéros | Effort estimé | Motif |
|
||
|---|---|---|---|
|
||
| **B1 cœur** | 30, 18 (+ contrôle 6), 19, 20, 23, 25, 26 | ≈ 5 h de MCP (5 × S, 2 × M), plus instantané, compilation des Blueprints et relecture : environ une demi-journée à une journée de jeton UE | tout ce qui est **visible du joueur** (textes de débogage à l'écran) ou **produit des Accessed None** à chaque geste ; corrections locales, réversibles, sans C++ |
|
||
| **B1 option** | 4, 21, 3, 27 | ≈ 2 h | 4 : écriture hors de `Modules` possible (moyenne) ; 21 : doublons dans la liste ; 3 et 27 : nettoyage à coût faible. À faire seulement si le cœur passe dans le créneau |
|
||
| **B2** | 1, 2, 5, 7, 8, 9, 10, 12, 14, 15, 17, 22, 24, 28, 29, 31, 32, 33, 34, 36, 37 | n° 33 ≈ 1 j de C++ ; le reste ≈ 1 à 1,5 j de MCP | n° 33 dépasse le créneau du J2 (L, compilation) ; n° 9 attend une décision ; n° 14, 17, 24 et 32 forment un lot « journaliser les échecs » (R06 § 3.1) ; n° 37 en lecture d'abord |
|
||
| **sans correction** | 11, 13 | — | comportements voulus |
|
||
| **hors lot** | 16, 35 | — | décision 4 de l'utilisateur |
|
||
|
||
Bilan de la build 1 : 7 corrections dans le cœur (sur 34 défauts), dont 4 des 8 de gravité moyenne (20, 23, 25, 30). Les
|
||
deux défauts visibles à l'écran et toutes les sources d'Accessed None connues du générateur sont dans ce cœur. Au-delà
|
||
d'une journée d'IMPL, la feuille de route (§ 3.3 risque 2) prévoit un tri avec l'utilisateur ; le cœur reste en dessous
|
||
(estimé).
|
||
|
||
## 6. Points à confirmer (repris par la SPEC CG2)
|
||
|
||
- Nœud exact du lecteur `GI.CharGen` dans `VisualMorph` (n° 30) : lecture MCP en tête de session.
|
||
- Forme commune des gardes `IsValid` (n° 20, 23, 25) : garde à l'entrée de chaque gestionnaire, ou fermeture de l'écran
|
||
si aucun personnage n'est édité.
|
||
- Le contrôle en jeu fait-il disparaître l'Accessed None de n° 6 après n° 18 ?
|
||
- Recompter en jeu les textes de débogage (n° 18, 19) et les Accessed None (n° 20, 23, 25, 30) avant et après, avec
|
||
`LogStats -Pattern`.
|
||
|
||
## 7. Questions pour la SPEC ou l'utilisateur
|
||
|
||
- **Q1 (n° 18)** : retirer seulement le texte à l'écran, ou aussi le morph fixe appliqué à chaque changement ? La SPEC
|
||
propose le retrait complet, à confirmer : c'est un reste de débogage d'après R04.
|
||
- **Q2 (n° 30)** : en B1, garde seule (plus d'Accessed None ; les curseurs restent à 0 sans CharGen ouvert, comme
|
||
aujourd'hui) ou lecture du personnage édité (change le comportement) ? Recommandé : garde seule en B1, lecture en B2.
|
||
- **Q3 (n° 9)** : reproduire le comportement actuel (morph remis à 0) ou le corriger (valeur laissée) ? Décision R06
|
||
§ 5.5 n° 2 non tranchée ; B2 dans tous les cas.
|
||
- **Q4 (n° 33)** : accord pour passer en B2 l'écriture du format du jeu par la Sandbox, environ une journée de C++ avec
|
||
compilation ? Faut-il garder la lecture des anciens fichiers V8 ?
|
||
- **Q5 (n° 4)** : B1 option ou B2 ? Règle de nom pour le jeu : refuser `..` et les séparateurs, ou les remplacer ? La
|
||
décision 3 vise la Sandbox ; le préfixe `Modules` du jeu reste.
|
||
- **Q6 (n° 25)** : une garde par bouton (8 points), ou une garde unique quand l'écran s'ouvre sans personnage (n° 20) ?
|