LifePlay-Revival/Docs/Migration/etat/ST/STG/STG-M1d-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

10 KiB

STG-M1d-VAL : validation statique du bloc COUPLE de LPDebugSubsystem (2026-10-14)

Fiche STG-M1d-VAL — Niveau N1 — Modèle prévu lp-validator (sonnet) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate

Lot STG, copie D:\Game\LifePlay-master 5.8, branche ue5.8. Lecture seule sauf ce livrable. Pas de build, pas d'UE, rien lancé.

1. Fiches amont relues

  • Docs\Migration\etat\ST\STG\STG-M1d-IMPL.md (IMPL, points à confirmer § 4).
  • Docs\Migration\etat\ST\STG\STG-C54-DIAG.md § 5 (mesure M1d : os le plus bas, bassin, surface sous le bassin, animation et position dans le cycle) : le bloc répond à ce § 5.
  • Instantané D:\Game\LifePlay_Backup_5.5\STG-M1d\ (manifest.csv : LPDebugSubsystem.cpp, 29622 octets, MD5 E281ACE2…).

2. Points à confirmer de l'IMPL (§ 4)

Id Point Résultat Preuve
P1 diff limité au bloc M1d PASS-STATIC § 3 et § 4 : 1 hunk, +50 / -0, bloc M1d seul
P2 API UE 5.8 FAIL (un appel non compilable) UAnimSingleNodeInstance::GetLength() non const, voir écart 1 ; le reste PASS-STATIC (tableau § 5)
P3 aucun effet de bord, lecture seule PASS-STATIC § 6
P4 compilation au build COMMUN-6 reporté (non mesurable sans build) ; annoncé en échec par P2 écart 1

3. Critères rejoués (commande, sortie brute)

MD5 (certutil -hashfile … MD5) :

LPDebugSubsystem.cpp : 31e2a3c5ff4a3feb5d9d5bf1c1b0afb0   (attendu 31E2A3C5FF4A3FEB5D9D5BF1C1B0AFB0 : conforme)
LPDebugSubsystem.h   : 78d3a07957d81e0b39c5d9a81e5e03d3   (attendu 78D3A079… : conforme, inchangé)

Fins de ligne (.\Tools\FileCheck.ps1 Source/LifePlay/LPDebugSubsystem.cpp,Source/LifePlay/LPDebugSubsystem.h) :

CRLF  819  0  0 -   31E2A3C5FF4A3FEB5D9D5BF1C1B0AFB0  Source\LifePlay\LPDebugSubsystem.cpp
CRLF   53  0  0 -   78D3A07957D81E0B39C5D9A81E5E03D3  Source\LifePlay\LPDebugSubsystem.h
fichiers=2 CRLF=2 alertes=0 introuvables=0     exit=0

git ls-files --eol : i/crlf w/crlf pour le .cpp. CRLF homogène (LF seul = 0, CR seul = 0).

Diff instantané → actuel : git diff --no-index --numstat --ignore-cr-at-eol <instantané>\…\LPDebugSubsystem.cpp Source/LifePlay/LPDebugSubsystem.cpp → 50 0 ; -U0 … | grep -c '^@@' → 1.

4. Diff lu en entier

Un seul hunk, @@ -492,0 +493,50 @@, 50 lignes ajoutées (l. 493 à 541 du fichier actuel, dont la ligne vide finale), 0 supprimée : le bloc M1d, inséré entre la fin du bloc GIState (l. 491) et le commentaire « Paires de personnages visibles » (l. 543). Aucun autre changement. P1 : PASS-STATIC. (Le diff contre HEAD montre 318 lignes, ce sont les lots antérieurs non commités : hors périmètre.)

5. API UE 5.8 (en-têtes D:\Game\Launcher\Engine\UE_5.8\Engine\Source\Runtime\Engine\)

Appel du bloc Déclaration lue Const sur l'objet utilisé Verdict
Body->GetNumBones() (const USkeletalMeshComponent*) Classes/Components/SkinnedMeshComponent.h:1144 int32 GetNumBones() const oui OK
Body->GetBoneName(int32) SkinnedMeshComponent.h:1165 FName GetBoneName(int32) const oui OK
Body->GetBoneIndex(FName) SkinnedMeshComponent.h:1156 int32 GetBoneIndex(FName) const oui OK
Body->GetBoneLocation(FName) SkinnedMeshComponent.h:2014 FVector GetBoneLocation(FName, EBoneSpaces::Type Space = EBoneSpaces::WorldSpace) const oui ; espace par défaut = monde OK
Body->GetSingleNodeInstance() Classes/Components/SkeletalMeshComponent.h:1539 UAnimSingleNodeInstance* GetSingleNodeInstance() const oui OK (retourne un pointeur non const)
Single->GetAnimationAsset() Classes/Animation/AnimSingleNodeInstance.h:78 virtual UAnimationAsset* GetAnimationAsset() const oui OK
Single->GetCurrentTime() AnimSingleNodeInstance.h:114 float GetCurrentTime() const oui OK
Single->GetLength() AnimSingleNodeInstance.h:67 ENGINE_API float GetLength(); (non const ; définition Private/Animation/AnimSingleNodeInstance.cpp:425 float UAnimSingleNodeInstance::GetLength()) non : Single est déclaré const UAnimSingleNodeInstance* (cpp l. 532) ERREUR C2662 attendue
Under.GetComponent()->GetReadableName() Classes/Components/ActorComponent.h:1219 virtual FString GetReadableName() const (héritée par UPrimitiveComponent) oui OK
Under.ImpactPoint.Z Classes/Engine/HitResult.h:53 FVector_NetQuantize ImpactPoint n/a OK (double)
World->LineTraceSingleByChannel(Under, …, ECC_Visibility, Query) Classes/Engine/World.h:2161 bool … const oui OK ; Query est un FCollisionQueryParams (cpp l. 374)
TNumericLimits<double>::Max() déjà utilisé l. 544 et 575 du même fichier, mêmes inclusions n/a OK
ECollisionEnabled::NoCollision enum utilisé l. 416 (ECollisionEnabled::Type) n/a OK

Visibilité : World (cpp l. 341), Persons (l. 363, TArray<ACharacter*>), Query (l. 374) sont déclarés au niveau fonction avant le bloc (l. 493) ; le bloc est dans la même fonction WritePersonsDump. Persons est parcouru en const ACharacter* : IsHidden, GetCapsuleComponent, GetMesh sont const. UAnimSingleNodeInstance : Animation/AnimSingleNodeInstance.h est inclus (l. 20) ; UAnimationAsset arrive par ce même en-tête.

Printf (cpp l. 534 à 538) : 12 spécificateurs (%s %s %.2f %.2f %.1f %.1f %s %.1f %s %s %.1f %.1f) pour 12 arguments : nom (*FString), Playing ? *Playing->GetName() : TEXT("-") (const TCHAR* des deux côtés), GetCurrentTime()/0.0 (float/double promu en double, %f correct), GetLength()/0.0 (idem), Body->GetComponentLocation().Z (double), Lowest (double), *LowestBone.ToString(), Pelvis.Z, *PelvisBone.ToString(), *GetReadableName() ou TEXT("-") (const TCHAR*), ImpactPoint.Z ou 0.0 (double), Lowest - ImpactPoint.Z ou 0.0 (double). Compte et types conformes. Le *FString temporaire d'un ternaire vit jusqu'à la fin de l'expression complète : même schéma déjà utilisé l. 397 et 399.

6. Logique

  • Actif seulement si SexOn est vrai : CoupleSexOn && GetPropertyValue_InContainer(CoupleGI) (l. 497-498) ; propriété absente = bloc sauté. PASS-STATIC.
  • Lecture seule : aucune affectation à un objet du jeu ; seules des variables locales et Lines.Add. LineTraceSingleByChannel const ; GetBoneLocation const. P3 PASS-STATIC.
  • Personnes cachées ou capsule autre que NoCollision : continue (l. 504-507) ; pointeurs nuls testés (Cap, Body) avant usage ; GetNumBones() == 0 écarté avant GetBoneName(0) (l. 527). PASS-STATIC.
  • Trace : le Query ignore tous les Person_C (l. 370, 375) ; bTraceComplex vrai (l. 374).
  • Shadowing. Réglage : Source/LifePlay.Target.cs:11 et LifePlayEditor.Target.cs:11 BuildSettingsVersion.V7 ; CppCompileWarnings.cs:90-93 du moteur : shadow = Error pour V2 et plus (cible), /we4456 /we4458 /we4459. LifePlay.Build.cs ne le modifie pas (grep Shadow|Warning sans résultat). Variables du bloc : CoupleGI, CoupleSexOn, Person, Cap, Body, Lowest, LowestBone, Bone, BoneName, BoneZ, PelvisBone, Pelvis, Under, bUnder, Single, Playing. Variables visibles de la fonction à cet endroit : Reason, bFile (paramètres), World, Lines, Persons, Ignored, Query. Les autres noms de la fonction (GI, Room…, It, Loc, Capsule, Move, Mesh, Single l. 407, GIState, Scene, Keys, Player…) vivent dans des portées déjà fermées (boucle l. 378-419, bloc l. 421-491, if l. 350-361) : pas de masquage, ni Person (boucle précédente close), ni Single (l. 407 dans un if fermé). Aucun des 16 noms ne masque un autre dans le bloc (Bone boucle, BoneName corps de boucle, distincts). Déclaration globale masquée (C4459) : les noms précédents de l'espace de noms anonyme (l. 44-48) ne sont pas repris ; non recherché dans le reste du module (réserve R2). Verdict : aucun masquage relevé ; le réglage (Error) rendrait un masquage bloquant, donc le contrôle compte.

7. Verdict

FAIL (statique). Une erreur de compilation établie par lecture des en-têtes : Single->GetLength() (cpp l. 535) appelé sur const UAnimSingleNodeInstance*, méthode non const. Message attendu : MSVC C2662 « impossible de convertir le pointeur 'this' de 'const UAnimSingleNodeInstance' en 'UAnimSingleNodeInstance &' ». Le reste du bloc est conforme (P1, P3, MD5, CRLF, printf, visibilité, shadowing).

Correctif pour l'IMPL (non appliqué, je ne corrige pas) : déclarer Single sans const (UAnimSingleNodeInstance* Single = Body->GetSingleNodeInstance();, la méthode retourne déjà un pointeur non const, l. 1539). GetAnimationAsset/GetCurrentTime restent appelables. Après correction : nouvelle VAL statique du MD5 et de la ligne, puis build COMMUN-6 (P4).

8. Écarts et réserves

  1. Écart 1 (bloquant) : GetLength() non const sur pointeur const (ci-dessus). L'IMPL § 4 P2 ne le signalait pas ; le texte « GetLength » y figure sans mention de constness.
  2. R2 : C4459 (global masqué) non exploré hors du fichier ; d'autres fichiers du module n'entrent pas dans ce .cpp, risque faible (noms de l'espace de noms anonyme seulement).
  3. R3 : l'ordre des inclusions n'a pas été compilé ; UAnimationAsset est supposé fourni par AnimSingleNodeInstance.h (estimé, non établi par compilation).
  4. Non mesuré : compilation (P4), comportement en jeu, valeur des Z. LPTestStringCompat, Build.ps1 -FromLog et G-U3 : sans objet (aucun build).

Aucun chemin C:\Users ni nom de compte dans ce livrable.

9. Points à confirmer par l'utilisateur

  • Faire corriger l'IMPL (suppression du const sur Single) puis refaire une VAL statique.
  • Build COMMUN-6 seulement après cette correction.

10. Fichiers à commiter

A : Docs/Migration/etat/ST/STG/STG-M1d-VAL.md (ce livrable). Aucun autre fichier modifié par moi (LPDebugSubsystem.cpp : à commiter par le gardien seulement après correction, build et nouvelle VAL).

Tours : 8 / 25