Fiche CAM-B2kmn-VAL — Niveau N1 — Modèle prévu non précisé par la demande | utilisé claude-sonnet-5-5 — Agent lp-validator (A-VAL) — Skills sk-protocol, sk-recount, debug-verification, lp-validate # CAM-B2kmn-VAL : validation des fiches CAM-B2k (Room, recalage C1), CAM-B2m (PC, lacet POV) et CAM-B2n (Room, orbite de scène) (2026-10-14) Verdict global : **PASS** (V5 Room, V5 PC, V6, MD5 et UeState rejoués à neuf, éditeur fermé). V7 (essai en jeu) n'est pas de cette VAL : reporté (COMMUN-6). Copie `D:\Game\LifePlay-master 5.8`, branche `ue5.8` (relevée par `git branch --show-current`). Aucun asset, code ni doc validée modifié par la VAL. Seuls fichiers écrits : les 3 sorties de commandlets (§ 3) et ce livrable. ## 1. Fiches amont relues - `CAM-B2k-FICHE.md`, `CAM-B2m-FICHE.md`, `CAM-B2n-FICHE.md` (avec l'amendement B2n-a : GetActorArrayAverageLocation dans le fil, opérateurs génériques `Soustraire` et `Ajouter`). - `CAM-B2k-IMPL.md` (25 / 60 tours), `CAM-B2m-IMPL.md` (23 / 60), `CAM-B2n-IMPL.md` (63 / 60). - Références de diff : `CAM-B2i-VAL_LPDumpFunction_20261013-225125.txt` (Room), `CAM-B1-VAL_LPDumpFunction_20261013-085611.txt` (PC), `CAM-B2i-VAL_CompileAllBlueprints_20261013-225336.txt` et son journal (V6). - Instantané d'avant : `D:\Game\LifePlay_Backup_5.5\CAM-B2kmn\` (manifeste, `Content\BPs\Room.uasset` et `PC.uasset`). Conformité des IMPL au gabarit IMPL de `lp-doc` : les 6 sections numérotées sont présentes dans les trois. Écarts de forme relevés (aucun ne touche au contenu validé) : - `CAM-B2n-IMPL.md` : 63 tours pour un budget de 60 (déclaré par l'auteur, sous le plafond de 75) ; ses « Constats » portent aussi la liste des appels MCP, des PinID et des liens, ce qui est permis. - `CAM-B2k-IMPL.md` et `CAM-B2m-IMPL.md` : « Modèle prévu non précisé par la fiche » ; section « Mesuré » hors gabarit mais utile. Pas d'écart bloquant. - Les trois fiches prévoient un instantané `-Lot CAM-B2k` / `-B2m` / `-B2n`. L'instantané réel est `CAM-B2kmn` (commun), signalé par chaque IMPL (§ 2). Retour arrière à lire `-Lot CAM-B2kmn -Only `. ## 2. Points à confirmer des IMPL | Id | Point (IMPL) | Verdict | Preuve | |---|---|---|---| | B2k-1 | Room = `6be71e01…` après B2k, PC / GI / Person inchangés | **Reporté pour `6be71e01…`** (état intermédiaire écrasé par B2n, non rejouable). PC / GI / Person : PASS | MD5 finaux § 3.4 ; le contenu de B2k est entièrement dans le diff V5 (B2k-3) | | B2k-2 | V5 : EventGraph à 1265 nœuds | **PASS (remplacé)** : 1272 attendu après B2n (1264 + 1 + 7) | `=== Room :: EventGraph (1272 noeuds) ===` ; réf. 1264 | | B2k-3 | Diff limité à `_512` (`SceneComponent::K2_SetWorldLocation()`, bSweep / bTeleport faux), `83.then → 512.execute`, sorties de 265 et de PO_2 | **PASS** | § 3.1 : 512 apparaît, `execute ← IfThenElse_83.then`, `self ← VariableGet_265.FirstPersonSM`, `NewLocation ← PromotableOperator_2.ReturnValue` ; 265 + 512.self ; PO_2 + 512.NewLocation | | B2k-4 | `83.else`, Condition de 83, liens de 81, 82, 91, 440, 441, 446 inchangés | **PASS** | aucun hunk sur ces nœuds ; `83.else → 440.execute` relu l. 9843 du dump | | B2k-5 | Nom `_512` absent de la référence | **PASS** | Grep `K2Node_CallFunction_512` sur la référence : 0 occurrence | | B2k-6 | V6 : Room compilé sans erreur ni avertissement nouveau | **PASS** | § 3.3 | | B2k-7 | V7 (C1 à hauteur des yeux ; `LogStats` sans `Accessed None` nouveau ; cas limite `PlayerCharacter` nul + vue nulle) | **Reporté** (essai en jeu COMMUN-6) | non rejoué | | B2m-1 | PC = `f45be57a…` ; Room, GI, Person inchangés | **PASS** | § 3.4 | | B2m-2 | V5 PC : 312 Yaw au lieu de Roll ; 136 then / else → 204 ; 951.execute vide ; 204.execute ← 136 (deux liens) ; aucun nœud nouveau ni supprimé | **PASS** | § 3.2 ; 1439 nœuds avant et après | | B2m-3 | 316, 164 et le reste de l'EventGraph inchangés | **PASS** | aucun autre hunk de corps | | B2m-4 | V6 : PC sans erreur ni avertissement nouveau malgré 951 mort | **PASS** | § 3.3 | | B2m-5 | V7 : sens du lacet (réserve `108.B` = 1), tangage 316 faux face à Y, `LogStats` | **Reporté** (essai en jeu) | non rejoué | | B2n-1 | 7 nœuds de plus : 101, 535 à 538, PO_46, PO_47 | **PASS** | § 3.1 ; 1264 → 1272 = 8 = 1 (512) + 7 | | B2n-2 | 14 liens de plus, `537.Axis` = (0, 0, 1) | **PASS** (liens) / **PASS-STATIC** (Axis) | § 3.1 : les 14 liens L1 à L13 (L11a + L11b) relus dans le dump. Axis relu `'0,0,1'`, alors que 497 porte `'0.0,0.0,1.0'` : même vecteur Z = 1 par lecture ; l'interprétation moteur de la chaîne `0,0,1` n'est pas rejouée en jeu (estimé) | | B2n-3 | Aucune autre différence ; 512 de B2k présent et inchangé | **PASS** | § 3.1 : 8 hunks de corps, tous attendus ; 512 identique aux § 1.4 de B2k | | B2n-4 | Conversion implicite `DeltaSeconds` (double) → `AngleDeg` (simple précision) sans diagnostic | **PASS** | Room compilé avec succès en V6, avertissements identiques (55 lignes, 42 signatures) | | B2n-5 | V6 = référence | **PASS** | § 3.3 | | B2n-6 | V7 (orbite pendant le sexe, hors sexe inchangé, `SexPersons` vide → orbite autour de l'origine) | **Reporté** (essai en jeu) | non rejoué | | B2n-7 | Sauvegarde automatique `Saved/Autosaves/Game/BPs/Room_Auto1.uasset` « à ignorer » | **Non vérifié** | hors périmètre (pas dans Content) | ## 3. Critères rejoués Environnement : éditeur fermé, `Tools\UeState.ps1 -Brief` avant et après : `processus=0 editeur=0 compilation=0 shaders=0 jeu=0` (UeState = 0). Moteur `D:\Game\Launcher\Engine\UE_5.8`. Lancement : `Tools\RunCommandlet.ps1 -Lot CAM-B2kmn-VAL … -EtatDir …\etat\CAM`. ### 3.0 MD5 de départ (avant tout lancement) ``` $ md5sum Content/BPs/Room.uasset Content/BPs/PC.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset 3a451fddf991ac01a699af7bd1fbdc12 *Content/BPs/Room.uasset f45be57a39d13d3eb19d0b543153ab0b *Content/BPs/PC.uasset e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset 8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset $ md5sum D:/Game/LifePlay_Backup_5.5/CAM-B2kmn/Content/BPs/*.uasset (instantané d'avant) a19510e613f31905437bab48f38c6154 *…/PC.uasset 18565365b1195bf2416a1048bf9051b6 *…/Room.uasset ``` Room et PC diffèrent de l'instantané ; Room = attendu `3A451FDD…`, PC = attendu `F45BE57A…`, GI et Person = attendus. ### 3.1 V5 Room : **PASS** Commande : `LPDumpFunction -BP=Room -Fn=* -Pins -Exec` ; code 0, 57 s, 0 erreur, 10 881 avertissements (le dump). Sortie : `Docs\Migration\etat\CAM\CAM-B2kmn-VAL_LPDumpFunction_20261014-011706.txt` (journal dans `Saved\Logs\portage\`). Diff : `git diff --no-index --unified=0 CAM-B2i-VAL_LPDumpFunction_20261013-225125.txt CAM-B2kmn-VAL_LPDumpFunction_20261014-011706.txt | grep -v '^[-+]LogInit:'` : 212 lignes. Les 138 premières sont l'en-tête (date, durée, histogramme des signatures d'avertissements, qui bouge avec le nombre de lignes : bruit). Corps (lignes 139 à 212), brut : ``` -=== Room :: EventGraph (1264 noeuds) === +=== Room :: EventGraph (1272 noeuds) === CustomEvent_1.DeltaSeconds + K2Node_CallFunction_537.AngleDeg CallFunction_149.then (vide) -> K2Node_IfThenElse_101.execute VariableGet_102.SceneCamera + K2Node_CallFunction_536.self, K2Node_CallFunction_538.self VariableGet_86.SexOn + K2Node_IfThenElse_101.Condition VariableGet_106.SexPersons + K2Node_CallFunction_535.Actors VariableGet_265.FirstPersonSM + K2Node_CallFunction_512.self IfThenElse_83.then (vide) -> K2Node_CallFunction_512.execute PromotableOperator_2.ReturnValue + K2Node_CallFunction_512.NewLocation + 45 lignes : blocs des 8 nœuds neufs (l. 10907 du nouveau dump) ``` Blocs neufs, relus l. 10907 à 10951 du nouveau dump : - `CallFunction_512` `SceneComponent::K2_SetWorldLocation()` : execute ← `IfThenElse_83.then`, then vide, self ← `VariableGet_265.FirstPersonSM`, NewLocation ← `PromotableOperator_2.ReturnValue`, bSweep et bTeleport `false`. - `IfThenElse_101` : execute ← `CallFunction_149.then`, Condition ← `VariableGet_86.SexOn`, then → `CallFunction_535.execute`, else vide. - `CallFunction_535` `GameplayStatics::GetActorArrayAverageLocation()` : execute ← `101.then`, then → `CallFunction_538.execute`, Actors ← `VariableGet_106.SexPersons`, ReturnValue → `PromotableOperator_46.B`, `PromotableOperator_47.A`. - `CallFunction_536` `K2_GetActorLocation()` : self ← `VariableGet_102.SceneCamera`, ReturnValue → `PromotableOperator_46.A`. - `PromotableOperator_46` `Subtract_VectorVector()` : A ← 536, B ← 535, ReturnValue → `CallFunction_537.InVect` (536 moins 535). - `CallFunction_537` `RotateAngleAxis()` : InVect ← 46, AngleDeg ← `CustomEvent_1.DeltaSeconds`, Axis `'0,0,1'`, ReturnValue → `PromotableOperator_47.B`. - `PromotableOperator_47` `Add_VectorVector()` : A ← 535, B ← 537, ReturnValue → `CallFunction_538.NewLocation` (535 plus 537). - `CallFunction_538` `K2_SetActorLocation()` : execute ← `535.then`, then vide, self ← `VariableGet_102.SceneCamera`, NewLocation ← 47, bSweep et bTeleport `false`. Contrôles complémentaires : - Compte : 1264 + 8 = 1272 (512, 101, 535, 536, 537, 538, PO_46, PO_47), recompté par 8 blocs neufs. - Absence de `_512` dans la référence : Grep, 0 occurrence ; 4 dans le nouveau dump (3 liens + le bloc). - Aucun hunk sur 19, 26, 29, 96, `MacroInstance_13`, 153 : liens inchangés (149 : execute ← `19.else` inchangé, relu l. 5491). - Aucune autre fonction de Room changée (aucun hunk hors EventGraph). - 149.then est passé de vide à `101.execute` seulement, conformément à L1. ### 3.2 V5 PC : **PASS** Commande : `LPDumpFunction -BP=PC -Fn=EventGraph -Pins -Exec` ; code 0, 58 s, 0 erreur, 6 410 avertissements (identique à B1). Sortie : `…\CAM-B2kmn-VAL_LPDumpFunction_20261014-011816.txt`. Référence B1 : une seule section `PC :: EventGraph (1439 noeuds)` (deux fois dans le fichier, la seconde en `LogInit:` retirée par le filtre), aucun autre graphe ; nouveau dump : même section, 1439 nœuds. Diff `grep -v '^[-+]LogInit:'`, corps brut (après l'en-tête, qui ne porte que des histogrammes de signatures) : ``` - Roll -> K2Node_CommutativeAssociativeBinaryOperator_108.ReturnValue (312) + Roll = '0.0' - Yaw = '0.0' + Yaw -> K2Node_CommutativeAssociativeBinaryOperator_108.ReturnValue - execute (vide) (204) + execute -> K2Node_IfThenElse_136.then, K2Node_IfThenElse_136.else - then -> K2Node_CallFunction_951.execute (136) - else -> K2Node_CallFunction_951.execute + then -> K2Node_CallFunction_204.execute + else -> K2Node_CallFunction_204.execute - execute -> K2Node_IfThenElse_136.then, K2Node_IfThenElse_136.else (951) + execute (vide) - ReturnValue -> K2Node_CallFunction_312.Roll (108) + ReturnValue -> K2Node_CallFunction_312.Yaw ``` Les nœuds portant chaque hunk ont été relus dans le nouveau dump (l. 1847 à 1852 pour 312, 1889 à 1893 pour 204, 2000 à 2004 pour 136, 2035 à 2039 pour 951, 2043 à 2047 pour 108). 312 : Yaw ← 108, Roll `0.0` non relié, ReturnValue → 204.DeltaRotation et 951.DeltaRotation ; 204 : self ← `VariableGet_67.FirstPersonSM`, DeltaRotation ← 312, then vide. Rien d'autre : écart au résultat attendu = 0. Le PC de la référence B1 est supposé `A19510E6…` (dit par la fiche B2m, non prouvable sur le fichier texte) ; le diff, limité aux seuls changements de B2m, est cohérent avec cela. ### 3.3 V6 : **PASS** Commande : `CompileAllBlueprints` ; code 3 (comme la référence : le code reflète les 3 erreurs de `CR_FaceExpRig`), 228 s, 25 lignes d'erreur, 55 lignes d'avertissement. Sortie : `…\CAM-B2kmn-VAL_CompileAllBlueprints_20261014-011924.txt`. ``` $ grep "Compiling Completed" (référence B2i et nouveau) Compiling Completed with 3 errors and 0 warnings and 0 blueprints that failed to load. (les deux) $ grep -c "Loading and Compiling" : 421 (réf.) 421 (nouveau) $ grep -c "La compilation de .* a réussi" : 420 (réf.) 420 (nouveau) $ liste triée des 'Loading and Compiling' (sans horodatage) : diff réf. contre nouveau = vide $ diff <(sed -n 6,40p réf.) <(sed -n 6,40p nouveau) : identiques (Erreurs : 25 lignes, 16 signatures ; Avertissements : 55 lignes, 42 signatures) GI, Person, PC, Room : « La compilation de … a réussi ! » (l. 1963, 1984, 2018, 2021 du journal) ``` La 421e entrée est `CR_FaceExpRig` (moteur, 3 erreurs). Les 16 signatures d'erreur sont toutes `CR_FaceExpRig` / `RLExpStruct` / `RLConstraintStruct` / « Could not find graph function data » : aucune ligne d'erreur d'un Blueprint du jeu. Le diff brut des deux résumés ne diffère que par les horodatages, les durées de compilation et la ligne de commande. ### 3.4 Fin : MD5 et UeState : **PASS** ``` $ md5sum Content/BPs/Room.uasset Content/BPs/PC.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset (après les commandlets) 3a451fddf991ac01a699af7bd1fbdc12 *Content/BPs/Room.uasset f45be57a39d13d3eb19d0b543153ab0b *Content/BPs/PC.uasset e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset 8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset $ Tools\UeState.ps1 -Brief (après) processus=0 editeur=0 compilation=0 shaders=0 jeu=0 ``` Les commandlets n'ont modifié aucun des 4 assets. `git status` : Room, PC, GI, Person `M` (déjà modifiés avant la VAL). ## 4. Diff lu en entier - Room : diff du corps du dump, 8 hunks de liens existants + 1 bloc de 45 lignes ajoutées + l'en-tête de graphe (§ 3.1). - PC : 6 hunks de corps (§ 3.2). - Fichiers de contenu lus : `Content/BPs/Room.uasset` et `PC.uasset` (binaires, lus par dump), `GI`/`Person` (MD5 seul). - Aucun fichier de code C++ n'est dans ces fiches. Fichiers non annoncés produits par la VAL : aucun hors § 3. - Fins de ligne des fichiers écrits : mon livrable en LF ; les trois sorties de commandlets sont celles de `RunCommandlet.ps1` (CRLF, `FileCheck.ps1` : alertes = 0). ## 5. Verdict **PASS** - V5 Room : PASS. V5 PC : PASS. V6 : PASS. MD5 : PASS. UeState = 0 : PASS. - PASS-STATIC (limité) : la chaîne d'axe `0,0,1` de `537.Axis` (lecture du dump, pas d'essai en jeu). - Non rejoué : V7 et `LogStats` (essais en jeu), état intermédiaire `6be71e01…` de Room, sens du lacet de B2m, tangage 316. ## 6. Points à confirmer par l'utilisateur - [ ] V7 (COMMUN-6) pour B2k : C1 à hauteur des yeux (assis, levé, marche, rassis, changement de pièce) ; C2 et sexe inchangés. - [ ] V7 pour B2m : lacet POV à la souris sans pente ; sens non inversé (sinon `set_pin_value 108.B = 1`) ; tangage 316 faux face à Y, connu, non traité. - [ ] V7 pour B2n : orbite autour du couple pendant le sexe, cadrage conservé ; cas `SexPersons` vide pendant `SexOn` (orbite autour de l'origine) ; limite C2 → sexe (vue restant sur `CamRoom`, fiche B2o éventuelle). - [ ] Ticket au gardien : `Room.uasset` contient B2k et B2n inséparables ; PC.uasset pour B2m ; l'instantané est `CAM-B2kmn`. - [ ] Sauvegarde automatique `Saved/Autosaves/Game/BPs/Room_Auto1.uasset` : à ignorer ou nettoyer (non vérifiée). ## Fichiers à commiter - A `Docs/Migration/etat/CAM/CAM-B2kmn-VAL.md` - A `Docs/Migration/etat/CAM/CAM-B2kmn-VAL_LPDumpFunction_20261014-011706.txt` - A `Docs/Migration/etat/CAM/CAM-B2kmn-VAL_LPDumpFunction_20261014-011816.txt` - A `Docs/Migration/etat/CAM/CAM-B2kmn-VAL_CompileAllBlueprints_20261014-011924.txt` - (Les journaux bruts restent dans `Saved/Logs/portage/`, non suivis.) Tours : 22 / 40 ## Constats - Le dump `LPDumpFunction` de PC ne contient que `EventGraph` quand `-Fn=EventGraph` ; le même nom de section apparaît deux fois dans le fichier (une fois préfixé `LogInit: Display:`), d'où le filtre `grep -v '^[-+]LogInit:'` du diff. - Un hook du poste refuse à `lp-validator` toute redirection de sortie de Bash vers le dossier temporaire de session : les diffs ont été affichés sans fichier intermédiaire. - Intervalle d'un gabarit à l'autre : le nom de nœud `_512` réutilisé (numéro libre sous des nœuds existants) a été contrôlé absent de la référence, comme le recommande l'IMPL B2k.