11 KiB
Fiche STG-KO3-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
STG-KO3-VAL : validation statique du C++ non compilé (KO 3 de COMMUN-2) (2026-10-13)
Lot STG, copie D:\Game\LifePlay-master 5.8, branche ue5.8. Lecture seule sauf ce livrable. Pas de build, pas d'UE, aucune commande git qui écrit.
1. Fiches amont relues
Docs\Migration\etat\ST\STG\STG-KO3-IMPL.md(seule IMPL du lot concernée ; fiche à 6 sections, gabarit IMPL non suivi à la lettre : pas de section « Écarts à la SPEC » ni « Ce qui n'a pas été fait » séparées, la section 4 « Limites » et la section 5 « Essai prévu » en tiennent lieu ; écart de gabarit signalé, sans effet sur le verdict).Docs\Migration\etat\CAM\CAM-COMMUN2-DIAG.md§ « KO 3 » (défaut visé), citée par l'IMPL.- Dump
Docs\Migration\etat\portage55\L6f\L6f_dump_Person.txtl. 12836-13116 (relu en entier). - Instantané
D:\Game\LifePlay_Backup_5.5\STG-KO3\(manifest.csv: 3 entrées).
2. Points à confirmer des IMPL
L'IMPL ne liste pas de section « points à confirmer » numérotée. Les affirmations vérifiables de ses § 1 à 3 sont reprises ici.
| Id | Affirmation de l'IMPL | Résultat |
|---|---|---|
| P1 | MD5 après : DirectControl.cpp 64766F64…EDFE, .h inchangé 7B8FED0E…, Debug.cpp E281ACE2…2F2D9 |
PASS (§ 3, c1) |
| P2 | CRLF conservés (1 141 et 769 CR = LF) | PASS (§ 3, c2) |
| P3 | LeaveSeat seul nom nouveau, absent du reste de Source/ |
PASS (§ 3, c4) |
| P4 | unOccupyFnt sans paramètre, vide OccupyingFnt sur tous les chemins |
PASS-STATIC (§ 3, c6) |
| P5 | Scene_C ajouté aux deux listes ; ScenePlaying lit SexOn |
PASS (§ 3, c3, c5) |
| P6 | Compilation | reporté : non compilé par construction (BUILD hors de cette fiche) |
| P7 | Essai en jeu (IMPL § 5, COMMUN-3) | reporté : COMMUN-3 |
3. Critères rejoués (commande → résultat brut)
c1. MD5 : powershell Get-FileHash -Algorithm MD5 sur les 3 fichiers :
64766F645CCC55C3F71F7DFCA3B3EDFE Source\LifePlay\LPDirectControlSubsystem.cpp
7B8FED0E88A4939BFB249C475FBDD7C4 Source\LifePlay\LPDirectControlSubsystem.h
E281ACE24AECEC31C23528777FB2F2D9 Source\LifePlay\LPDebugSubsystem.cpp
Attendus identiques aux trois valeurs de la fiche. Instantané manifest.csv : DirectControl.cpp CC5EB9BC…D3 (32 787 o), .h 7B8FED0E… (2 440 o), Debug.cpp FF69A2EE…EF (29 141 o). Le .h actuel égale son instantané : PASS.
c2. Fins de ligne : Tools\FileCheck.ps1 -Path <3 fichiers> puis -Lot STG-KO3 -OnlyChanged :
CRLF 1141 0 0 - 64766F64… LPDirectControlSubsystem.cpp
CRLF 77 0 0 - 7B8FED0E… LPDirectControlSubsystem.h
CRLF 769 0 0 - E281ACE2… LPDebugSubsystem.cpp
fichiers=3 CRLF=3 alertes=0 introuvables=0 (code 0)
contenu : identique=1 modifie=2 (Sauv CRLF pour les 3)
git ls-files --eol : i/crlf w/crlf pour les deux .cpp. CRLF homogènes, LF seul = 0, CR seul = 0 : PASS.
c3. Diff intégral instantané → actuel : diff --strip-trailing-cr des deux .cpp. Lu en entier ; contenu complet :
- DirectControl.cpp : l. 54
TEXT("Scene_C")ajouté àMenuClasses; l. 456-457 deux lignes de commentaire ; l. 458-462ScenePlayinglitFBoolProperty SexOn(plus deCurrentScene, plus deTrimStartAndEnd/Equals("None")) ; l. 464-485 nouvelle fonctionLeaveSeat; l. 907 appelLeaveSeat(Pawn);en tête de la brancheif (bMoving). Rien d'autre. - Debug.cpp : l. 438
TEXT("Scene_C")dansMenuClasseslocale ; l. 484-485 deuxFBoolProperty(SexOn,SceneOn) ; l. 486-489 ligne WALK :sexOn=%d sceneOn=%dajoutés et 2 arguments. Rien d'autre. Ces changements sont exactement ceux du § 3 de l'IMPL (3a, 3b, M1b). Aucun ajout non demandé.git diff --stat HEAD: DirectControl.cpp 33 lignes (+27/-6 environ), Debug.cpp +268 (le reste du Debug.cpp vient de B7-a/CLOSE, présent dans l'instantané, hors périmètre de ce diff).
c4. Collisions de noms (Grep LeaveSeat|ScenePlaying|MenuClasses sur Source) :
LeaveSeat: 2 occurrences, toutes dansLPDirectControlSubsystem.cpp(l. 465 définition, l. 907 appel).ScenePlaying: définition l. 458, appels l. 626 et 754, même fichier.MenuClasses: DirectControl l. 51 (espace anonyme, préexistant) ; Debug l. 435 (staticlocale de fonction, pas d'espace de noms) ; CameraMode l. 56 (dansnamespace LPCameraModeLocal, nommé, ce qui évite C2374 par conception, l. 22-24). Aucun nom nouveau en collision. PASS.
c5. Exactitude C++ (UE 5.8), lecture :
FBoolProperty::GetPropertyValue_InContainer(const void*)surconst FBoolProperty*: méthode const,GI(const UObject*) convertible enconst void*. Même schéma que leFStrPropertyremplacé et que l. 977 (CastField<FBoolProperty>déjà utilisé). OK.FObjectPropertyBase::GetObjectPropertyValue_InContainer(const void*)const, rendUObject*: utilisé l. 134-142 du même fichier. OK.GetNameSafe(UObject*)déjà utilisé l. 448 et 844. OK.Player->FindFunction(TEXT("unOccupyFnt")):UObject::FindFunction(FName), renvoieUFunction*;Function->ParmsSizeest unint32public ; l. 409 utilise déjàFindFunction.Player->ProcessEvent(Function, nullptr): signatureProcessEvent(UFunction*, void* Parms),nullptrcorrect pour une fonction sans paramètre.AActor*←APawn*(l. 863APawn* Pawn, l. 907) : conversion implicite. OK.- Includes : tous les symboles (
FObjectPropertyBase,FBoolProperty,UFunction,GetNameSafe,LogLifePlayviaLifePlay.h) sont déjà utilisés dans le fichier avec les mêmes includes (l. 8-43) ; aucun include nouveau nécessaire. Debug.cpp : mêmes types déjà employés l. 423, 481. - Accolades : lues l. 456-485 et 905-913 : équilibrées,
LeaveSeatfermée l. 485 avantMenuOnScreen, dans l'espace anonyme. Printfde la ligne WALK (Debug.cpp l. 486-490) : spécificateurs%d %s %d %d %.2f %.2f %.1f %.1f= 8 ; arguments : int (Keys && … ? 1 : 0),*FString(TCHAR*), int (SexProp ? (…?1:0) : -1), int (idemSceneOnProp),Forward(double),Right(double), double (PlayerMove ? … : -1.0), double (Player ? … : -1.0) = 8. Types conformes. PASS-STATIC.UE_LOG … %savec*GetNameSafe(...)(TCHAR*) : OK.
c6. Logique :
ScenePlayingne lit plusCurrentScene: confirmé (diff c3 ; Grep : plus deCurrentScenedans la fonction). SeulSexOn(bool).CurrentScenereste lu dans Debug.cpp l. 423 pour la ligneGI CurrentScene=(journal, intentionnel).Scene_CdansMenuClassesde DirectControl (l. 54, testée parMenuOnScreenl. 513) et dans la liste de la ligne WALK (Debug.cpp l. 438). Confirmé.LeaveSeat: sort sans rien faire siPlayernul, si la propriétéOccupyingFntest absente ou si sa valeur est nulle. Sinon, contrôleFindFunction/ParmsSize != 0avec un avertissement unique (static bool bWarned) et sans appel, puis journal etProcessEvent. Pas de boucle interne ; appel unique par tick de marche.- Dump
L6f_dump_Person.txtl. 12836-13116,Person :: unOccupyFnt (59 noeuds):K2Node_FunctionEntry_0l. 12837-12838 sans pin de paramètre ni de sortie (aucune ligneNear/ReturnValuesur l'entrée, contrairement àstandIdlel. 13120 qui porteNear) : aucun paramètre. Chemins quandOccupyingFntest valide (MacroInstance_1« Is Valid » →IfThenElse_4, l. 13029-13032, 12972-12976) : (a) condition fausse (Map vide ou animation sans préfixefnt_) →else→VariableSet_0qui metOccupyingFntà vide (l. 13034-13037, 12976) ; (b) condition vraie → boucleMap_Keys(MacroInstance_0) : corpsIfThenElse_5(l. 13021-13025) ; faux (elsevide) = élément suivant ; vrai →IfThenElse_2(l. 12941-12945) ;else→Knot_1;then→ journal →IfThenElse_3→Map_RemoveouMap_Add→Knot_1;Knot_1→Break(l. 12922-12924) →Completed→VariableSet_0(l. 12904, 13035). Fin de tableau sans correspondance :Completed→VariableSet_0. Tous les chemins aboutissent àVariableSet_0:OccupyingFntest vidé, doncLeaveSeatne boucle pas et ne répète pas l'appel (sauf si un autre code réaffecteOccupyingFnt, ce qui est le comportement voulu). BrancheOccupyingFntnon valide (Is Not Valid, l. 13033 →VariableSet_10) : inaccessible depuisLeaveSeat, qui n'appelle que si valide. La description de l'IMPL § 2 est conforme au dump. Aucun appel de fonction ne peut boucler indéfiniment (boucleForEachsur tableau fini). PASS-STATIC. - Chemin sans siège et sans scène :
LeaveSeatsort tôt (propriété vide ou absente, y compris pour un pion non-Persondu mode sandbox) ;ScenePlayingrenvoiefalsehors scène de sexe ;MenuOnScreeninchangé hors la classe ajoutée. Marche inchangée. PASS-STATIC.
c7. Content\UI\Scene.uasset : existe, 667 076 octets (Get-Item). Nom de classe générée Scene_C (convention <Asset>_C, widget /Game/UI/Scene) : estimé par convention ; confirmation par GI::ClearSceneWidget citée en IMPL (dump GI l. 54849-54859, non relu ici).
4. Diff lu en entier
2 fichiers .cpp (DirectControl, Debug), 1 .h inchangé (MD5 = instantané). Hunks : DirectControl 6 (l. 54, 456-457, 458-464, 465-485 nouvelle, 907 ; remplacement l. 460-464) ; Debug 2 (l. 438, 484-490). Rien hors § 3 de l'IMPL.
5. Verdict
PASS-STATIC (lecture seule, rien compilé ni exécuté : critère « compile » non vérifié, jamais compté comme passé).
6. Points à confirmer par l'utilisateur
- BUILD
LifePlayEditor5.8 (0 erreur, module LifePlay dans les unités compilées) avant COMMUN-3. - COMMUN-3 : les trois essais de l'IMPL § 5 (scène de dialogue fermée puis ZQSD ; assis puis ZQSD avec les deux lignes de journal ; dialogue de scène ouvert : ZQSD sans effet).
Scene_C: nom de classe confirmé seulement en jeu (la ligne WALKmenus=[…]doit afficherScene_Cpendant une scène).
Réserves
LPCameraModeSubsystem.cppl. 56-59 garde sa propre copie deMenuClassessansScene_C(masquage du texte pendant les menus) : non modifiée, hors périmètre de l'IMPL ; à décider (écart de cohérence, pas un défaut du KO 3).unOccupyFntexécuteGetArrayItem(ar, 2)sans garde sicurrentAnimationa moins de 3 champs (conditionfnt_seule) : risque d'« Accessed None »/erreur de tableau Blueprint propre au graphe existant, pas introduit par ce C++ ; effet : journal, pas de blocage.GI.SexOnpeut rester vrai après une scène (IMPL § 4) : à lire sur la ligne WALK.- L'IMPL ne suit pas exactement le gabarit IMPL (pas de section « Points à confirmer en VAL » ni « Fichiers à commiter » au format
A/M/D) ; sections 1-4 présentes sous d'autres titres.
Fichiers écrits par la VAL : D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STG\STG-KO3-VAL.md (A).
Fichiers à commiter : Docs/Migration/etat/ST/STG/STG-KO3-VAL.md (A) ; dépôt jeu, branche ue5.8.
Tours : 7 / 30