LifePlay-Revival/Docs/Migration/etat/CG/CG2/CG2-CART-01.md
edujiro5972 56dfcfc3d2 LifePlay UE 5.8 : état de développement au 2026-10-20
Tickets : PUB-20261020-T1

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 17:35:10 +02:00

171 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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) ?