LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2k-IMPL.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

213 lines
17 KiB
Markdown

Fiche CAM-B2k — Niveau N3 — Modèle prévu non précisé par la fiche | utilisé claude-opus-5-5 — Agent lp-mcp-bp (A-MCP-BP) — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot
# CAM-B2k-IMPL : recalage de la caméra C1 sur les yeux à chaque passage de la minuterie, Room enregistré (2026-10-14)
Résultat : **réussi**, en un passage dans l'éditeur headless déjà lancé par l'orchestrateur (pid 1272, port 8000).
- État lu conforme au tableau de la fiche ; 1 nœud créé (`K2_SetWorldLocation`) et 3 liens posés (L1 à L3).
- Relecture conforme ; compilation stricte sans diagnostic ; `save_assets` de Room seul.
- Room passe de `18565365…` à `6be71e01…`. PC, GI et Person sont inchangés et n'ont pas été chargés.
Spécification : `Docs/Migration/etat/CAM/CAM-B2k-FICHE.md` ; origine : `CAM-COMMUN5-DIAG.md` § 1 (C5-3). Préfixe des
nœuds : `/Game/BPs/Room.Room:EventGraph.`. Un seul appel MCP par message. Outils :
`editor_toolset.toolsets.asset.AssetTools` (AT) et `editor_toolset.toolsets.blueprint.BlueprintTools` (BT).
Abréviations : `SWL_512` = `K2Node_CallFunction_512` (nœud créé) ; `PO_n` = `K2Node_PromotableOperator_n` ; `8x`, `91` =
`K2Node_IfThenElse_8x`, `_91` ; `26x` = `K2Node_VariableGet_26x` ; `3xx`, `4xx` = `K2Node_CallFunction_xxx`.
PinID au format `{direction, index_id}` du nœud nommé.
## 1. Fichiers modifiés
- `Content/BPs/Room.uasset` : 1 nœud créé, 3 liens posés (aucun ne remplace un lien existant).
- MD5 `18565365b1195bf2416a1048bf9051b6` (6 387 514 octets) devient `6be71e0110c4187fa02d7ac9c1c92306`
(6 391 327 octets, 2026-10-14 01:01:51 locale).
- Seule sauvegarde du journal de l'éditeur : l. 2278, `LogFileHelpers: Saving Package: /Game/BPs/Room`.
- `Content/BPs/PC.uasset` = `a19510e613f31905437bab48f38c6154`, `Content/BPs/GI.uasset` =
`e64b5b37c9ef0db7735de0d6e3bd7c1c` et `Content/BPs/Person.uasset` = `8668a47c627f7a5254910cf0ac33b12a`, comme au
début. Aucun des trois n'a été chargé (13 appels au journal, tous listés au § 1.1).
- `git status` marque GI et Person `M` : déjà le cas au début de la session (lots précédents), pas de cette fiche.
- `Docs/Migration/etat/CAM/CAM-B2k-IMPL.md` : ce livrable.
### 1.1 Appels MCP, dans l'ordre
| # | Appel | Arguments | Retour |
|---|---|---|---|
| 1 | AT.`load_asset` | `{asset_path:"/Game/BPs/Room"}` | `{"refPath":"/Game/BPs/Room.Room"}` |
| 2 | BT.`get_node_infos` | `83`, `82`, `81`, `91`, `265`, `PO_2`, `PO_1`, `446`, `440`, `441` | état avant (§ 1.3) |
| 3 | BT.`get_node_infos` | `329`, `434`, `449`, `VariableSet_53`, `VariableSet_54`, `PO_0`, `269`, `258`, `261`, `447`, `448` | état avant (§ 1.3) |
| 4 | BT.`find_node_types` | `{graph:{refPath:"…:EventGraph"}, type_id_filter:"SetWorldLocation", context_pins:[265 {EGPD_Output,0}]}` | `["Transformation|SetWorldLocationAndRotation","Transformation|SetWorldLocation"]` |
| 5 | BT.`create_node` | `{graph:{refPath:"…:EventGraph"}, type_id:"Transformation|SetWorldLocation", pos:{x:31550,y:3800}}` | `{"refPath":"…K2Node_CallFunction_512"}` |
| 6 | BT.`get_node_infos` | `SWL_512` | broches identiques à 446 (§ 1.2), toutes libres |
| 7 | BT.`connect_pins` (L1) | `83 {EGPD_Output,0}` (then) → `SWL_512 {EGPD_Input,0}` (execute) | `null` |
| 8 | BT.`connect_pins` (L2) | `265 {EGPD_Output,0}` (FirstPersonSM) → `SWL_512 {EGPD_Input,1}` (self) | `null` |
| 9 | BT.`connect_pins` (L3) | `PO_2 {EGPD_Output,0}` (ReturnValue) → `SWL_512 {EGPD_Input,2}` (NewLocation) | `null` |
| 10 | BT.`get_node_infos` | `SWL_512`, `83`, `265`, `PO_2`, `446`, `81`, `82`, `91`, `440`, `441` | relecture conforme (§ 1.3, § 1.4) |
| 11 | AT.`is_dirty` | `{asset_path:"/Game/BPs/Room"}` | `true` |
| 12 | BT.`compile_blueprint` | `{blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true}` | `null` (pas d'exception) |
| 13 | AT.`save_assets` | `{asset_paths:["/Game/BPs/Room"]}` | `true`, confirmé par le journal et le MD5 |
Aucun `break_pins`, `delete_node` ni `set_pin_value`. Aucune écriture par HyperAIStudio. Aucun autre asset chargé.
Le journal de l'éditeur compte exactement 13 lignes `Dispatching toolset tool` (l. 2234 à 2276), une par appel
ci-dessus, dans le même ordre.
### 1.2 Nœud créé
| Nœud | refPath | type_id | Position |
|---|---|---|---|
| `K2_SetWorldLocation` | `/Game/BPs/Room.Room:EventGraph.K2Node_CallFunction_512` | `Transformation|SetWorldLocation` | (31550, 3800), à droite de 83 (31200, 4100), au-dessus de 440 (31600, 4300) |
Broches de `SWL_512` (appel 6), identiques en nom, type et index à celles de 446 :
- entrées : execute `{EGPD_Input,0}`, self `{EGPD_Input,1}` (`Scene Component Référence d'objet`), NewLocation
`{EGPD_Input,2}` (Vector, `0, 0, 0`), bSweep `{EGPD_Input,3}` = `false`, bTeleport `{EGPD_Input,4}` = `false` ;
- sorties : then `{EGPD_Output,0}`, SweepHitResult `{EGPD_Output,1}`.
Type : même `type_id` que 446, que le dump de référence donne pour `SceneComponent::K2_SetWorldLocation()`
(`CAM-B2i-VAL_LPDumpFunction_20261013-225125.txt` l. 9937). Que `SWL_512` appelle bien cette fonction est **estimé**
(même `type_id`, même broche self `Scene Component`, mêmes broches) : le dump de V5 le tranchera.
Le nom `K2Node_CallFunction_512` est absent du dump de référence (Grep, 0 occurrence) : il apparaîtra comme nœud
nouveau au diff de V5.
### 1.3 État lu avant écriture (appels 2 et 3), comparé au tableau de la fiche
| Nœud | Lu | Tableau |
|---|---|---|
| `83` Branche (31200, 4100) | execute ← `82` [0] ; Condition `{EGPD_Input,1}` ← `PO_0` [0] ; then `{EGPD_Output,0}` **vide** ; else `{EGPD_Output,1}` → `440` [0] | conforme |
| `PO_0` `Equal(Object)` | A ← `CallFunction_439` [0] ; B ← `261` [0] (`PlayerCharacter`) ; sortie → `83` [1] seul | conforme (vue = `PlayerCharacter`, 439 non relu, § 4) |
| `82` Branche | Condition ← `269` (`|GetCamC1On`) ; execute ← `81` else [1] ; then → `83` ; else → `440` | conforme |
| `81` Branche | Condition ← `258` (`|GetSexOn`, self ← `VariableGet_257`) ; execute ← `91` else [1] ; then vide ; else → `82` | conforme |
| `91` Branche | Condition ← `PO_8` ; execute ← `CustomEvent_45` [1] ; then → `IfThenElse_92` ; else → `81` | conforme |
| `265` `|GetFirstPersonSM` | self ← `261` [0] (`|GetPlayerCharacter`) ; FirstPersonSM `{EGPD_Output,0}` → 430, 431, 433, 446 `[1]` (self) | conforme |
| `PO_2` `vector*vector` (31450, 1050) | A ← `PO_1` [0] ; B = `0.5,0.5,0.5` ; ReturnValue `{EGPD_Output,0}` → `446` [2] (NewLocation) seul | conforme |
| `PO_1` `vector+vector` | A ← `447` (`GetSocketLocation`, `lEye`) ; B ← `448` (`GetSocketLocation`, `rEye`), tous deux self ← `264` | conforme |
| `446` `SetWorldLocation` (31600, 450) | execute ← `431` [0] ; self ← `265` ; NewLocation ← `PO_2` ; bSweep, bTeleport `false` ; then → `433` | conforme |
| `440` `|RestoreC1` (31600, 4300) | execute ← `83` else, `82` else ; then → `441` | conforme |
| `441` `ClearandInvalidateTimerbyHandle` | execute ← `440` ; Handle ← `VariableGet_274` ; then vide | conforme |
| Minuterie en C1 | `VariableSet_53` (`|SetC1Hidden`, valeur `true`) → `449` (`DelayUntilNextFrame`) → `434` (`SetViewTargetWithBlend`, NewViewTarget ← `261`) → `329` (`SetTimerbyEvent`, Delegate ← `CustomEvent_45`, Time `0.016`, bLooping `true`) → `VariableSet_54` (`|SetRoomCamTimer`, valeur ← `329` ReturnValue) | conforme |
Liens hors tableau, lus et laissés tels quels : `434.execute` ← aussi `IfThenElse_80` ; `329.execute` ← aussi
`CallFunction_94` ; `82.else` → `440`. Le tableau ne les exclut pas : aucun écart, pas d'arrêt.
### 1.4 Relecture (appel 10) : avant et après
| Broche (PinID) | Avant | Après |
|---|---|---|
| `83` then `{EGPD_Output,0}` | vide | **→ `SWL_512` [0]** |
| `83` else `{EGPD_Output,1}` / execute / Condition | → `440` / ← `82` / ← `PO_0` | identique |
| `265` FirstPersonSM `{EGPD_Output,0}` | → 430, 431, 433, 446 `[1]` | → 430, 431, 433, 446, **`SWL_512`** `[1]` (5 liens) ; self ← `261` identique |
| `PO_2` ReturnValue `{EGPD_Output,0}` | → `446` [2] | → `446` [2], **`SWL_512` [2]** ; A ← `PO_1`, B `0.5,0.5,0.5` identiques |
| `446` | execute ← 431, self ← 265, NewLocation ← PO_2, then → 433 | identique |
| `SWL_512` execute / self / NewLocation | absent | ← `83` [0] / ← `265` [0] / ← `PO_2` [0] |
| `SWL_512` then `{EGPD_Output,0}` / SweepHitResult | absent | libre / libre ; bSweep, bTeleport `false` |
| `81`, `82`, `91`, `440`, `441` | § 1.3 | identiques, broche par broche |
Garde `Accessed None` (lp-mcp § 1 règle 4) : aucun `IsValid` ajouté, la fiche n'en prévoit pas.
- `SWL_512` lit `265` (`PlayerCharacter.FirstPersonSM`) et `PO_2` (`GetSocketLocation` sur `264`, self ← `261`). Ce
sont les lectures que la voie C1 d'`ApplyRoomCamera` fait déjà par 430, 431, 433, 446, 447 et 448.
- Estimé sans risque nouveau dans le cas normal : 83.then ne s'exécute que si la vue = `PlayerCharacter`. Cas limite
non vérifié : `PlayerCharacter` nul et vue nulle en même temps (`Equal(Object)` vrai sur deux nulls). Repris en § 5.
- Comportement voulu par la fiche : hors sexe, en C1, vue sur le joueur, chaque passage de la minuterie (0,016 s)
recale `FirstPersonSM` sur le milieu des yeux ; `else` (vue ailleurs) → `RestoreC1` inchangé ; sexe et C2 inchangés
(81, 82, 91 non touchés).
### 1.5 Compilation et sauvegarde (journal `D:\Game\LifePlay_Backup_5.5\CAM-B2kmn\editeur\editeur-B2kmn.log`)
- 2046 lignes au début de la fiche, 2270 avant la compilation, aucune ligne `Saving Package` avant.
- Après l'appel 12 : l. 2273, `LogBlueprint: Compiling Blueprint '/Game/BPs/Room.Room'`. Puis 0 ligne `error` ou
`warning` (insensible à la casse) de la l. 2271 à la fin (l. 2308), sauvegarde et validation comprises.
- `hyper_blueprint_debug_inspect` n'a pas été appelé : il est absent du serveur (repli prévu : `warnings_as_errors`
et le journal).
- Sauvegarde, l. 2278 : `Saving Package: /Game/BPs/Room`. Puis `Moving '…/Saved/Room2E880115405C4A4C093C3A9251FC3A32.tmp'
to '…/Content/BPs/Room.uasset'` et `AssetCheck: /Game/BPs/Room Validation de la ressource`. Le journal n'a pas
d'autre ligne `Saving Package`.
- Entre les l. 2047 et 2270 (avant la compilation), 4 lignes d'erreur, toutes du transport MCP (Constats), aucune de
Blueprint.
## 2. Écarts à la SPEC
- Aucun écart sur l'état lu, le type, le nœud, les liens ni la relecture.
- Position : la fiche dit « près de 83 (à droite de sa branche then) ». Valeur choisie au § 1.2.
- Instantané : la fiche prévoit le lot `CAM-B2k` ; l'orchestrateur l'a pris sous `CAM-B2kmn` (Room et PC). Le dossier
`D:\Game\LifePlay_Backup_5.5\CAM-B2k` n'existe pas (`ls -d …/CAM-B2k*` ne rend que `CAM-B2kmn`). Le retour arrière
de la fiche (`-Lot CAM-B2k`) est donc à lire `-Lot CAM-B2kmn` (§ 3).
- PC, GI et Person n'ont pas été ouverts. Ni build, ni commandlet, ni jeu. L'éditeur n'a été ni lancé ni arrêté.
## 3. Instantané
- `D:\Game\LifePlay_Backup_5.5\CAM-B2kmn\manifest.csv` (pris par l'orchestrateur), relu :
`"Content\BPs\Room.uasset","True","6387514","18565365B1195BF2416A1048BF9051B6","2026-10-14T00:59:11"` et
`"Content\BPs\PC.uasset","True","3404928","A19510E613F31905437BAB48F38C6154","2026-10-14T00:59:11"`.
- MD5 sur le disque avant l'appel 1 = ceux du manifeste.
- Retour arrière **proposé, non lancé**, par l'orchestrateur, éditeur fermé, sur accord (Room seul : PC est traité
par la fiche suivante sur le même instantané) :
1. `.\Tools\Snapshot.ps1 -Lot CAM-B2kmn-retour -Path Content\BPs\Room.uasset` ;
2. `.\Tools\Restore.ps1 -Lot CAM-B2kmn -Only Content\BPs\Room.uasset -WhatIf` ;
3. `.\Tools\Restore.ps1 -Lot CAM-B2kmn -Only Content\BPs\Room.uasset`.
Contrôle : `md5sum Content/BPs/Room.uasset` = `18565365…`.
- Entrée : `2026-10-14 | CAM-B2k, recalage C1 sur les yeux (83.then → K2_SetWorldLocation) | Content/BPs/Room.uasset |
retour arrière : Restore.ps1 -Lot CAM-B2kmn -Only Content\BPs\Room.uasset | instantané :
D:\Game\LifePlay_Backup_5.5\CAM-B2kmn | vérification : relecture conforme, compilation stricte 0 diagnostic,
Room = 6be71e01…`.
## 4. Ce qui n'a pas été fait
- Le nombre de nœuds de Room (V5 : 1265 attendu) n'a pas été compté ; `find_nodes` n'a pas été appelé (aucun nœud
supprimé dans cette fiche).
- `CallFunction_439` (source de la vue pour `PO_0` et `PO_8`) et `CustomEvent_45` (événement `UpdateRoomCam` selon
`CAM-B2i-IMPL.md` § 1.4) n'ont pas été relus ici.
- `is_dirty` n'a pas été relu après la sauvegarde (la fiche ne le demande pas).
- `CompileAllBlueprints` éditeur fermé, build empaqueté, `LogStats`, essai en jeu : hors fiche (lp-mcp § 1 règles 3 et 5).
- PC non touché (fiche suivante). L'éditeur n'est pas fermé (rôle de l'orchestrateur, puis `BUILD-FIN`).
## 5. Points à confirmer en VAL
- Room = `6be71e0110c4187fa02d7ac9c1c92306` ; PC = `a19510e6…`, GI = `e64b5b37…` et Person = `8668a47c…` inchangés
(PC peut avoir changé d'ici là par la fiche suivante : comparer à son IMPL).
- V5 : EventGraph à 1265 nœuds (non compté ici).
- V5, diff de Room limité à :
- 1 nœud nouveau : `K2Node_CallFunction_512`, appel `SceneComponent::K2_SetWorldLocation()`, bSweep et bTeleport
`false` ;
- `83.then` → `_512.execute` ; sorties de `265.FirstPersonSM` (430, 431, 433, 446, `_512`) et de `PO_2` (446, `_512`).
- `83.else`, Condition de 83, et les liens de 81, 82, 91, 440, 441 et 446 inchangés.
- V6 : `CompileAllBlueprints` éditeur fermé = référence (Room compilé sans erreur ni avertissement nouveau).
- V7 (COMMUN-6) : cas de la fiche ; en plus, `LogStats` sans `Accessed None` nouveau sur `Room` / `UpdateRoomCam`
(cas limite `PlayerCharacter` nul, § 1.4).
## 6. Fichiers à commiter
- M `Content/BPs/Room.uasset` (dépôt du jeu, branche ue5.8).
- A `Docs/Migration/etat/CAM/CAM-B2k-IMPL.md` (dépôt du jeu, branche ue5.8).
- Pas GI ni Person : leur `M` vient de lots antérieurs. Pas PC : inchangé ici.
## Mesuré
```
$ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset Content/BPs/PC.uasset (avant l'appel 1)
18565365b1195bf2416a1048bf9051b6 *Content/BPs/Room.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
a19510e613f31905437bab48f38c6154 *Content/BPs/PC.uasset
$ wc -l editeur-B2kmn.log (avant l'appel 1)
2046 /d/Game/LifePlay_Backup_5.5/CAM-B2kmn/editeur/editeur-B2kmn.log
$ wc -l editeur-B2kmn.log ; grep -c "Saving Package" editeur-B2kmn.log (avant l'appel 12)
2270 /d/Game/LifePlay_Backup_5.5/CAM-B2kmn/editeur/editeur-B2kmn.log
0
$ tail -n +2271 editeur-B2kmn.log | grep -ciE "error|warning" (après les appels 12 et 13)
0
$ grep -n "Saving Package" editeur-B2kmn.log (après l'appel 13)
2278:[2026.10.13-23.01.50:880][326]LogFileHelpers: Saving Package: /Game/BPs/Room
$ md5sum Content/BPs/Room.uasset Content/BPs/PC.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset (après l'appel 13)
6be71e0110c4187fa02d7ac9c1c92306 *Content/BPs/Room.uasset
a19510e613f31905437bab48f38c6154 *Content/BPs/PC.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
$ stat -c "%s %y" Content/BPs/Room.uasset Content/BPs/PC.uasset
6391327 2026-10-14 01:01:51.899749700 +0200
3404928 2026-10-13 08:54:05.738841800 +0200
$ git status --short -- Content/BPs/
M Content/BPs/GI.uasset
M Content/BPs/Person.uasset
M Content/BPs/Room.uasset
```
Tours : 25 / 60
## Constats
- Transport MCP : 4 lignes d'erreur au journal juste avant et pendant l'appel 1, toutes du protocole, aucune de
Blueprint : l. 2141 (23:00:15 UTC) `LogModelContextProtocol: Error: Unknown session id '…' for 'tools/call'; client
should reinitialize`, puis l. 2222, 2223 et 2241 `Call to unknown method "server/discover"`. L'appel 1 a été
distribué à la l. 2234 (23:00:17) et a répondu ; le message système « unreal-mcp encore en connexion » est apparu
après lui, comme en B2i. Estimé : la session partagée a été réinitialisée par le client, sans effet sur les 13 appels.
- À verser dans lp-mcp § 3 (vérifié aujourd'hui) :
- `type_id` de `SceneComponent::K2_SetWorldLocation` : `Transformation|SetWorldLocation` (filtre
`SetWorldLocation` avec `context_pins` sur une sortie de composant : 2 résultats, `…AndRotation` et celui-ci) ; il
se crée en `K2Node_CallFunction_<n>` avec bSweep et bTeleport `false` par défaut ;
- `create_node` peut réutiliser un numéro libre inférieur aux nœuds existants (`_512` alors que `_516` et `_518`
existent) : contrôler l'absence du nom dans le dump de référence avant V5.
- À verser dans lp-lot ou au gabarit de fiche lp-mcp-bp : quand l'instantané est partagé entre plusieurs fiches
(`CAM-B2kmn`), la commande de retour arrière de chaque fiche doit citer ce lot-là, avec `-Only`.