17 KiB
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_assetsde 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) devient6be71e0110c4187fa02d7ac9c1c92306(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.
- MD5
Content/BPs/PC.uasset=a19510e613f31905437bab48f38c6154,Content/BPs/GI.uasset=e64b5b37c9ef0db7735de0d6e3bd7c1cetContent/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 statusmarque GI et PersonM: 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 |
| 5 | BT.create_node |
`{graph:{refPath:"…:EventGraph"}, type_id:"Transformation | SetWorldLocation", pos:{x:31550,y:3800}}` |
| 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` |
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 ← 81else [1] ; then →83; else →440` |
81 Branche |
Condition ← 258 (` |
GetSexOn, self ← VariableGet_257) ; execute ← 91else [1] ; then vide ; else →82` |
91 Branche |
Condition ← PO_8 ; execute ← CustomEvent_45 [1] ; then → IfThenElse_92 ; else → 81 |
conforme |
265 ` |
GetFirstPersonSM` | self ← 261 [0] (` |
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 |
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 ( |
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_512lit265(PlayerCharacter.FirstPersonSM) etPO_2(GetSocketLocationsur264, self ←261). Ce sont les lectures que la voie C1 d'ApplyRoomCamerafait 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é :PlayerCharacternul 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
FirstPersonSMsur le milieu des yeux ;else(vue ailleurs) →RestoreC1inchangé ; 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 Packageavant. - Après l'appel 12 : l. 2273,
LogBlueprint: Compiling Blueprint '/Game/BPs/Room.Room'. Puis 0 ligneerrorouwarning(insensible à la casse) de la l. 2271 à la fin (l. 2308), sauvegarde et validation comprises. hyper_blueprint_debug_inspectn'a pas été appelé : il est absent du serveur (repli prévu :warnings_as_errorset le journal).- Sauvegarde, l. 2278 :
Saving Package: /Game/BPs/Room. PuisMoving '…/Saved/Room2E880115405C4A4C093C3A9251FC3A32.tmp' to '…/Content/BPs/Room.uasset'etAssetCheck: /Game/BPs/Room Validation de la ressource. Le journal n'a pas d'autre ligneSaving 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 sousCAM-B2kmn(Room et PC). Le dossierD:\Game\LifePlay_Backup_5.5\CAM-B2kn'existe pas (ls -d …/CAM-B2k*ne rend queCAM-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é) :
.\Tools\Snapshot.ps1 -Lot CAM-B2kmn-retour -Path Content\BPs\Room.uasset;.\Tools\Restore.ps1 -Lot CAM-B2kmn -Only Content\BPs\Room.uasset -WhatIf;.\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_nodesn'a pas été appelé (aucun nœud supprimé dans cette fiche). CallFunction_439(source de la vue pourPO_0etPO_8) etCustomEvent_45(événementUpdateRoomCamselonCAM-B2i-IMPL.md§ 1.4) n'ont pas été relus ici.is_dirtyn'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, appelSceneComponent::K2_SetWorldLocation(), bSweep et bTeleportfalse; 83.then→_512.execute; sorties de265.FirstPersonSM(430, 431, 433, 446,_512) et dePO_2(446,_512).
- 1 nœud nouveau :
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,
LogStatssansAccessed Nonenouveau surRoom/UpdateRoomCam(cas limitePlayerCharacternul, § 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
Mvient 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 2241Call 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_iddeSceneComponent::K2_SetWorldLocation:Transformation|SetWorldLocation(filtreSetWorldLocationaveccontext_pinssur une sortie de composant : 2 résultats,…AndRotationet celui-ci) ; il se crée enK2Node_CallFunction_<n>avec bSweep et bTeleportfalsepar défaut ;create_nodepeut réutiliser un numéro libre inférieur aux nœuds existants (_512alors que_516et_518existent) : 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.