LifePlay-Revival/Docs/Migration/etat/ST/STG/STG-B7a-VAL.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

15 KiB

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.