LifePlay-Revival/Docs/Migration/etat/ST/STG/STG-B7a-VAL.md

174 lines
15 KiB
Markdown
Raw Normal View History

Fiche STG-B7av — Niveau N1 — Modèle prévu (agent lp-validator) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills lp-validate, lp-commandlets, sk-protocol, sk-recount, debug-verification
# STG-B7a-VAL : validation statique de B7-a (GI.Show) et du filtre CLOSE (LPDebugSubsystem.cpp) (2026-10-13)
Verdict global : **PASS-STATIC**. Partie I (GI.Show) : PASS-STATIC (dump et compilation rejoués, aucune exécution en jeu).
Partie II (filtre CLOSE) : PASS-STATIC (lecture seule, rien compilé). Aucun FAIL. Réserves en § 6.
## 1. Fiches amont relues
- `Docs\Migration\etat\ST\STG\fiches\STG-B7a.md` (gestes, critères), `STG-B7a-IMPL.md` (nœuds, liens, MD5, V1-V5),
`STG-C5-CART.md` (cité par la fiche : cause B7 ; non redémontré ici, la VAL contrôle l'IMPL contre la fiche),
`STG-CLOSE.patch`, `STG-TACHES.md` (lignes STG-B2P, STG-C2a, STG-SF4b-I pour le contexte et les références 25 / 3 / 55 / 420),
`STG-B2P-VAL.md` et `STG-B1-VAL.md` (référence CompileAllBlueprints), `dumps\GI__Show.txt` (départ, 84 nœuds).
- Rien n'est cru sur parole : dump, MD5, diff et compilation sont rejoués ci-dessous.
## 2. Points à confirmer des IMPL
| Id | Point | Verdict | Preuve |
|---|---|---|---|
| V1 | Dump `GI.Show` : 84 + 7 = 91 nœuds, liens du § 1.3 de l'IMPL, `IfThenElse_3.else` → `IfThenElse_6` | **PASS** | § 3 b : `=== GI :: Show (91 noeuds) ===` (journal l. 1931) ; 7 ajoutés, 0 retiré ; 4 nœuds existants aux liens modifiés = liste de la fiche ; liens des 7 nœuds = tableau IMPL § 1.3 |
| V2 | `PromotableOperator_0` = `Less_DoubleDouble` (B = 70) ; `PromotableOperator_1` = `NotEqual_ObjectObject` | **PASS** | dump : `appel KismetMathLibrary::Less_DoubleDouble()`, `B = '70.0'` ; `appel KismetMathLibrary::NotEqual_ObjectObject()` (l'estimé E1 de l'IMPL est établi) |
| V3 | `CallFunction_28` = `Person_C::moveToPersonStand`, `self` ← personne montrée, `Person` ← `PlayerCharacter`, `Distance` = 100 | **PASS** | dump : `appel Person_C::moveToPersonStand()`, `self -> GetArrayItem_10739.Output`, `Person -> VariableGet_4.PlayerCharacter`, `Distance = '100.0'` |
| V4 | `CompileAllBlueprints` éditeur fermé : aucun message nouveau sur GI | **PASS** | § 3 c : `La compilation de GI a réussi ! [en 4 228 ms]` (journal l. 142 du résumé) ; 0 ligne d'erreur sous `/Game/` ; 25 / 55 / 420 = référence |
| V5 | En jeu : personne à moins de 70 cm, `SexOn` faux, autre que le joueur → placée à 100 ; aucun `Accessed None` nouveau ; branche `then` d'`IfThenElse_3` inchangée | **reporté** (STG-B7a-V5) | exige un build empaqueté + `LogStats` ; interdit par la fiche (pas de jeu, pas de build). La non-régression du `then` est établie par le dump seulement (§ 3 b) |
## 3. Critères rejoués
### a. (I-a) MD5 et état
Au départ (avant tout commandlet) et à la fin (après dump, CompileAllBlueprints), `md5sum` :
```
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
ca2a9a0baaca4130fd5c318797f008ae *Content/BPs/Room.uasset
ff69a2ee950e52e95f4f21635fcb5cef *Source/LifePlay/LPDebugSubsystem.cpp
```
= attendus (GI `E64B5B37…`, Person `8668A47C…`, Room `CA2A9A0B…`, .cpp `ff69a2ee…`) : **PASS**. Départ = fin (deux relevés identiques).
`pwsh -NoProfile -File Tools/UeState.ps1` au départ et à la fin : `processus=0 editeur=0 compilation=0 shaders=0 jeu=0`, code 0 : **PASS**.
Le MD5 de départ de GI `0E6AEDCC…` (instantané `Backup_5.5\STG-B7a`, manifeste cité par l'IMPL) n'est plus vérifiable que par
l'IMPL (le fichier d'avant n'existe plus dans la copie) : repris de l'IMPL, **estimé**.
### b. (I-b, I-c) Dump `LPDumpFunction -BP=GI -Fn=Show -Pins -Exec`
Commande : `pwsh -NoProfile -File 'D:\Game\LifePlay-master 5.8\Tools\RunCommandlet.ps1' -Lot STG-B7av -Commandlet LPDumpFunction -Args "-BP=GI -Fn=Show -Pins -Exec" -EtatDir 'D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STG'`
Sortie : `code=0 duree=51s erreurs=0 avertissements=465` ; journal `Saved\Logs\portage\STG-B7av_LPDumpFunction_20261013-192844.log` ;
résumé `etat\ST\STG\STG-B7av_LPDumpFunction_20261013-192844.txt`. Pas de demande de recompilation de modules.
Comparaison avec le dump de départ par un script de lecture seule (Python `-I`, dossier temporaire de session, rien écrit dans le projet) :
```
base nodes 84 new nodes 91
added: ['K2Node_CallFunction_27', 'K2Node_CallFunction_28', 'K2Node_CommutativeAssociativeBinaryOperator_3', 'K2Node_IfThenElse_6', 'K2Node_PromotableOperator_0', 'K2Node_PromotableOperator_1', 'K2Node_VariableGet_17']
removed: []
changed existing: 4
```
Les 4 nœuds existants modifiés (broche : avant → après), seuls écarts parmi les 84 nœuds et leurs broches :
| Nœud | Broche | Avant | Après (ajout) |
|---|---|---|---|
| `IfThenElse_3` | `else` | `(vide)` | `-> IfThenElse_6.execute` |
| `CallFunction_10` | `Dist` | `-> CallFunction_12.A` | `+ PromotableOperator_0.A` |
| `GetArrayItem_10739` | `Output` | 4 liens | `+ PromotableOperator_1.A`, `+ CallFunction_28.self` |
| `VariableGet_4` | `PlayerCharacter` | `-> VariableGet_14.self, CallFunction_10.To` | `+ PromotableOperator_1.B`, `+ CallFunction_28.Person` |
= la liste de la fiche (I-b) : **PASS**. Les 7 nouveaux nœuds (types et broches relevés du dump) : `IfThenElse_6` (Branch),
`CommutativeAssociativeBinaryOperator_3` (`BooleanAND`, entrées A, B, C : 3), `PromotableOperator_0` (`Less_DoubleDouble`),
`CallFunction_27` (`Not_PreBool`), `PromotableOperator_1` (`NotEqual_ObjectObject`), `VariableGet_17` (`SexOn`, `self` vide = GI),
`CallFunction_28` (`moveToPersonStand`) : **PASS**.
Logique (I-c), lue dans le dump :
- `IfThenElse_3.else -> IfThenElse_6.execute` ; `IfThenElse_6.Condition <- AND_3.ReturnValue` ; `AND_3.A <- Less(Dist, 70.0)` avec
`Dist <- CallFunction_10.Dist` ; `AND_3.B <- Not(SexOn)` ; `AND_3.C <- NotEqual(GetArrayItem_10739.Output, PlayerCharacter)` : **PASS**.
- `IfThenElse_6.then -> CallFunction_28.execute` ; `CallFunction_28` : `self <- GetArrayItem_10739.Output`, `Person <- PlayerCharacter`,
`Distance = 100.0` ; `IfThenElse_6.else (vide)` ; `CallFunction_28.then (vide)` : **PASS**.
- Branche `then` d'origine inchangée : `IfThenElse_3.then` non listé parmi les écarts (reste `-> CallFunction_13.execute`) ; `CallFunction_13`,
`CallFunction_11` (`moveToPerson`), `CallFunction_5` (`TalkDirty`) : aucun écart de broche : **PASS**.
- Aucune lecture d'objet pouvant être nul ajoutée : `Less` lit `Dist` (déjà calculé par `getDistance` sur `GetArrayItem_10739.Output`,
même chemin, `CallFunction_10` précède `IfThenElse_3`) ; `SexOn` est une variable de GI (`self` vide) ; `NotEqual_ObjectObject` compare deux
références sans les déréférencer ; `moveToPersonStand` vise la même cible que `getDistance`. Aucune nouvelle lecture sur `PlayerCharacter` en dehors
de l'argument `Person` de `moveToPersonStand` et du `NotEqual` : **PASS-STATIC**. Remarque : `moveToPersonStand` reçoit `PlayerCharacter`
éventuellement nul ; ce cas est couvert par le garde G-B1a (`IsValid(Person)`) de STG-B2P (`STG-B2P-VAL.md`), établi pour Person, non rejoué ici.
### c. (I-d) `CompileAllBlueprints`
Commande : `pwsh -NoProfile -File 'D:\Game\LifePlay-master 5.8\Tools\RunCommandlet.ps1' -Lot STG-B7av -Commandlet CompileAllBlueprints -EtatDir 'D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STG'`
Sortie : `code=3 duree=196s erreurs=25 avertissements=55` ; journal `Saved\Logs\portage\STG-B7av_CompileAllBlueprints_20261013-192940.log` ;
résumé `etat\ST\STG\STG-B7av_CompileAllBlueprints_20261013-192940.txt`.
Recompte par une seconde méthode (Grep sur le journal) : `La compilation de .* a réussi` = **420** ; `Error:.*(/Game/|GI\b)` = **0**. Lignes de
`La compilation de GI a réussi ! [en 4 228 ms]`, `Person … réussi [en 2 835 ms]`, `Room … réussi [en 1 227 ms]`.
Les 25 lignes d'erreur (16 signatures) portent toutes sur `/Engine/CC_Shaders/Utilities/CR_FaceExpRig` (trois « Could not find graph function data for
node » : `GetMinCurveValue`, `GetMultiplyCurveValue`, `ModeIndexConversion`, plus structures inconnues) ; six lignes « Script Msg: … @@ » n'indiquent pas
de chemin (estimé : même Control Rig, même source, mêmes quantités que la référence).
Référence `STG-B2P-VAL.md` / `STG-B1-VAL.md` : code 3, 25 lignes, 3 erreurs, 55 avertissements, 420 réussites : **identique** (le « 3 » est lu comme
les trois nœuds distincts ci-dessus, déduit de la signature, la référence ne le définit pas). Verdict (I-d) : **PASS**.
## 4. Diff lu en entier
### Partie I : GI.uasset
Binaire : pas de diff texte. Contrôle par dump (§ 3 b) : 84 → 91 nœuds, 7 ajoutés, 4 nœuds aux liens modifiés, 0 retiré. `git status --short` :
` M Content/BPs/GI.uasset`, ` M Content/BPs/Person.uasset`, ` M Content/BPs/Room.uasset` ; Person et Room étaient déjà ` M` avant la fiche (Person par STG-B2P,
Room par CAM) et leurs MD5 sont ceux attendus : aucun asset non annoncé modifié par B7-a.
### Partie II : `Source/LifePlay/LPDebugSubsystem.cpp`
Commande : `git diff --no-index --numstat D:/Game/LifePlay_Backup_5.5/STG-CLOSE/Source/LifePlay/LPDebugSubsystem.cpp Source/LifePlay/LPDebugSubsystem.cpp`
Sortie : `14 0 {…/STG-CLOSE/Source => Source}/LifePlay/LPDebugSubsystem.cpp` (14 ajouts, 0 retrait).
MD5 de l'instantané : `57880954408614d93d0a1e39d724abee` (= `57880954…` annoncé) ; fichier actuel `ff69a2ee950e52e95f4f21635fcb5cef` (= `ff69a2ee…`).
Deux hunks : `@@ -326,6 +326,14 @@` (fonction `SeatPlace`, 8 lignes) et `@@ -491,6 +499,12 @@` (test avant `Radii`, 6 lignes) = 14. Le diff est identique,
ligne à ligne, à `STG-CLOSE.patch` (lu en entier). Rien d'autre dans le fichier ne diffère de l'instantané.
Fins de ligne : `cat -A` du diff : chaque ligne ajoutée finit par `^M$` ; `Tools\FileCheck.ps1 Source/LifePlay/LPDebugSubsystem.cpp` :
```
Fins CRLF LF CR BOM MD5 ...
CRLF 765 0 0 - FF69A2EE950E52E95F4F21635FCB5CEF Source\LifePlay\LPDebugSubsystem.cpp
fichiers=1 CRLF=1 alertes=0 introuvables=0
```
CRLF conservé (765 CRLF, 0 LF seul, 0 CR seul, pas de BOM) : **PASS**.
Logique (lecture de `LPDebugSubsystem.cpp` l. 329-335 et 502-507) :
- `SeatPlace` : `currentAnimation` (nom de l'objet lu par `ReadObjectName`), découpé sur `-` ; `Parts.Num() >= 4 ? Parts[2] : FString()` : place = 3e champ
de `fnt_xxx-<sexe>-<place>-<desc>`. `ReadObjectName` définie l. 316, avant `SeatPlace` (même espace de noms) : **PASS-STATIC**.
- Test : `FntA != "-"` (A occupe un meuble) `&&` même `OccupyingFnt` pour B `&&` `SeatPlace(A) != SeatPlace(B)` → `continue` (la paire n'est ni comptée, ni écrite `CLOSE`).
Même place → la condition est fausse → paire gardée (cas K8 : deux personnages sur la même place restent signalés) : **PASS-STATIC**.
Meuble différent, ou sans meuble (`-`) → paire gardée : **PASS-STATIC**.
- Placement : après le test `IsHidden` et avant `Radii`/`Gap` : une paire exclue n'entre pas dans `MinGap` ni `Close` : conforme à l'objet du filtre.
- API : `FString::ParseIntoArray(TArray<FString>&, const TCHAR*, bool bInCullEmpty = true) const`, `Engine\Source\Runtime\Core\Public\Containers\UnrealString.h.inl:1746`
(moteur 5.8 installé) ; appel sur une valeur temporaire permis (méthode `const`) : **PASS-STATIC**. `bInCullEmpty` vaut vrai : un champ vide compte pour 0 (voir R2).
- Compilation : **non faite** (interdit). Le verdict d'API et de syntaxe est par lecture ; la compilation reste à prouver par BUILD.
## 5. Verdict
| Partie | Verdict |
|---|---|
| I-a MD5 et UeState | PASS |
| I-b dump 84 → 91, 7 nouveaux, rien retiré, 4 nœuds modifiés | PASS |
| I-c logique | PASS-STATIC |
| I-d CompileAllBlueprints | PASS |
| **Partie I** | **PASS-STATIC** (V5 reporté) |
| II diff 14 lignes, CRLF, logique, API | PASS-STATIC (non compilé) |
| **Global** | **PASS-STATIC** |
## 6. Points à confirmer par l'utilisateur et réserves
- [ ] **STG-B7a-V5** : essai en jeu (build empaqueté) : partenaire à moins de 70 cm hors `SexOn` se place à 100 cm ; aucun `Accessed None` nouveau dans `Show`.
- [ ] **Compilation du filtre CLOSE** : à confier à BUILD (`Tools/Build.ps1`) avant le prochain paquet ; `LPDebugSubsystem.cpp` n'a pas été compilé.
- R1 (estimé, sans effet bloquant) : `moveToPersonStand` est appelé avec `Person = PlayerCharacter` ; si `PlayerCharacter` est nul, le `NotEqual` laisse passer et la
fonction cible reçoit un `Person` vide : couvert par G-B1a (STG-B2P), établi à la VAL B2P, non rejoué sur ce chemin.
- R2 (estimé) : si un seul des deux personnages a un `currentAnimation` vide ou non conforme (moins de 4 champs, `SeatPlace` vide) et l'autre une place, sur le même meuble,
la paire est exclue du compte `CLOSE` alors qu'elle pourrait se chevaucher réellement. Le fichier d'origine ne gère pas ce cas ; effet limité à la mesure M1.
- R3 : pas d'exécution en jeu de B7-a (collision de la capsule du joueur lors du placement à 100 cm non étudiée ici).
## 7. Commandes, fichiers écrits, fichiers à commiter
Fichiers produits par mes commandlets et mon livrable (aucun fichier de `Source/`, `Content/`, `Config/` modifié) :
- `Docs/Migration/etat/ST/STG/STG-B7a-VAL.md` (A)
- `Docs/Migration/etat/ST/STG/STG-B7av_LPDumpFunction_20261013-192844.txt` (A)
- `Docs/Migration/etat/ST/STG/STG-B7av_CompileAllBlueprints_20261013-192940.txt` (A)
- Journaux (non suivis par git) : `Saved\Logs\portage\STG-B7av_LPDumpFunction_20261013-192844.log`, `…\STG-B7av_CompileAllBlueprints_20261013-192940.log`.
- Script de comparaison de lecture seule : `cmp_show.py` dans le dossier temporaire de session (non versé).
Aucune commande git qui écrit. Fichiers à commiter : trois `A` ci-dessus (le gardien du dépôt).
Trace : `D:\Game\LifePlay-master 5.8\Saved\Logs\portage\STG-B7av_LPDumpFunction_20261013-192844.log` et `…\STG-B7av_CompileAllBlueprints_20261013-192940.log` — Fiche STG-B7av — 2026-10-13 19:28-19:36
Commande : voir § 3 b et § 3 c
Environnement: copie `D:\Game\LifePlay-master 5.8`, branche `ue5.8`, HEAD `0745917`, moteur UE 5.8 ; `UeState` 0 avant et après
Attendu : dump 91 nœuds (7 ajoutés, 4 modifiés) ; CompileAllBlueprints 0 erreur `/Game/`, 25 / 3 / 55 / 420, code 3
Obtenu : 91 nœuds, 7 ajoutés, 0 retiré, 4 modifiés ; code 3, 25 lignes d'erreur (toutes `CR_FaceExpRig`), 55 avertissements, 420 réussites
Lecture : code 3 de CompileAllBlueprints = erreurs `CC_Shaders` seules ; `LPDumpFunction` n'imprime pas les valeurs de classe
Tours : 17 / 40
## Constats
- À verser : `lp-commandlets` — le titre `=== GI :: Show (91 noeuds) ===` apparaît deux fois dans le journal (flux `LogLPDump` et copie `LogInit: Display:`) : comparer sur la première occurrence ;
le dump de départ `dumps\GI__Show.txt` classe les nœuds dans le même ordre que le dump actuel, mais seul un script par nœud et par broche détecte un lien modifié.
Note de l'orchestrateur (2026-10-13) : dans la section Constats, la ligne « À verser » affirme que le dump de départ et le dump actuel classent les nœuds dans le même ordre. Le validateur l'a signalé lui-même comme **non vérifié** (le début des deux fichiers suggère le contraire) : seule la première moitié (titre « (91 noeuds) » présent deux fois dans le journal) est établie.