LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2f-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

16 KiB

Fiche CAM-B2f (+ amendement B2f-a) — Niveau N3 — Modèle prévu non précisé (CAM-TACHES.md:29, fiche § 2) | utilisé claude-opus-5-5 — Agent lp-mcp-bp — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot

CAM-B2f-IMPL : Room, sonde C2 de Camera à Visibility par MCP (2026-10-13)

Résultat : réussi après l'amendement B2f-a. Premier passage : arrêt à l'étape 6, car save_assets n'avait rien écrit (Constats C1 à C5). Reprise B2f-a (fiche § 5) : on a créé puis supprimé un nœud Branche isolé pour marquer Room comme modifié. Ensuite is_dirty = vrai, relecture conforme, compilation stricte sans exception, et Room enregistré seul. MD5 de Room CA2A9A0B… → F2B082D2… ; GI et Person sont inchangés (section B2f-a).

1. Fichiers modifiés

  • Content/BPs/Room.uasset : graphe EventGraph, nœuds K2Node_CallFunction_459, _499 et _505. Broche TraceChannel (entrée, index 4) passée de TraceTypeQuery2 à TraceTypeQuery1. Aucun autre changement voulu : le nœud temporaire K2Node_IfThenElse_101 a été créé puis supprimé avant l'enregistrement. MD5 avant CA2A9A0BAACA4130FD5C318797F008AE (6 378 087 octets), après F2B082D2911D9F7C7BE60C2CF30EE6D5 (6 378 021 octets), enregistré le 2026-10-13 à 19:50:29 (heure locale).
  • Docs/Migration/etat/CAM/CAM-B2f-IMPL.md : ce livrable (nouveau).
  • Effet de bord, hors dépôt : la sauvegarde automatique de l'éditeur a écrit Saved/Autosaves/Game/BPs/Room_Auto1.uasset et Saved/Autosaves/PackageRestoreData.json à 19:47:39 (heure locale), entre create_node et delete_node (section B2f-a, A3).

2. Écarts à la SPEC

  • E1 (premier passage, résolu par B2f-a) : save_assets → true sans rien écrire (Tous les fichiers sont déjà enregistrés.), parce que set_pin_value ne marque pas Room comme modifié (Constats C3).
  • E2 (non bloquant) : le type_id des nœuds est Collision|SphereTraceByChannel, le nom d'affichage de UKismetSystemLibrary::SphereTraceSingle (KismetSystemLibrary.h:1299-1300 du moteur 5.8 installé).
  • E3 (B2f-a, prescrit par l'amendement) : un nœud a été créé puis supprimé, alors que la fiche § 2 disait « aucun nœud créé ni supprimé ». Le graphe final n'a pas ce nœud : find_nodes ne le liste plus (section B2f-a, A2).
  • E4 (B2f-a, lectures en plus des étapes) : get_node_infos du nœud créé, avant et après delete_node, et find_nodes pour vérifier sa disparition. Le premier find_nodes a été refusé par le schéma (title obligatoire, erreur de paramètre de ma part) et refait une fois avec title: "", comme le prévoit lp-mcp § 3.
  • E5 (B2f-a, effet de bord) : la sauvegarde automatique de l'éditeur dans Saved/Autosaves (A3). Aucun fichier de Content n'a été écrit par elle (mesuré).
  • hyper_blueprint_debug_inspect est absent du serveur. Repli appliqué : compile_blueprint {warnings_as_errors:true}
    • journal de l'éditeur.

3. Instantané

  • Pris par l'orchestrateur avant tout appel : .\Tools\Snapshot.ps1 -Lot CAM-B2f. Manifeste D:\Game\LifePlay_Backup_5.5\CAM-B2f\manifest.csv, lu le 2026-10-13 à 19:38 (heure locale) :
"Rel","Existed","Size","MD5","Date"
"Content\BPs\Room.uasset","True","6378087","CA2A9A0BAACA4130FD5C318797F008AE","2026-10-13T19:36:19"
  • Contrôle C9a avant écriture : md5sum Content/BPs/Room.uasset → ca2a9a0baaca4130fd5c318797f008ae (= attendu).
  • Retour arrière (proposé, non lancé) : .\Tools\Restore.ps1 -Lot CAM-B2f -WhatIf, puis .\Tools\Restore.ps1 -Lot CAM-B2f -Only Content\BPs\Room.uasset, éditeur fermé, sur accord.

4. Ce qui n'a pas été fait

  • Pas de comptage des 1260 nœuds de Room : il revient à la VAL (V5, dump).
  • Pas de CompileAllBlueprints, pas de build, pas de commandlet, pas de jeu (hors fiche).
  • L'éditeur n'a pas été fermé (pid 28928, toujours ouvert) : c'est à l'orchestrateur, puis BUILD-FIN.
  • Je n'ai pas nettoyé Saved/Autosaves (A3) : c'est signalé ici, pas supprimé.

5. Points à confirmer en VAL

  • V5 dump Room (-BP=Room -Fn=* -Pins -Exec) : TraceTypeQuery1 sur 459, 499 et 505, et 1260 nœuds. Aucun K2Node_IfThenElse_101 dans le dump.
  • Diff du dump avec celui de l'instantané (CA2A9A0B) : seules les 3 valeurs TraceChannel changent. La taille du fichier baisse de 66 octets (6 378 087 → 6 378 021). Cause non vérifiée : vignette régénérée à l'enregistrement, sérialisation ou autre.
  • MD5 de Room = F2B082D2911D9F7C7BE60C2CF30EE6D5 à l'ouverture de la VAL (sinon, quelqu'un a réécrit Room).
  • V6 CompileAllBlueprints = référence ; V7 dans le build COMMUN-3.
  • Au prochain lancement de l'éditeur, ne pas accepter la restauration de Room_Auto1 si elle est proposée : c'est un état intermédiaire, qui contient le nœud temporaire (A3).

6. Fichiers à commiter

Dépôt du jeu, D:\Game\LifePlay-master 5.8, branche ue5.8 :

  • A Docs/Migration/etat/CAM/CAM-B2f-IMPL.md
  • M Content/BPs/Room.uasset (MD5 F2B082D2911D9F7C7BE60C2CF30EE6D5). À confirmer par l'orchestrateur : Room était déjà M avant cette fiche (état git du début de session ; l'instantané CA2A9A0B n'est pas la version de HEAD). Le commit de Room portera donc aussi les changements non commités d'avant B2f.
  • Saved/Autosaves/… : rien à commiter (dossier ignoré).

Tours : 51 / 60

Constats

C1. Premier passage : appels MCP dans l'ordre (un par message, journal D:\Game\LifePlay_Backup_5.5\CAM-B2f\editeur\editeur-B2f.log, heures UTC)

# Appel Retour Journal
1 AssetTools.load_asset {asset_path:"/Game/BPs/Room"} {"refPath":"/Game/BPs/Room.Room"} l. 2243-2244, 17:38:43
2 BlueprintTools.get_node_infos (459, 499, 505 groupés) 3 nœuds, lus en C2 l. 2251-2252
3 set_pin_value {pin:{EGPD_Input, 4, …CallFunction_459}, value:"TraceTypeQuery1"} null l. 2253-2254
4 set_pin_value idem sur …CallFunction_499 null l. 2255-2256
5 set_pin_value idem sur …CallFunction_505 null l. 2257-2258
6 get_node_infos (459, 499, 505 groupés), relecture 3 nœuds, lus en C2 l. 2259-2260
7 compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true} null (pas d'exception) l. 2261-2264
8 AssetTools.save_assets {asset_paths:["/Game/BPs/Room"]} true, mais Tous les fichiers sont déjà enregistrés. l. 2265-2267

Aux lignes 2234-2245 (17:38:43-44), le client se reconnecte au moment du premier appel : Unknown session id … client should reinitialize, puis Call to unknown method "server/discover". L'appel 1 est passé ensuite sans erreur.

C2. Nœuds touchés : avant et après (refPath /Game/BPs/Room.Room:EventGraph.K2Node_CallFunction_<n>)

Nœud Position TraceChannel (index 4) avant → après Radius bIgnoreSelf ActorsToIgnore ← execute ← then → Start ← End ← OutHit → ReturnValue →
459 35750, 1500 TraceTypeQuery2 → TraceTypeQuery1 20.0 true MakeArray_5 [0] CallFunction_494 [0] IfThenElse_90 [0] CallFunction_455 [0] CallFunction_495 [0] CallFunction_460 [0] IfThenElse_90 [1]
499 31450, 4500 TraceTypeQuery2 → TraceTypeQuery1 20.0 true MakeArray_5 [0] CallFunction_467 [0] CallFunction_474 [0] CallFunction_455 [0] CallFunction_468 [0] CallFunction_500 [0] CallFunction_501 [2]
505 38450, 1500 TraceTypeQuery2 → TraceTypeQuery1 20.0 true MakeArray_5 [0] IfThenElse_95 [0] VariableSet_66 [0] CallFunction_455 [0] CallFunction_504 [0] CallFunction_506 [0] CallFunction_507 [2]

Sur les 3 nœuds, lors des trois lectures (appels 2, 6 et B2f-a n° 16) : bTraceComplex false, DrawDebugType None, TraceColor (1,0,0,1), TraceHitColor (0,1,0,1), DrawTime 5.0. Les relectures ne diffèrent de la première lecture que par TraceChannel.

C3. Cause de E1 (établie dans les sources du moteur 5.8 installé, D:\Game\Launcher\Engine\UE_5.8)

  • set_pin_value → UBlueprintGraphPinLibrary::SetPinValue (Engine/Source/Editor/BlueprintEditorLibrary/Private/BlueprintEditorLibrary/BlueprintGraphPin.cpp:79) appelle Schema->TrySetDefaultValue(*NativePin, Value, false). Le 3e paramètre est bMarkAsModified, true par défaut (Engine/Source/Editor/BlueprintGraph/Classes/EdGraphSchema_K2.h:576).
  • save_assets (Engine/Plugins/Experimental/Toolsets/EditorToolset/Content/Python/editor_toolset/toolsets/asset.py:343-349) appelle eas.save_asset(path), donc avec bOnlyIfIsDirty = true (Engine/Source/Editor/UnrealEd/Public/Subsystems/EditorAssetSubsystem.h:296). Un paquet non marqué n'est pas écrit, et l'appel rend true.
  • Dans asset.py et blueprint.py, aucun outil ne marque un paquet comme modifié. Seul l'outil de lecture AssetTools.is_dirty existe (asset.py:353).

C4. Mesuré à la fin du premier passage

$ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset
ca2a9a0baaca4130fd5c318797f008ae *Content/BPs/Room.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset

Fin du journal : [2026.10.13-17.39.53:161][942]LogFileHelpers: Tous les fichiers sont déjà enregistrés.

C5. Options proposées après le premier passage

On a retenu l'option 1 : marquer Room comme modifié dans la même session, avec les outils de la fiche. L'orchestrateur l'a prescrite dans l'amendement B2f-a (fiche § 5).

B2f-a : reprise (amendement, fiche § 5)

A1. Appels MCP dans l'ordre (un par message, même journal, heures UTC)

# Appel Retour Journal
9 create_node {graph:{refPath:"/Game/BPs/Room.Room:EventGraph"}, type_id:"Utilitaires|ContrôleDeFlux|Branche", pos:{x:-20000, y:-20000}} {"refPath":"/Game/BPs/Room.Room:EventGraph.K2Node_IfThenElse_101"} l. 2272-2273, 17:47:29
10 get_node_infos K2Node_IfThenElse_101 Branche, position (-20000, -20000), 4 broches (execute, Condition = true, then, else), 0 lien l. 2274-2275
11 delete_node {node:{refPath:"…K2Node_IfThenElse_101"}} null l. 2286-2287, 17:47:41
12 AssetTools.is_dirty {asset_path:"/Game/BPs/Room"} true l. 2288-2289
13 get_node_infos K2Node_IfThenElse_101 se résout encore (même contenu) : objet en attente du ramasse-miettes, voir A2 l. 2290-2291
14 find_nodes {graph, node_class:K2Node_IfThenElse} refusé : input param "title" is required l. 2292-2293
15 find_nodes {graph, title:"", node_class:{refPath:"/Script/BlueprintGraph.K2Node_IfThenElse"}} liste des Branche du graphe : K2Node_IfThenElse_101 absent, plus grand numéro listé _100 l. 2294-2295
16 get_node_infos (459, 499, 505 groupés) TraceTypeQuery1 sur les 3, reste identique à C2 l. 2296-2297
17 compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true} null (pas d'exception) l. 2298-2301
18 AssetTools.save_assets {asset_paths:["/Game/BPs/Room"]} true, Room écrit l. 2305-2338, 17:50:28

A2. Nœud temporaire : créé, puis retiré du graphe

  • Avant suppression (appel 10), le nœud était bien celui que j'avais créé : type_id Branche, position (-20000, -20000), aucun lien.
  • Après delete_node, il se résout encore par son refPath (appel 13). C'est normal : UEdGraphNode::DestroyNode appelle ParentGraph->RemoveNode(this) avec le commentaire « Will be GC'd after this » (Engine/Source/Runtime/Engine/Private/EdGraph/EdGraphNode.cpp:554-560), et UEdGraph::RemoveNode le retire de Nodes (EdGraph.cpp:266). L'objet reste en mémoire jusqu'au ramasse-miettes.
  • find_nodes parcourt bp_editor.list_all_nodes() (blueprint.py:706-709) et ne le liste plus (appel 15).
  • delete_node → UBlueprintGraphEditor::RemoveNodes → FBlueprintEditorUtils::RemoveNode(Blueprint, Node, true) (Engine/Source/Editor/BlueprintEditorLibrary/Private/BlueprintEditorLibrary/BlueprintGraphEditor.cpp:1576-1598).

A3. Sauvegarde automatique de l'éditeur (effet de bord)

À 17:47:39 UTC, entre les appels 10 et 11, l'éditeur a fait sa sauvegarde automatique (l. 2276-2285) :

[2026.10.13-17.47.39:691][ 90]LogFileHelpers: Editor autosave (incl. external actors) for '/Game/Scenes/CentralLondon' took 0.099
[2026.10.13-17.47.39:871][ 90]Cmd: OBJ SAVEPACKAGE PACKAGE="/Game/BPs/Room" FILE="../../../../../../LifePlay-master 5.8/Saved/Autosaves/Game/BPs/Room_Auto1.uasset" SILENT=false AUTOSAVING=true
[2026.10.13-17.47.40:602][ 90]LogFileHelpers: Auto-saving content packages took 0.911

Mesuré juste avant l'appel 18 (19:50:22, heure locale) :

$ find Content -newermt "-20 minutes" -type f
(aucune ligne)
$ find Saved/Autosaves -newermt "-20 minutes" -type f
Saved/Autosaves/Game/BPs/Room_Auto1.uasset
Saved/Autosaves/PackageRestoreData.json
$ md5sum Content/BPs/Room.uasset
ca2a9a0baaca4130fd5c318797f008ae *Content/BPs/Room.uasset

Room_Auto1.uasset contient l'état intermédiaire, avec K2Node_IfThenElse_101 (estimé : la sauvegarde a eu lieu avant l'appel 11). Je ne l'ai pas supprimé. Je ne sais pas si PackageRestoreData.json a été remis à jour par l'enregistrement de l'appel 18 : c'est incertain, et la lecture de ce fichier le trancherait.

A4. Enregistrement (appel 18), journal

[2026.10.13-17.50.28:576][ 47]LogFileHelpers: Saving Package: /Game/BPs/Room
[2026.10.13-17.50.28:587][ 47]Cmd: OBJ SAVEPACKAGE PACKAGE="/Game/BPs/Room" FILE="../../../../../../LifePlay-master 5.8/Content/BPs/Room.uasset" SILENT=true
[2026.10.13-17.50.29:171][ 47]LogSavePackage: Moving output files for package: /Game/BPs/Room
[2026.10.13-17.50.29:229][ 48]AssetCheck: /Game/BPs/Room Validation de la ressource

Seul /Game/BPs/Room a été enregistré. Le journal finit à la ligne 2338. On compte 0 ligne Error ou Warning depuis la ligne 2265 (tail -n +2265 <journal> | grep -c -E "Error|Warning" → 0).

A5. Mesuré après l'appel 18 (19:50:36, heure locale)

$ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset
f2b082d2911d9f7c7be60c2cf30ee6d5 *Content/BPs/Room.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
$ stat -c '%y %s %n' Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset
2026-10-13 19:50:29.168177700 +0200 6378021 Content/BPs/Room.uasset
2026-10-13 19:26:08.639049400 +0200 52636801 Content/BPs/GI.uasset
2026-10-13 17:42:36.059256500 +0200 20821244 Content/BPs/Person.uasset
$ find Content -newermt "-25 minutes" -type f
Content/BPs/GI.uasset
Content/BPs/Room.uasset
  • Room : MD5 différent de ca2a9a0b… (attendu), date 19:50:29, soit l'appel 18.
  • GI : e64b5b37… (attendu, inchangé). Il apparaît dans la fenêtre de 25 minutes à cause de sa date, 19:26:08. Elle est antérieure à cette fiche : on la relevait déjà à 19:39, dans C4.
  • Person : 8668a47c… (attendu, inchangé), date 17:42:36.

À verser : lp-mcp § 3 — set_pin_value ne marque pas le Blueprint comme modifié (BlueprintGraphPin.cpp:79, TrySetDefaultValue(…, false)), et save_assets n'enregistre que les paquets marqués (asset.py:348, EditorAssetSubsystem.h:296). Un true accompagné de « Tous les fichiers sont déjà enregistrés » veut dire que rien n'a été écrit. Le moyen qui marche : create_node d'une Branche isolée, puis delete_node, puis is_dirty = vrai avant save_assets, et contrôle du MD5 après. Autres points : un nœud supprimé se résout encore par refPath jusqu'au ramasse-miettes, c'est find_nodes qui fait foi ; find_nodes exige title ("" pour tous) ; un paquet marqué déclenche la sauvegarde automatique de l'éditeur dans Saved/Autosaves.

Suite : l'orchestrateur doit fermer l'éditeur (pid 28928), faire BUILD-FIN, puis lancer la VAL (V5 dump Room, V6) et le ticket au gardien. État : Room enregistré (F2B082D2…), GI et Person inchangés, éditeur encore ouvert.