113 lines
30 KiB
Markdown
113 lines
30 KiB
Markdown
Fiche STB-VAL — Niveau N1 — Modèle prévu sonnet (modèle de l'agent lp-validator) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills lp-validate, lp-build
|
||
# STB-VAL : validation statique et rejouée du lot STB (corrections Blueprint et C++ après G-ST) (2026-10-09)
|
||
|
||
Copie `D:\Game\LifePlay-master 5.8`, branche `ue5.8`. Base de comparaison : `9f59fa6` (STB-T0, dernier commit avant les corrections ; aucun tag `STB-avant` n'existe, `git tag` relu). Fin des commandes : 21:56. [sk-protocol] skills présents : sk-protocol, sk-recount, debug-verification, lp-validate.
|
||
|
||
Observation de contexte (établi, `git log`) : pendant la validation, HEAD est passé de `7049121` à `12d86d2` (deux commits `EDIT3` d'une autre session : `fe0cdd8`, `12d86d2`, trois fichiers Docs/Migration, aucun fichier Content, Source ou Config : `git diff 7049121 HEAD --stat`). Le diff STB lu est donc `9f59fa6..7049121`.
|
||
|
||
## 1. Fiches amont relues
|
||
- `Docs/Migration/Journal_Modifications.md` lignes 1134-1145 (CHG-292 à CHG-281), lues en entier : elles tiennent lieu de fiches IMPL (STB-TACHES.md : « fiche IMPL non écrite : le CHG en tient lieu » pour GIA ; PEA, PEB, MEN, SMS, ROO, GIC, SEX, MAP sans fiche IMPL non plus). Aucun livrable IMPL au gabarit n'existe pour le lot : section 5 du gabarit IMPL absente partout, remplacée par les mentions « à confirmer / preuve en jeu » du journal (voir § 2).
|
||
- `etat\ST\STB\STB-TACHES.md` (relu : aucun point amont à reprendre pour STB-VAL).
|
||
- `etat\ST\STB\STB-T0-BUILD.md`, `STB-GIB-BUILD.md` (code 0, `LPTestStringCompat` 3120 / 0 / 60, l.59-65), `STB-GIB-DATA-INV.md`, `STB-MAP-BUILD.md` (relu en entier : code 0, MSVC 14.50.35717, 2 unités, 0 erreur, 0 avertissement compilateur). `STB-T0-BUILD.md` et `STB-GIB-DATA-INV.md` : présence confirmée, contenu non relu ligne à ligne (hors périmètre des critères de la fiche).
|
||
- Dumps de référence d'avant lot : `etat\ST\STA\dumps\` (comptes de nœuds relus par Grep sur la ligne `=== … (n noeuds) ===`).
|
||
- Écart de gabarit amont (à signaler, sans bloquer) : les fiches BUILD STB-MAP, STB-GIB suivent le gabarit BUILD (sections 1 à 7). Aucune fiche IMPL, donc aucune section « Points à confirmer en VAL » à reprendre ; voir § 2 pour ce que les CHG demandent.
|
||
|
||
## 2. Points à confirmer des IMPL (tirés des lignes CHG)
|
||
| Point (source) | Verdict | Preuve ou report |
|
||
|---|---|---|
|
||
| CHG-281 : « Preuve en jeu à faire (STB-JEU : `array Floats_3` → résidu R02 seulement) » | reporté STB-JEU | Effet à l'exécution ; non vérifiable sans jeu (interdit fiche § 6). La présence des 2 appels est PASS (§ 3, tableau). |
|
||
| CHG-281 : appels dans les événements `LoadSettings` et `PopulateRaws` (ordre : après `loadAverageAttractiveness`, avant `SetSquirtMult` ; après `PopulateBeautyStandardsDefault`, avant `FillPregnancyMorphs`) | PASS-STATIC | Chaînes d'exécution lues dans `dumps/GI__EventGraph.txt:28727-28730`, `30052-30059`, `27975-27977`, `28577-28580`, `17263-17265`. L'appartenance des nœuds aux événements nommés (`CustomEvent_3270` l.8645, `CustomEvent_642` l.1723) n'a pas été suivie nœud par nœud : estimé (chaîne cohérente). |
|
||
| CHG-286 : `OnInitialized` avant l'évaluation des liaisons (`SynchronizeProperties` avant `Construct`) | PASS-STATIC pour le câblage, reporté STB-JEU pour l'ordre d'exécution | Câblage : `dumps/MainMenu__EventGraph.txt:1875-1894`. L'ordre d'exécution moteur n'est pas rejoué. |
|
||
| CHG-287 : « Effet en jeu à confirmer en STB-JEU » | reporté STB-JEU | Donnée : `Content/Modules/Clothes4.txt` 39 919 octets (ls), 956 CRLF, 0 LF seul, 0 ligne finissant par espace (Grep ` +\r?$` : 0 résultat), `FileCheck` 0 alerte. Établi (cohérent avec CHG-287). |
|
||
| CHG-289 : risque voisin non traité (`len = 0`, aucun préréglage pour l'amenity) | reporté (non traité par conception, hors lot) | Aucune garde ajoutée ; `dumps/Room__pickPresetWorld.txt` : aucun test de `len` hors du chemin existant. |
|
||
| CHG-290 : conditionnels R06-R08, R10 « à trancher, D11 / E4 / E5 » | reporté (décision orchestrateur) | Non traités, annoncés comme tels. |
|
||
| CHG-292 : comportement des saccades (R29) après retrait du composant | reporté STB-JEU | Code lu et compilé (§ 3, § 4) ; effet de performance non mesuré. |
|
||
|
||
## 3. Critères rejoués (commande → résultat)
|
||
|
||
### 3.1 Compilation et test (preuve fraîche, cette session)
|
||
| Critère | Commande | Résultat | Verdict |
|
||
|---|---|---|---|
|
||
| Éditeur fermé avant | `.\Tools\UeState.ps1` | `processus=0 editeur=0 compilation=0 shaders=0 jeu=0`, code 0 (aussi avant les commandlets de dump et avant LPTestStringCompat) | PASS |
|
||
| Tous les Blueprints compilent | `.\Tools\RunCommandlet.ps1 -Lot STB-VAL -Commandlet CompileAllBlueprints -Args ''` | `code=0 duree=208s erreurs=0 avertissements=0`. Journal `Saved\Logs\portage\STB-VAL_CompileAllBlueprints_20261009-213128.log`, résumé `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STB\STB-VAL_CompileAllBlueprints_20261009-213128.txt` | PASS |
|
||
| Recompte du précédent | Grep `a réussi` (count) sur le journal : 418 ; Grep `Loading and Compiling` : 418 ; Grep `Error:\|Warning:\|Avertissement\|Erreur\|a échoué\|Fatal\|Ensure\|Assertion` : 0 | Référence la plus récente `etat\ST\STM\STM-T4c_CompileAllBlueprints_20261009-162345.txt` (code 0, 0 erreur, 0 avertissement, 228 s) : `a réussi` = 418 par le même Grep. Écart : 0, nouvelles erreurs : 0, connues : 0 | PASS |
|
||
| Blueprints modifiés compilés | Grep `compilation de (GI\|Person\|Room\|StreetMap_Static\|MainMenu\|SexInterface\|MapMarkers) a r` | 7 lignes sur 7 (l.1971 MapMarkers, 2010 GI, 2013 Person, 2017 Room, 2020 StreetMap_Static, 2799 MainMenu, 2802 SexInterface) | PASS |
|
||
| Sémantique des chaînes | `.\Tools\RunCommandlet.ps1 -Lot STB-VAL -Commandlet LPTestStringCompat -Args ''` | `code=0 duree=16s erreurs=0 avertissements=2` ; ligne `=== 3120 cas : compat != herite(UE4) : 0 ; moteur != herite(UE4) : 60 ===` (`etat\ST\STB\STB-VAL_LPTestStringCompat_20261009-214222.txt:9,92`). Les « 2 avertissements » sont cette ligne même (journalisée en `Warning`, vue deux fois : `LogLPTestStringCompat` et sa copie `LogInit`). Grep `Condition failed` dans le journal : 0 (les 20 de la culture française annoncés par la fiche § 5 ne figurent pas dans ce journal ; pas une régression) | PASS (3120 / 0 / 60 = attendu) |
|
||
| Recompte du build STB-MAP, sans recompiler | `.\Tools\Build.ps1 -Lot STB-VAL -FromLog '…\Saved\Logs\portage\STB-MAP_Build_20261009-212857.log'` | `code=-1 duree=0s erreurs=0 avertissements=0 autres=20 unites=2` (le code -1 est celui d'une relecture de journal : aucun code dans le journal ; `Result: Succeeded` l.51 et `Total execution time: 28.84 seconds` l.52 lus). Chaîne : MSVC `14.50.35717` (l.34). Unités : `[1/5] Compile LPMapMarkersGuardSubsystem.cpp`, `[2/5] Module.LifePlay.cpp`, 2 liens (l.41-45). Conforme au livrable BUILD (2 unités, 0 / 0 / 20 autres). Les 20 lignes : `Plugin 'HyperAIStudio' does not list plugin …`, préexistantes (BUILD § 4) | PASS |
|
||
| DLL à jour | `ls -l --time-style=full-iso` | `UnrealEditor-LifePlay.dll` 1 248 768 octets, 21:29:25, postérieure à `LPMapMarkersGuardSubsystem.cpp` (21:27:58) et à `LPStringCompat.*` (20:52) ; `LifePlayEditorTools.dll` 20:54:26 | PASS |
|
||
| Aucune modification du dépôt par la VAL | `git status --short` (vide avant et après toutes les commandes) | 0 ligne | PASS |
|
||
|
||
### 3.2 Gardes dans les graphes (dumps frais : `LPDumpFunction -BP=<BP> -Fn=<Fn> -Pins -Exec`, un à la fois)
|
||
Dumps produits (copies des résumés `RunCommandlet`, nommés `<BP>__<Fn>.txt`) dans `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STB\dumps\` ; les lignes citées sont celles de la **première** copie du dump (la fin du fichier répète les mêmes lignes préfixées `LogInit: Display:`). Résumés d'origine : `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STB\STB-VAL_LPDumpFunction_<horodatage>.txt` (horodatages : Consolidate 214306, clearVariable 214358, determinePersonVars 214454, clearScenePersons 214546, pickPresetWorld 214637, standIdle 214725, assignHome 214817, SearchByAmenitySafe 214908, findNearbyBuilding 214959, LoadSettings 215051, GI EventGraph 215151, Person EventGraph 215300, MainMenu 215405, StreetMap_Static EventGraph 215502, SexInterface 215600). Les 14 dumps utiles : code 0, 0 erreur ; `GI__LoadSettings` : code 1 attendu (voir Écart 1).
|
||
|
||
Comptes de nœuds (ligne `=== … ===`, dump frais contre STA) : clearVariable 30 → 32 (+2), clearScenePersons 50 → 56 (+6), determinePersonVars 112 → 114 (+2), standIdle 89 → 93 (+4), assignHome 78 → 82 (+4 : 5 créés, 1 supprimé), pickPresetWorld 34 → 37 (+3), SearchByAmenitySafe 47 → 50 (+3), MainMenu EventGraph 394 → 398 (+4), StreetMap_Static EventGraph 1248 → 1252 (+4), SexInterface EventGraph 84 → 86 (+2), Person EventGraph 3677 → 3684 (+7 : 12 créés dont 4 dans standIdle, 1 supprimé), GI EventGraph 6201 → 6216 (+15), ConsolidateBeautyStandards 16 → 16 (inchangé). Chaque différence égale le nombre de nœuds créés moins supprimés annoncé par les CHG. `findNearbyBuilding` : 63 nœuds, sans dump STA (pas de comparaison de compte).
|
||
|
||
| CHG | Nœuds attendus (journal) | Constaté dans le dump frais (liaisons d'exécution) | Verdict | Preuve (dump:ligne) |
|
||
|---|---|---|---|---|
|
||
| 281 | `CallFunction_391` (`ConsolidateBeautyStandards`) dans `LoadSettings` après `loadAverageAttractiveness`, avant `SetSquirtMult` ; `CallFunction_406` dans `PopulateRaws` après `PopulateBeautyStandardsDefault`, avant `FillPregnancyMorphs` | `CallFunction_1055 (loadAverageAttractiveness).then → CallFunction_391.execute` ; `391.then → VariableSet_353 (SquirtMult)` ; `CallFunction_1037 (PopulateBeautyStandardsDefault).then → CallFunction_406.execute` ; `406.then → CallFunction_41 (FillPregnancyMorphs)` ; `41.execute ← 406.then` | OK | `GI__EventGraph.txt:28727-28730`, `30052-30059`, `27975-27977`, `28577-28580`, `17263-17265` |
|
||
| 282 (clearVariable) | `IfThenElse_3` sur `IsValidIndex(Person, 0)` (`CallArrayFunction_0`) entre `GetVariable` et la suite ; tableau vide → fin | `CallFunction_0 (GetVariable).then → IfThenElse_3.execute` (avant lot : `→ IfThenElse_1`, STA `GI__clearVariable.txt:7`) ; `IfThenElse_3.Condition ← CallArrayFunction_0.ReturnValue` (`Array_IsValidIndex`, `TargetArray` = `Person`, `IndexToTest 0`) ; `then → IfThenElse_1.execute` ; `else` (vide) | OK | `GI__clearVariable.txt:126`, `271-280` |
|
||
| 282 (FocusOnMapMarkers) | `IfThenElse_205` sur `IsValidIndex(MapMarkers.WidgetComponents, 0)` (`CallArrayFunction_115`) : vrai → `SetInputModeGameAndUI` existant ; faux → nouveau `CallFunction_412` sans widget, même contrôleur et options | `CustomEvent_183 ('FocusOnMapMarkers').then → IfThenElse_205.execute` ; `Condition ← CallArrayFunction_115` (`WidgetComponents`, index 0) ; `then → CallFunction_967.execute` ; `else → CallFunction_412.execute` (`SetInputMode_GameAndUIEx`, `InWidgetToFocus` vide, `PlayerController ← PC`, `DoNotLock`, `bHideCursorDuringCapture true`, `bFlushInput false`). Seule lecture de `WidgetComponents` dans le graphe : `GetArrayItem_497` (l.13311), derrière la garde | OK | `GI__EventGraph.txt:13304-13306`, `30060-30078`, `13310-13314` |
|
||
| 283 (Blueprint) | `GetArrayItem_65` → `CallFunction_423` ; `GetArrayItem_56` et `_58` → `CallFunction_426` et `_429` (`GetStringAtOrEmpty`) | `423` (`Index 3`), `426` et `429` (`Index 1`) présents, `LPStringCompat::GetStringAtOrEmpty()` ; les 3 `GetArrayItem` supprimés : 0 occurrence en frais, 3 en STA (`GI__EventGraph.txt` STA) | OK | `GI__EventGraph.txt:30079-30093` |
|
||
| 283 (C++) | `GetStringAtOrEmpty(Array, Index)` : élément ou chaîne vide | `git diff 9f59fa6 7049121 -- Source/LifePlay/LPStringCompat.{h,cpp}` : fonction `BlueprintPure`, `Array.IsValidIndex(Index) ? Array[Index] : FString()` ; fins de ligne LF inchangées (`FileCheck` : 0 alerte) ; `LPTestStringCompat` 3120 / 0 / 60 | OK | diff (+5 / +5 lignes) |
|
||
| 284 (standIdle) | `IfThenElse_7` sur `IsValid(Near)` (`CallFunction_18`) entre `SetDest` et `SetNearVec` ; non valide → boucle `ForEachLoopWithBreak` ; `IfThenElse_8` sur `IsValidIndex(Room.Standspots_Occupied, Array Index)` (`CallArrayFunction_2`) entre le corps de boucle et la macro `IsValid` ; hors bornes → `Knot_1` | `VariableSet_3 (Dest).then → IfThenElse_7` ; `Condition ← CallFunction_18 (IsValid, Object = Near)` ; `then → VariableSet_6 (NearVec)` ; `else → MacroInstance_1 (ForEachLoopWithBreak).Exec` ; `MacroInstance_1.LoopBody → IfThenElse_8` ; `Condition ← CallArrayFunction_2` (`Standspots_Occupied`, `IndexToTest ← Array Index`) ; `then → MacroInstance_3 (IsValid).exec` ; `else → Knot_1 → VariableSet_4` ; `Knot_1` reçoit aussi `MacroInstance_3.Is Not Valid` et `IfThenElse_3.else` | OK | `Person__standIdle.txt:293-294`, `308-315`, `329-330`, `447-448`, `539-557` |
|
||
| 284 (EventGraph, Headtrack) | `SelectVector` pur (`CallFunction_998`) supprimé ; cascade avant `SetActorRotation` (`CallFunction_442`) : `IsValid(HeadtrackStatic)` → `HeadtrackAimLocation` ; sinon `IsValid(HeadtrackTarget)` → `HeadtrackAimLocation` ; sinon rotation sautée vers `VariableSet_230` ; variable `HeadtrackAimLocation` lue par `FindLookAtRotation` | `CallFunction_998` : 0 occurrence en frais, 1 en STA (`Person__EventGraph.txt:18986`) ; `IfThenElse_147 (CallFunction_999).then → VariableSet_231 (HeadtrackAimLocation ← CallFunction_1000).then → CallFunction_442` ; `else → IfThenElse_148 (CallFunction_420 = IsValid(HeadtrackTarget)).then → VariableSet_233 (← CallFunction_451).then → 442` ; `else → VariableSet_230` ; `VariableGet_72 (HeadtrackAimLocation) → CallFunction_438.Target` (l.13018) | OK | `Person__EventGraph.txt:19390-19418`, `13026-13030`, `13018` |
|
||
| 284 (OccupyingFnt) | `IfThenElse_149` sur `IsValid(OccupyingFnt)` avant `IfThenElse_75` ; faux → rien | `IfThenElse_149.Condition ← CallFunction_462 (IsValid, Object = OccupyingFnt)` ; `then → IfThenElse_75.execute` ; `else` (vide) | OK | `Person__EventGraph.txt:19419-19427` |
|
||
| 285 | `BooleanAND` (`Prefix == 'F'` ET `FamilyLiveWiths[SaveSlot]`) supprimé ; cascade `IfThenElse_4` (`Prefix == 'F'`) → `IfThenElse_10` (`IsValidIndex(FamilyLiveWiths, SaveSlot)`, `CallArrayFunction_0`) → `IfThenElse_1` ; chaque cas faux vers `IfThenElse_3` ; `IfThenElse_11` sur `IsValidIndex(Buildings, 0)` (`CallArrayFunction_5`) entre `SearchByAmenitySafe` et `Map_Add(AI_Homes)` | STA : `BooleanAND_2` (A = `CallFunction_5`, B = `GetArrayItem_0`) alimentait `IfThenElse_1` (`Person__assignHome.txt:93-97` STA) ; frais : `IfThenElse_1.Condition ← GetArrayItem_0.Output` directement ; `IfThenElse_4 (Condition ← CallFunction_5).then → IfThenElse_10.execute`, `else → IfThenElse_3` ; `IfThenElse_10 (Condition ← CallArrayFunction_0 : FamilyLiveWiths, IndexToTest ← SaveSlot).then → IfThenElse_1`, `else → IfThenElse_3` ; `IfThenElse_1.else → IfThenElse_3` ; `CallFunction_0 (SearchByAmenitySafe).then → IfThenElse_11.execute` ; `IfThenElse_11.Condition ← CallArrayFunction_5 (Buildings, IndexToTest 0)`, `then → CallFunction_16.execute`, `else` (vide). Le `BooleanAND_1` restant (`Prefix` et `CallFunction_3`) est celui de STA l.51 | OK | `Person__assignHome.txt:194-198`, `260-264`, `458-482`, `129-130`, `170-174` |
|
||
| 286 | `Event On Initialized` (`Event_0`) → `Cast To GI` (`DynamicCast_1`, objet `GetGameInstance`) → `Set GI` (`VariableSet_27`) ; `Event Construct` conserve son affectation | `Event_0 ('OnInitialized').then → DynamicCast_1.execute` ; `Object ← CallFunction_66 (GetGameInstance)` ; `DynamicCast_1.then → VariableSet_27 (GI ← AsGI)` ; `then` vide ; `Event_1 ('Construct').then → DynamicCast_0` conservé (affectation de `Construct` supposée inchangée : estimé) | OK (câblage) | `MainMenu__EventGraph.txt:1875-1894`, `121-123` |
|
||
| 288 (SearchByAmenitySafe) | `IsValid(CurrentCityExpansion)` `CallFunction_8` ; `IfThenElse_7` après `IfThenElse_5.then` : valide → `VariableSet_3`, sinon `IfThenElse_2` ; `IfThenElse_8` après `IfThenElse_5.else` : valide → `IfThenElse_6`, sinon `FunctionResult_0` | `IfThenElse_5.then → IfThenElse_7.execute`, `else → IfThenElse_8.execute` (l.272-273) ; `CallFunction_8` (`Object ← GI.CurrentCityExpansion`) alimente `IfThenElse_7` et `_8` ; `IfThenElse_7 : then → VariableSet_3, else → IfThenElse_2` ; `IfThenElse_8 : then → IfThenElse_6, else → FunctionResult_0` | OK | `StreetMap_Static__SearchByAmenitySafe.txt:269-273`, `294-296`, `318-331` |
|
||
| 288 (findNearbyBuilding) | `IsValid` `CallFunction_7` ; `IfThenElse_8` sur `IfThenElse_0.else` : valide → `VariableSet_2`, sinon `IfThenElse_4` | `IfThenElse_0.else → IfThenElse_8.execute` (l.152) ; `CallFunction_7 (Object ← CurrentCityExpansion).ReturnValue → IfThenElse_8.Condition` ; `then → VariableSet_2.execute` ; `else → IfThenElse_4.execute` ; `IfThenElse_4.execute ← IfThenElse_8.else` | OK | `StreetMap_Static__findNearbyBuilding.txt:148-153`, `285-289`, `385-393` |
|
||
| 288 (PlayBGA) | `CallFunction_144` `IsValid(BGA)` ; `IfThenElse_38` après `IfThenElse_22.then` : non valide → `SwitchString_3` ; `IfThenElse_39` après `IfThenElse_22.else` : valide → `Stop` `CallFunction_134`, sinon fin ; `IfThenElse_40` devant `Stop` `CallFunction_124` (entrées `SwitchString_3.Default` et `IfThenElse_21.then`) : non valide → `SpawnSound2D` `CallFunction_110` | `IfThenElse_22.then → IfThenElse_38`, `.else → IfThenElse_39` ; `IfThenElse_38 : then → IfThenElse_23, else → SwitchString_3.execute` ; `IfThenElse_39 : then → CallFunction_134, else` vide ; `IfThenElse_40.execute ← SwitchString_3.Default, IfThenElse_21.then ; then → CallFunction_124, else → CallFunction_110` ; `CallFunction_144 (Object ← BGA)` alimente 38, 39, 40 ; `Stop` 134 et 124 ciblent `BGA` | OK | `StreetMap_Static__EventGraph.txt:5540-5547`, `5562-5568`, `5580-5583`, `5600-5604`, `5620-5624`, `6080-6098` |
|
||
| 289 | `IfThenElse_1` sur `IsValidIndex(BuildingPoints, 1)` (`CallArrayFunction_0`) entre `VariableSet_1` (`len`) et `VariableSet_2` ; vrai → chemin existant ; faux → `VariableSet_0` = `Strings[0]` (`GetArrayItem_3`) → `PrintString` → `FunctionResult_0` | `VariableSet_1.then → IfThenElse_1.execute` ; `Condition ← CallArrayFunction_0` (`BreakStruct_0.BuildingPoints`, `IndexToTest 1`) ; `then → VariableSet_2.execute` ; `else → VariableSet_0.execute` ; `VariableSet_0.string ← GetArrayItem_3.Output` (STA : `GetArrayItem_3`, `Dimension 1 = 0`, tableau `Strings`) ; `VariableSet_0.then → CallFunction_10 (PrintString).execute` ; `PrintString.then → FunctionResult_0` | OK | `Room__pickPresetWorld.txt:128-130`, `191-193`, `206-210`, `278-292` |
|
||
| 290 (determinePersonVars) | `IfThenElse_7` sur `IsValid(currentMatchRace)` (`CallFunction_32`) entre l'entrée et `getRace` ; non valide → `VariableSet_27` (`Dice`), `getRace` et `getEthnicity` sautés | `FunctionEntry_0.then → IfThenElse_7.execute` ; `Condition ← CallFunction_32 (Object ← currentMatchRace)` ; `then → CallFunction_18 (getRace)` (→ `CallFunction_28 (getEthnicity)` → `VariableSet_27`) ; `else → VariableSet_27.execute` (`Dice ← RandomFloat`) | OK | `GI__determinePersonVars.txt:122`, `142-145`, `558-565`, `587-595` |
|
||
| 290 (clearScenePersons) | `CumOn(['Clear'])` `CallFunction_4` réduit à `PlayerCharacter` ; `IfThenElse_6` sur `IsValid(Companion)` → nouveau `CumOn` `CallFunction_6` ; `IfThenElse_7` sur `IsValid(Interacting)` → nouveau `CumOn` `CallFunction_15` ; avant `CallFunction_5` | `CallFunction_4 (self ← PlayerCharacter, Wheres = MakeArray ['Clear']).then → IfThenElse_6` ; `IfThenElse_6 (Condition ← CallFunction_16 : Object = Companion) : then → CallFunction_6 (self ← Companion), else → IfThenElse_7` ; `CallFunction_6.then → IfThenElse_7` ; `IfThenElse_7 (Condition ← CallFunction_17 : Object = Interacting) : then → CallFunction_15 (self ← Interacting), else → CallFunction_5 (secondScreen)` ; `CallFunction_15.then → CallFunction_5` ; le même `MakeArray_1` alimente les trois `CumOn` | OK | `GI__clearScenePersons.txt:268-269`, `311-317`, `340-367` |
|
||
| 290 (EventGraph, clearDaily) | `clearDaily` `CallFunction_864` réduit à `PlayerCharacter` ; `IfThenElse_206` sur `IsValid(Interacting)` (`CallFunction_432`) → nouveau `clearDaily` `CallFunction_435` ; les deux chemins vers `MacroInstance_53` | `864 (self ← PlayerCharacter).then → IfThenElse_206` ; `Condition ← CallFunction_432 (Object ← Interacting)` ; `then → CallFunction_435 (self ← Interacting)` ; `else → MacroInstance_53.exec` ; `435.then → MacroInstance_53.exec` | OK | `GI__EventGraph.txt:26309-26314`, `26343-26347`, `30094-30106` |
|
||
| 290 (PlayIdle partenaire) | `PlayIdle` `CallFunction_866` derrière `IfThenElse_207` (même `IsValid`) | `IfThenElse_207.execute ← CallFunction_865.then ; Condition ← CallFunction_432 ; then → CallFunction_866.execute ; else` vide ; `866 (self ← Interacting)` | OK | `GI__EventGraph.txt:26325-26330`, `30107-30111` |
|
||
| 290 (PlayDaily) | `PlayDaily` `CallFunction_863` réduit à `PlayerCharacter` ; `IfThenElse_208` sur `IsValid(Interacting)` (`CallFunction_438`) → nouveau `PlayDaily` `CallFunction_441` (même `Anim`) ; deux chemins vers `IfThenElse_511` | `863 (self ← PlayerCharacter, Anim ← BreakStruct_103).then → IfThenElse_208` ; `Condition ← CallFunction_438 (Object ← Interacting)` ; `then → CallFunction_441 (self ← Interacting, Anim ← BreakStruct_103 : même broche)` ; `else → IfThenElse_511` ; `441.then → IfThenElse_511` ; `IfThenElse_511.execute ← IfThenElse_208.else, CallFunction_441.then` | OK | `GI__EventGraph.txt:26304-26308`, `30112-30125`, `6642-6646` |
|
||
| 290 (PerTick) | `IfThenElse_209` sur l'`IsValid(Interacting)` existant (`CallFunction_952`) avant `VariableSet_339` ; non valide → nouveau `VariableSet_392` = `SelectInt(12, 3, nuit)` (`CallFunction_445`, condition `CallFunction_950`), sans lire `Interacting.Valid` | `IfThenElse_209 (Condition ← CallFunction_952) : then → VariableSet_339 (PerTick ← CallFunction_949), else → VariableSet_392` ; `392.PerTick ← CallFunction_445 (SelectInt A = 12, B = 3, bPickA ← CallFunction_950 = InRange(CurrentTime, 0.0, 5.0))` ; `392.then → MacroInstance_39` (comme `339`) ; `BooleanAND_91` (lecture de `Interacting.Valid`) n'alimente que `BooleanOR_89` du chemin « valide » | OK | `GI__EventGraph.txt:27392-27428`, `30126-30142` |
|
||
| 291 | `IfThenElse_2` sur `IsValidIndex(GI.SexPersons, Array Index)` (`CallArrayFunction_2`) entre `LoopBody` de la boucle (`MacroInstance_1`) et la macro `IsValid` (`MacroInstance_2`) ; hors bornes → `VariableSet_1` | `MacroInstance_1 (ForEachLoop).LoopBody → IfThenElse_2.execute` ; `Condition ← CallArrayFunction_2` (`TargetArray` = `SexPersons`, `IndexToTest ← Array Index`) ; `then → MacroInstance_2.exec` ; `else → VariableSet_1.execute` (`Person` vide) ; `MacroInstance_2.Is Not Valid → VariableSet_1` conservé | OK | `SexInterface__EventGraph.txt:354-374`, `545-554` |
|
||
| 292 | `LPMapMarkersGuardSubsystem.cpp` : création par `NewObject` du composant `LPFocusWidgetComponent` retirée (22 → 3 lignes en fin de `Guard`) ; `.h` : commentaire mis à jour ; garde conservée pour retrait des entrées détruites, reconstitution et remise à zéro de `Vector2Ds` | `git diff 9f59fa6 7049121` lu en entier : `-` 22 lignes (création du composant, `AddValue`, journal), `+` 2 lignes de commentaire ; fonction `Guard` relue l.80-129 : boucle de retrait l.89-96, `ClearArrayProp(Vector2Ds)` l.104, reconstitution l.106-125, plus de `NewObject` ; `bLoggedOnce` encore utilisé l.119-121 ; build code 0, 0 avertissement (recompté § 3.1) ; fins de ligne CRLF conservées (`FileCheck` : `.cpp` CRLF 129 / LF 0, `.h` CRLF 31 / LF 0 ; référence avant lot 149 et 30 CRLF par `git show`, sans LF seul) | OK | `Source/LifePlay/LPMapMarkersGuardSubsystem.cpp:80-129` |
|
||
|
||
Bilan du tableau : 12 CHG (281 à 292), 22 lignes de contrôle, 22 OK, 0 écart.
|
||
|
||
## 4. Diff lu en entier
|
||
- Base `9f59fa6`, arrivée `7049121` : `git diff --stat` = 11 fichiers, 27 insertions, 24 suppressions ; `git rev-list --count 9f59fa6..7049121` = 12 commits (les 12 annoncés par la fiche : `ba4335d`, `cac5b2d`, `959bd8b`, `fcdaf24`, `ee2821a`, `2aa6f64`, `8a61361`, `281207f`, `17bf1c7`, `cdecfcc`, `476effb`, `7049121`), `git log --name-only` relu commit par commit : aucun fichier non annoncé (8a61361 = journal seul).
|
||
- Fichiers : 6 `.uasset` (`GI`, `Person`, `Room`, `StreetMap_Static`, `MainMenu`, `SexInterface`) ; `Journal_Modifications.md` (+12 lignes = CHG-281 à CHG-292) ; `LPMapMarkersGuardSubsystem.cpp` (+2 / −22), `.h` (+3 / −2) ; `LPStringCompat.cpp` (+5), `.h` (+5).
|
||
- Lus en entier : les 4 fichiers C++ (diff texte), le journal (12 lignes). Les 6 `.uasset` sont binaires : relus **par dump de graphe** (§ 3.2), pas par diff texte.
|
||
- Fins de ligne : `.\Tools\FileCheck.ps1 -Path …` : `LPMapMarkersGuardSubsystem.cpp` CRLF (129, LF 0), `.h` CRLF (31, LF 0), `LPStringCompat.cpp` LF (68, CRLF 0), `.h` LF (61, CRLF 0), `Journal_Modifications.md` LF (1270, CRLF 0), `Clothes4.txt` CRLF (956, LF 0) : `fichiers=… alertes=0`, code 0. Aucun BOM.
|
||
- Garde de version : aucun `UE_VERSION_OLDER_THAN` ajouté par le diff. `.uproject` inchangé.
|
||
- Fichier modifié par script : aucun indice (diff C++ propre, nombres de lignes cohérents avec les CHG).
|
||
|
||
Inventaire de ce que la VAL a produit (aucune modification de code, d'asset, de doc validée ni de config ; `git status --short` vide avant et après) :
|
||
- Dossier créé : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STB\dumps\` (15 fichiers copiés des résumés `RunCommandlet` par `cp -n`, sans modification de contenu).
|
||
- Résumés et journaux produits par les commandes, dossiers ignorés par git : `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STB\STB-VAL_*.txt` (CompileAllBlueprints, LPTestStringCompat, 15 LPDumpFunction, BuildLog `STB-VAL_BuildLog_20261009-213151.txt`) ; `D:\Game\LifePlay-master 5.8\Saved\Logs\portage\STB-VAL_*.log`.
|
||
- Ce livrable : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STB\STB-VAL.md`.
|
||
- Éditeur et jeu non lancés ; aucun build ; aucun commit.
|
||
|
||
## 5. Verdict
|
||
**PASS** pour les critères de la fiche § 8 (verdict global **VALIDÉ**) :
|
||
- `CompileAllBlueprints` : code 0, 0 erreur, 0 avertissement, 418 / 418 compilations réussies, égal à la référence STM-T4c (aucune nouvelle, aucune connue).
|
||
- `LPTestStringCompat` : 3120 / 0 / 60, code 0.
|
||
- Les 12 CHG (281 à 292) : chaque garde annoncée constatée dans un dump frais (22 lignes OK sur 22).
|
||
Nuance de portée (à ne pas confondre avec une preuve d'exécution) : la présence et le câblage des gardes sont **établis** par dumps rejoués ; leur **effet en jeu** (rafale `Floats_3`, ordre `OnInitialized` / liaisons, saccades R29, effet des espaces finaux de `Clothes4.txt`) n'est pas validé ici : reporté à STB-JEU.
|
||
|
||
Écarts et observations (numérotés) :
|
||
1. `LPDumpFunction -BP=GI -Fn=LoadSettings` : code 1, `LogLPDump: Error: Fonction 'LoadSettings' introuvable dans GI. Relancer sans -Fn pour lister.` (`dumps/GI__LoadSettings_ECHEC-fonction-introuvable.txt:7`). Explication établie : `LoadSettings` est un événement personnalisé de l'EventGraph (`GI__EventGraph.txt:8645`), pas une fonction ; la fiche prévoyait « graphe contenant l'appel ». Remplacé par le dump de `GI EventGraph` (code 0). Arrêt non déclenché (code ≠ 0 expliqué). Rien n'a été contourné.
|
||
2. HEAD a avancé pendant la VAL (`7049121` → `12d86d2`, deux commits Docs `EDIT3`, voir en-tête) : aucun impact sur le code ni les assets validés ; la ligne CHG relue (1134-1145) est celle de l'arbre au moment des dumps.
|
||
3. Les dumps livrés sont les résumés bruts de `RunCommandlet` (en-tête, agrégat des lignes, sortie, puis seconde copie `LogInit: Display:` des mêmes lignes), non filtrés au format `LogLPDump: Warning:` seul des dumps STA ; les numéros de ligne cités visent la première copie.
|
||
4. Comparaison aux dumps STA : par **compte de nœuds** et par lecture ciblée des nœuds du CHG, pas par `diff` textuel complet des fichiers (les graphes de 6 216 et 3 684 nœuds ne se comparent pas utilement en texte à cause des numéros de nœud). `GI__ConsolidateBeautyStandards` : seul le compte (16 = 16) a été comparé.
|
||
5. `Build.ps1 -FromLog` renvoie `code=-1` (pas de code dans un journal relu) ; le code 0 vient du livrable BUILD et de `Result: Succeeded` (journal l.51), pas de la relecture elle-même.
|
||
6. Gabarit amont : aucune fiche IMPL au gabarit pour GIA, PEA, PEB, MEN, SMS, ROO, GIC, SEX, MAP (le CHG en tient lieu, STB-TACHES.md) ; `STB-T0-BUILD.md` et `STB-GIB-DATA-INV.md` : sections non vérifiées une à une.
|
||
7. Le journal de LPTestStringCompat ne contient aucune ligne `Condition failed` (la fiche § 5 en attendait 20 préexistantes en culture française) : constat neutre, pas une régression.
|
||
|
||
## 6. Points à confirmer par l'utilisateur
|
||
- [ ] STB-JEU : rafale `array Floats_3` disparue (CHG-281) et résidu R02 éventuel.
|
||
- [ ] STB-JEU : plus de lecture hors bornes et plus d'erreurs « Accès à None » aux endroits corrigés (CHG-282, 284, 285, 288, 289, 290, 291), comparés à `STA-T1`.
|
||
- [ ] STB-JEU : `MainMenu` affecte bien `GI` avant les liaisons de `SpinBox` (CHG-286, R13 / R14).
|
||
- [ ] STB-JEU : disparition des saccades R29 sans composant de focus créé par la garde (CHG-292) ; ouverture de la carte (`FocusOnMapMarkers`) sans crash ni perte de focus clavier.
|
||
- [ ] STB-JEU : effet du retrait des 12 espaces finaux de `Clothes4.txt` (CHG-287, fichier hors dépôt).
|
||
- [ ] Décision orchestrateur : R06-R08 et R10 (CHG-290) restent à trancher ; risque `len = 0` de `pickPresetWorld` (CHG-289) non traité.
|
||
- [ ] Décision orchestrateur : consigner dans lp-build § 7 les 20 lignes UBT `does not list plugin` comme connues (proposition de STB-MAP-BUILD § 4).
|
||
|
||
## Constats
|
||
- Durées des commandlets : CompileAllBlueprints 208 s (STM-T4c : 228 s), LPTestStringCompat 16 s, LPDumpFunction 47 à 66 s chacun (15 dumps, un à la fois).
|
||
- Pic et tours : non mesurés par cette fiche (voir `Tools/FicheStats.py` à la clôture du lot).
|