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

100 lines
11 KiB
Markdown
Raw Normal View History

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.txt` l. 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-462 `ScenePlaying` lit `FBoolProperty SexOn` (plus de `CurrentScene`, plus de `TrimStartAndEnd`/`Equals("None")`) ; l. 464-485 nouvelle fonction `LeaveSeat` ; l. 907 appel `LeaveSeat(Pawn);` en tête de la branche `if (bMoving)`. Rien d'autre.
- Debug.cpp : l. 438 `TEXT("Scene_C")` dans `MenuClasses` locale ; l. 484-485 deux `FBoolProperty` (`SexOn`, `SceneOn`) ; l. 486-489 ligne WALK : `sexOn=%d sceneOn=%d` ajouté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 dans `LPDirectControlSubsystem.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 (`static` locale de fonction, pas d'espace de noms) ; CameraMode l. 56 (dans `namespace 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*)` sur `const FBoolProperty*` : méthode const, `GI` (`const UObject*`) convertible en `const void*`. Même schéma que le `FStrProperty` remplacé et que l. 977 (`CastField<FBoolProperty>` déjà utilisé). OK.
- `FObjectPropertyBase::GetObjectPropertyValue_InContainer(const void*)` const, rend `UObject*` : 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)`, renvoie `UFunction*` ; `Function->ParmsSize` est un `int32` public ; l. 409 utilise déjà `FindFunction`. `Player->ProcessEvent(Function, nullptr)` : signature `ProcessEvent(UFunction*, void* Parms)`, `nullptr` correct pour une fonction sans paramètre. `AActor*` ← `APawn*` (l. 863 `APawn* Pawn`, l. 907) : conversion implicite. OK.
- Includes : tous les symboles (`FObjectPropertyBase`, `FBoolProperty`, `UFunction`, `GetNameSafe`, `LogLifePlay` via `LifePlay.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, `LeaveSeat` fermée l. 485 avant `MenuOnScreen`, dans l'espace anonyme.
- `Printf` de 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 (idem `SceneOnProp`), `Forward` (double), `Right` (double), double (`PlayerMove ? … : -1.0`), double (`Player ? … : -1.0`) = 8. Types conformes. PASS-STATIC.
- `UE_LOG … %s` avec `*GetNameSafe(...)` (TCHAR*) : OK.
**c6. Logique** :
- `ScenePlaying` ne lit plus `CurrentScene` : confirmé (diff c3 ; Grep : plus de `CurrentScene` dans la fonction). Seul `SexOn` (bool). `CurrentScene` reste lu dans Debug.cpp l. 423 pour la ligne `GI CurrentScene=` (journal, intentionnel).
- `Scene_C` dans `MenuClasses` de DirectControl (l. 54, testée par `MenuOnScreen` l. 513) et dans la liste de la ligne WALK (Debug.cpp l. 438). Confirmé.
- `LeaveSeat` : sort sans rien faire si `Player` nul, si la propriété `OccupyingFnt` est absente ou si sa valeur est nulle. Sinon, contrôle `FindFunction`/`ParmsSize != 0` avec un avertissement unique (`static bool bWarned`) et sans appel, puis journal et `ProcessEvent`. Pas de boucle interne ; appel unique par tick de marche.
- Dump `L6f_dump_Person.txt` l. 12836-13116, `Person :: unOccupyFnt (59 noeuds)` : `K2Node_FunctionEntry_0` l. 12837-12838 sans pin de paramètre ni de sortie (aucune ligne `Near`/`ReturnValue` sur l'entrée, contrairement à `standIdle` l. 13120 qui porte `Near`) : aucun paramètre. Chemins quand `OccupyingFnt` est valide (`MacroInstance_1` « Is Valid » → `IfThenElse_4`, l. 13029-13032, 12972-12976) : (a) condition fausse (Map vide ou animation sans préfixe `fnt_`) → `else` → `VariableSet_0` qui met `OccupyingFnt` à vide (l. 13034-13037, 12976) ; (b) condition vraie → boucle `Map_Keys` (`MacroInstance_0`) : corps `IfThenElse_5` (l. 13021-13025) ; faux (`else` vide) = élément suivant ; vrai → `IfThenElse_2` (l. 12941-12945) ; `else` → `Knot_1` ; `then` → journal → `IfThenElse_3` → `Map_Remove` ou `Map_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` : `OccupyingFnt` est vidé, donc `LeaveSeat` ne boucle pas et ne répète pas l'appel (sauf si un autre code réaffecte `OccupyingFnt`, ce qui est le comportement voulu). Branche `OccupyingFnt` non valide (`Is Not Valid`, l. 13033 → `VariableSet_10`) : inaccessible depuis `LeaveSeat`, 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 (boucle `ForEach` sur tableau fini). PASS-STATIC.
- Chemin sans siège et sans scène : `LeaveSeat` sort tôt (propriété vide ou absente, y compris pour un pion non-`Person` du mode sandbox) ; `ScenePlaying` renvoie `false` hors scène de sexe ; `MenuOnScreen` inchangé 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 `LifePlayEditor` 5.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 WALK `menus=[…]` doit afficher `Scene_C` pendant une scène).
## Réserves
1. `LPCameraModeSubsystem.cpp` l. 56-59 garde sa propre copie de `MenuClasses` sans `Scene_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).
2. `unOccupyFnt` exécute `GetArrayItem(ar, 2)` sans garde si `currentAnimation` a moins de 3 champs (condition `fnt_` seule) : risque d'« Accessed None »/erreur de tableau Blueprint propre au graphe existant, pas introduit par ce C++ ; effet : journal, pas de blocage.
3. `GI.SexOn` peut rester vrai après une scène (IMPL § 4) : à lire sur la ligne WALK.
4. 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