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

17 KiB
Raw Blame History

Fiche CAM-B2e — Niveau N3 — Modèle prévu opus | utilisé claude-opus-5-5 (Opus 5.5) — Agent lp-mcp-bp — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot

CAM-B2e-IMPL : boîte de pièce sur les faces intérieures des murs (2026-10-13)

Consignes : CAM-B2e-FICHE.md (règle, nœuds existants, écritures 1 à 8) ; rubriques communes de CAM-B2b-FICHES.md (l. 23-63). UE-GO de Big Boss pour le passage Room B2d + B2e (2026-10-13, cité par l'orchestrateur). Éditeur headless PID 22060, port 8000, connexion unreal-mcp partagée (MCPA-T1) ; Room chargé, B2d en mémoire (non touché). Un seul call_tool par message. 60 appels MCP : 21 create_node, 2 get_node_infos, 29 connect_pins, 4 set_pin_value, 1 compile_blueprint, 1 save_assets, 2 ObjectTools.get_properties (dont 1 en erreur de schéma). Aucun break_pins (§ 2 E1), delete_node, write_graph_dsl ni ProgrammaticToolset. Aucune écriture par HyperAIStudio.

1. Fichiers modifiés

  • Content/BPs/Room.uasset : enregistré (save_assets {asset_paths:["/Game/BPs/Room"]} → true), B2d et B2e ensemble. MD5 avant e0517c63… (= instantané), après ca2a9a0baaca4130fd5c318797f008ae (§ 3).
  • Graphe /Game/BPs/Room.Room:EventGraph, nouveaux nœuds en x 38000-39150, y 1200-2000 (sous ComputeRoomBox).

1.1 Nœuds créés (préfixe refPath : /Game/BPs/Room.Room:EventGraph.)

Chaîne Rôle refPath (suffixe) type_id relu Position
Wall1 (−X) getter Wall1 K2Node_VariableGet_297 |GetWall1 (créé par Variables|Pardéfaut|ObtenirWall1) 38000, 1200
GetComponentBounds(Wall1) K2Node_CallFunction_525 Collision|GetComponentBounds 38300, 1200
O + E K2Node_PromotableOperator_37 Math|Vecteur|vector+vector 38650, 1200
+ (30,30,0) K2Node_PromotableOperator_38 Math|Vecteur|vector+vector 38900, 1200
BreakVector → X K2Node_CallFunction_530 Math|Vecteur|BreakVector 39150, 1200
Wall2 (+X) GetComponentBounds(283) K2Node_CallFunction_526 Collision|GetComponentBounds 38300, 1400
O − E K2Node_PromotableOperator_39 Math|Vecteur|vector-vector 38650, 1400
− (30,30,0) K2Node_PromotableOperator_40 Math|Vecteur|vector-vector 38900, 1400
BreakVector → X K2Node_CallFunction_531 Math|Vecteur|BreakVector 39150, 1400
Wall3 (−Y) getter Wall3 K2Node_VariableGet_298 |GetWall3 (créé par Variables|Pardéfaut|ObtenirWall3) 38000, 1600
GetComponentBounds(Wall3) K2Node_CallFunction_527 Collision|GetComponentBounds 38300, 1600
O + E K2Node_PromotableOperator_41 Math|Vecteur|vector+vector 38650, 1600
+ (30,30,0) K2Node_PromotableOperator_42 Math|Vecteur|vector+vector 38900, 1600
BreakVector → Y K2Node_CallFunction_532 Math|Vecteur|BreakVector 39150, 1600
Wall4 (+Y) GetComponentBounds(284) K2Node_CallFunction_528 Collision|GetComponentBounds 38300, 1800
O − E K2Node_PromotableOperator_43 Math|Vecteur|vector-vector 38650, 1800
− (30,30,0) K2Node_PromotableOperator_44 Math|Vecteur|vector-vector 38900, 1800
BreakVector → Y K2Node_CallFunction_533 Math|Vecteur|BreakVector 39150, 1800
WallT GetComponentBounds(285) K2Node_CallFunction_529 Collision|GetComponentBounds 38300, 2000
O − E (face inférieure) K2Node_PromotableOperator_45 Math|Vecteur|vector-vector 38650, 2000
BreakVector → Z K2Node_CallFunction_534 Math|Vecteur|BreakVector 39150, 2000

Broches relues avant câblage (get_node_infos groupé, 7 créés + 492, 493, PO_15, 283, 284, 285) : GetComponentBounds : Component in 0 (Scene Component Référence d'objet), Origin out 0 (Vector), BoxExtent out 1 (Vector), SphereRadius out 2 (Float (simple précision), non relié) ; getters out 0 (Static Mesh Component Référence d'objet) ; opérateurs A 0, B 1, sortie 0 (génériques à la création, typés Vector à la première liaison) ; BreakVector InVec 0, X 0 / Y 1 / Z 2. État relu avant écriture : 492.X ← 484.0, 492.Y ← 484.1, 492.Z ← PO_14 ; 493.X ← 485.0, 493.Y ← 485.1, 493.Z ← 491 ; PO_15.A ← 488.2, PO_15.B = 25.0 ; 283 → 476, 284 → 477, 285 → 487 (conforme aux rapports F1, F2 et à la fiche).

1.2 Liens faits (connect_pins, 29, tous {"returnValue":null})

# Sortie (nœud.broche index) Entrée (nœud.broche index) Fiche
L1 VariableGet_297.0 CallFunction_525.Component 0 1
L2 CallFunction_525.Origin 0 PromotableOperator_37.A 0 1
L3 CallFunction_525.BoxExtent 1 PromotableOperator_37.B 1 1
L4 PromotableOperator_37.0 PromotableOperator_38.A 0 1
L5 PromotableOperator_38.0 CallFunction_530.InVec 0 1
L6 CallFunction_530.X 0 CallFunction_492.X 0 (remplace 484.X) 1
L7 VariableGet_283.0 CallFunction_526.Component 0 2
L8 CallFunction_526.Origin 0 PromotableOperator_39.A 0 2
L9 CallFunction_526.BoxExtent 1 PromotableOperator_39.B 1 2
L10 PromotableOperator_39.0 PromotableOperator_40.A 0 2
L11 PromotableOperator_40.0 CallFunction_531.InVec 0 2
L12 CallFunction_531.X 0 CallFunction_493.X 0 (remplace 485.X) 2
L13 VariableGet_298.0 CallFunction_527.Component 0 3
L14 CallFunction_527.Origin 0 PromotableOperator_41.A 0 3
L15 CallFunction_527.BoxExtent 1 PromotableOperator_41.B 1 3
L16 PromotableOperator_41.0 PromotableOperator_42.A 0 3
L17 PromotableOperator_42.0 CallFunction_532.InVec 0 3
L18 CallFunction_532.Y 1 CallFunction_492.Y 1 (remplace 484.Y) 3
L19 VariableGet_284.0 CallFunction_528.Component 0 4
L20 CallFunction_528.Origin 0 PromotableOperator_43.A 0 4
L21 CallFunction_528.BoxExtent 1 PromotableOperator_43.B 1 4
L22 PromotableOperator_43.0 PromotableOperator_44.A 0 4
L23 PromotableOperator_44.0 CallFunction_533.InVec 0 4
L24 CallFunction_533.Y 1 CallFunction_493.Y 1 (remplace 485.Y) 4
L25 VariableGet_285.0 CallFunction_529.Component 0 5
L26 CallFunction_529.Origin 0 PromotableOperator_45.A 0 5
L27 CallFunction_529.BoxExtent 1 PromotableOperator_45.B 1 5
L28 PromotableOperator_45.0 CallFunction_534.InVec 0 5
L29 CallFunction_534.Z 2 PromotableOperator_15.A 0 (remplace 488.Z) 5

Valeurs (set_pin_value, toutes {"returnValue":null}, relues "value":"30,30,0") : B 1 de PromotableOperator_38, _40, _42 et _44 = 30,30,0. PromotableOperator_15.B reste 25.0 (relu).

1.3 Liens coupés

Les 5 liens remplacés, coupés par connect_pins sur une entrée déjà reliée (§ 2 E1) : 484.X 0 → 492.X 0 ; 484.Y 1 → 492.Y 1 ; 485.X 0 → 493.X 0 ; 485.Y 1 → 493.Y 1 ; 488.Z 2 → PO_15.A 0. Aucun autre lien touché.

1.4 Relecture (get_node_infos groupé final, 24 nœuds : 21 créés + 492, 493, PO_15)

Les 29 liens apparaissent des deux côtés. Entrées cibles, un seul lien chacune : 492.X ← 530.X ; 492.Y ← 532.Y ; 492.Z ← PO_14 (inchangé) ; 493.X ← 531.X ; 493.Y ← 533.Y ; 493.Z ← 491 (inchangé) ; PO_15.A ← 534.Z, B = 25.0, sortie → 491.B 1 (inchangée). Sorties de 492 → VariableSet_64.1 et de 493 → VariableSet_65.1 inchangées. Les huit opérateurs sont typés (vector+vector 37, 38, 41, 42 ; vector-vector 39, 40, 43, 44, 45), A et B en Vector. Aucune divergence avec la fiche.

Chaîne obtenue (ComputeRoomBox) :

  • C2BoxMin := (W1.O.X + W1.E.X + 30, W3.O.Y + W3.E.Y + 30, sol.Z + 50) ;
  • C2BoxMax := (W2.O.X − W2.E.X − 30, W4.O.Y − W4.E.Y − 30, SelectFloat(1000000, WallT.O.Z − WallT.E.Z − 25, Ext)). Les anciens nœuds de calcul (PO_9 à PO_13, 476 à 485, 487, 488) restent en place, sans consommateur en aval de 484, 485 et 488 (fiche, point 6) ; purs, ils ne sont plus évalués.

1.5 Compilation et enregistrement

  • compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true} → {"returnValue":null}, aucune exception (B2d + B2e en mémoire). hyper_blueprint_debug_inspect non appelé (absent du serveur le 2026-10-10, mémoire unreal-mcp-reconnect, non revérifié) ; journal de l'éditeur non lu (chemin -abslog non fourni).
  • AssetTools.save_assets {asset_paths:["/Game/BPs/Room"]} → {"returnValue":true}, Room seul.

1.6 Lecture de la collision (point 7, lecture seule, arrêtée à Wall1 faute de tours)

ObjectTools.get_properties {instance:{refPath:"/Game/BPs/Room.Room_C:Wall1_GEN_VARIABLE"}, properties:["BodyInstance"]} (gabarit du composant de Wall1 dans la classe générée), extrait tel quel :

"objectType":"ECC_WorldDynamic","collisionEnabled":"QueryAndPhysics", ... "collisionProfileName":"Custom",
"collisionResponses":{"responseArray":[]}, ... "bSimulatePhysics":false

Le premier appel (object, property_names) a échoué sur le schéma ; il a rendu le schéma exact (instance, properties). Wall2, Wall3, Wall4 et WallT : non lus (budget atteint). Lecture (estimé, non vérifié) : profil Custom avec responseArray vide, donc aucune réponse surchargée. Le canal Camera garderait la réponse par défaut du conteneur, ECR_Block sauf réglage contraire dans DefaultEngine.ini. Ce point est à confirmer : il faut lire DefaultEngine.ini (DefaultChannelResponses) et les instances placées. Une instance de niveau ou le C++ (LPOutdoorRoomSubsystem) peuvent changer la collision à l'exécution.

2. Écarts à la SPEC

  • E1 (procédure, même résultat) : la fiche prescrit break_pins avant de relier 492.X (point 1) et PO_15.A (point 5), et par extension 493.X, 492.Y et 493.Y. Les 5 coupures sont faites par connect_pins lui-même. Preuve par les sources du moteur installé : connect_pins appelle out.try_create_connection(inp) (D:\Game\Launcher\Engine\UE_5.8\Engine\Plugins\Experimental\Toolsets\EditorToolset\Content\Python\editor_toolset\toolsets\blueprint.py:1067). Cet appel aboutit à UEdGraphSchema_K2::TryCreateConnection (…\Engine\Source\Editor\BlueprintEditorLibrary\Private\BlueprintEditorLibrary\BlueprintGraphPin.cpp:92-102). Pour une entrée de donnée déjà reliée, le schéma répond CONNECT_RESPONSE_BREAK_OTHERS_* (…\Engine\Source\Editor\BlueprintGraph\Private\EdGraphSchema_K2.cpp:2086-2088) : l'ancien lien est coupé, puis le nouveau est fait. Le § 1.4 vérifie le résultat : chaque entrée n'a qu'un lien, le nouveau. Motif : le budget. Les 5 break_pins auraient porté l'enregistrement au-delà des 65 tours (même motif que B2d E2).
  • E2 (ordre) : la lecture des nœuds existants est faite après la création des 21 nœuds et avant tout câblage, en un seul appel groupé avec les nœuds créés, comme en B2d (§ 1.2 de CAM-B2d-IMPL.md). Créer des nœuds non reliés ne touche aucun nœud existant.
  • Garde Accessed None : aucune IsValid ajoutée (ni la SPEC ni la fiche n'en demandent). Lectures nouvelles : Wall1 (297) et Wall3 (298) dans ComputeRoomBox. Wall1 a un gabarit de composant dans la classe générée (Room_C:Wall1_GEN_VARIABLE, lu au § 1.6). C'est un composant de la construction, « vide » n'y est pas un état normal (estimé). Wall3 est supposé du même type, sans lecture. Wall2, Wall4 et WallT étaient déjà lus (476, 477, 487).
  • Comportement : changement voulu (faces intérieures au lieu des centres des murs). ZMin, le choix extérieur (491) et les affectations (64, 65) sont inchangés (relus).
  • Aucun nœud de B2d touché (513-524, PO28, PO30, 96, 97, CE48) : aucun appel ne les vise.

3. Instantané

Fait par l'orchestrateur (non refait, consigne) : D:\Game\LifePlay_Backup_5.5\CAM-B2d\. Relevé avant écriture :

date -Iseconds; md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"; grep -i "Room.uasset" "/d/Game/LifePlay_Backup_5.5/CAM-B2d/manifest.csv"; git -C "/d/Game/LifePlay-master 5.8" rev-parse --short HEAD
2026-10-13T17:24:45+02:00
e0517c63541f249bd9dbda5c39815ba5 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset
"Content\BPs\Room.uasset","True","6318319","E0517C63541F249BD9DBDA5C39815BA5","2026-10-13T17:11:26"
0745917

Relevé après save_assets :

date -Iseconds; md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"; ls -l "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"; git -C "/d/Game/LifePlay-master 5.8" status --short -- Content Source Config
2026-10-13T17:29:45+02:00
ca2a9a0baaca4130fd5c318797f008ae */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset
-rw-r--r-- 1 <compte> 197609 6378087 Oct 13 17:29 /d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset
 M Content/BPs/Person.uasset
 M Content/BPs/Room.uasset
 M Source/LifePlay/LPDebugSubsystem.cpp
 M Source/LifePlay/LPDebugSubsystem.h
 M Source/LifePlay/LPOutdoorRoomSubsystem.cpp
 M Source/LifePlay/LPOutdoorRoomSubsystem.h
?? Source/LifePlay/LPCameraModeSubsystem.cpp
?? Source/LifePlay/LPCameraModeSubsystem.h

Le MD5 diffère de E0517C63 (attendu). Le git status correspond à l'état annoncé par l'orchestrateur : Person, LPDebugSubsystem., LPOutdoorRoomSubsystem. et LPCameraModeSubsystem.* viennent d'autres fiches et ne sont pas touchés ici. Retour arrière, proposé et jamais lancé : Tools\Restore.ps1 -Lot CAM-B2d -Only Content\BPs\Room.uasset, éditeur fermé, sur décision de l'orchestrateur. Il ramène Room à E0517C63, l'état B2b, et perd B2d et B2e.

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

  • Point 7 : collision de Wall2, Wall3, Wall4 et WallT non lue (budget). Réponse effective au canal Camera non établie (§ 1.6).
  • Anciens nœuds (point 6) laissés en place, conformément à la fiche (nettoyage plus tard).
  • hyper_blueprint_debug_inspect, journal de l'éditeur : non consultés (§ 1.5).
  • Valeurs de C2BoxMin / C2BoxMax à l'exécution : non mesurées (pas de PIE ni de build) ; preuve en jeu (build empaqueté + LogStats) hors rôle. Éditeur laissé ouvert (fermeture : orchestrateur, puis BUILD-FIN).

5. Points à confirmer en VAL

  1. V5 (fiche) par dump après fermeture de l'éditeur : GetComponentBounds ≥ 5 dans ComputeRoomBox (525 à 529) ; 492.X ← 530.X, 492.Y ← 532.Y, 493.X ← 531.X, 493.Y ← 533.Y ; PO_15.A ← 534.Z (O − E de WallT) ; valeurs 30,30,0 sérialisées sur PO_38, _40, _42, _44.
  2. Orientation (estimé, risque) : la règle suppose des pièces sans rotation, Wall1 en −X du monde et Wall2 en +X. Une Room tournée de 180° en lacet donne MinX > MaxX : la boîte est croisée. Une Room tournée de 90° fait que X et Y ne correspondent plus aux murs. L'ancienne formule (Abs, F1) supportait 180°. Il faut vérifier que les pièces placées ou générées ont toutes un lacet de 0.
  3. Bornes croisées : la garde Vector_ComponentMax de F1 (483) n'est plus sur le chemin. Une pièce de moins de 60 unités utiles entre les faces (ou WallT − 25 < sol + 50) donne Min > Max dans VectorBoundedToBox. Ce comportement n'est pas vérifié.
  4. Extérieur : les murs sont écrasés en Z (échelle 0,01) mais gardent leur emprise XY. WallT est toujours évalué (pur) même quand SelectFloat choisit 1000000 : aucun Accessed None attendu, à vérifier par LogStats.
  5. Lectures nouvelles Wall1 (297), Wall3 (298) : à vérifier par LogStats (aucun Accessed None sur ComputeRoomBox).
  6. Collision : réponse au canal Camera de Wall1 à Wall4 et WallT (gabarits et instances), et DefaultEngine.ini (§ 1.6). Wall1 : Custom, responseArray vide.
  7. Essai de la fiche : dos au mur des 4 côtés, dans un coin, en hauteur, et dans une pièce redimensionnée. Aucune vue de l'extérieur ne doit apparaître.
  8. Compilation stricte jugée sur l'absence d'exception seulement : à recontrôler par CompileAllBlueprints, éditeur fermé (V6).

6. Fichiers à commiter

  • A Docs/Migration/etat/CAM/CAM-B2e-IMPL.md (dépôt du jeu, branche ue5.8).
  • M Content/BPs/Room.uasset (dépôt du jeu, branche ue5.8) : B2d et B2e enregistrés ensemble, MD5 ca2a9a0b…. Commit après VAL et essai, sur ticket de l'orchestrateur.

Tours : 65 / 65 (63 de travail ; le livrable et le compte rendu sont dans la marge)

Constats

  • À verser : lp-mcp § 3. connect_pins passe par UEdGraphSchema_K2::TryCreateConnection (blueprint.py:1067, BlueprintGraphPin.cpp:92-102). Sur une entrée de donnée déjà reliée, il remplace l'ancien lien (EdGraphSchema_K2.cpp:2086-2088) : aucun break_pins préalable n'est nécessaire, à relire ensuite. break_pins vérifie le lien puis appelle break_single_pin_link (blueprint.py:1074-1087).
  • À verser : lp-mcp § 3. Lecture d'un composant de Blueprint : ObjectTools.get_properties {instance:{refPath:"/Game/BPs/X.X_C:<Composant>_GEN_VARIABLE"}, properties:[…]}. Code des outils Epic : D:\Game\Launcher\Engine\UE_5.8\Engine\Plugins\Experimental\Toolsets\EditorToolset\Content\Python\editor_toolset\toolsets\.
  • À verser : lp-mcp § 3. Collision|GetComponentBounds : Component in 0 ; Origin out 0, BoxExtent out 1, SphereRadius out 2 (nœud pur). Variables|Pardéfaut|ObtenirWall1 / ObtenirWall3 acceptés tels quels.
  • Ordre efficace (60 appels pour 21 nœuds et 29 liens) : toutes les créations, puis une lecture groupée (créés + existants), puis le câblage chaîne par chaîne, set_pin_value juste après le typage de l'opérateur, puis une relecture finale groupée.