Fiche CAM-B2b-F1 — 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-B2b-F1-IMPL : variables et `ComputeRoomBox`, partie XY (2026-10-13) Consignes : `CAM-B2b-FICHES.md` § « Rubriques communes » et § « F1 » ; SPEC `CAM-SPEC.md` § « CAM-B2b », lignes B2b-0 (l. 374) et B2b-1 (l. 375). BUILD-GO / UE-GO de Big Boss du 2026-10-13 (cité par l'orchestrateur). Éditeur headless PID 10708, port 8000, connexion `unreal-mcp` partagée avec la session qui lance (MCPA-T1). Room chargé par l'orchestrateur (`load_asset /Game/BPs/Room`). Un seul appel `call_tool` par message, 51 appels MCP au total. ## 1. Fichiers modifiés - `Content/BPs/Room.uasset` : modifié **en mémoire de l'éditeur seulement**, non enregistré (pas de `save_assets` avant F7). Preuve : MD5 disque après F1 = MD5 de l'instantané (§ 3). - Graphe `/Game/BPs/Room.Room:EventGraph`, positions x 38000-40000, y 0-600. ### 1.1 Variables (B2b-0) : `add_variable` ×5 sur `{"refPath":"/Game/BPs/Room.Room"}` | Nom | `type_name` passé | Retour | |---|---|---| | `C2BoxMin` | `Vector` | `{"returnValue":null}` | | `C2BoxMax` | `Vector` | `{"returnValue":null}` | | `C2Yaw` | `float` | `{"returnValue":null}` | | `C2Height` | `float` | `{"returnValue":null}` | | `C2Dist` | `float` | `{"returnValue":null}` | Défauts non réglés (0), conformément à la fiche (le 175 de `C2Dist` est porté en F3 par les valeurs d'entrée). ### 1.2 Nœuds créés (préfixe `refPath` : `/Game/BPs/Room.Room:EventGraph.`) | Rôle | `refPath` (suffixe) | `type_id` relu | Position | |---|---|---|---| | Événement `ComputeRoomBox` | `K2Node_CustomEvent_49` | `AddEvent\|Custom\|ComputeRoomBox` (OutputDelegate 0, then 1) | 38000, 0 | | Getter `StaticMeshComponent` | `K2Node_VariableGet_282` | `\|GetStaticMeshComponent` (créé par `Variables\|Acteurdemaillagestatique\|ObtenirStaticMeshComponent`) | 38000, 300 | | Getter `Wall2` | `K2Node_VariableGet_283` | `\|GetWall2` (créé par `Variables\|Pardéfaut\|ObtenirWall2`) | 38000, 450 | | Getter `Wall4` | `K2Node_VariableGet_284` | `\|GetWall4` (créé par `Variables\|Pardéfaut\|ObtenirWall4`) | 38000, 600 | | **sol** = `GetWorldLocation(StaticMeshComponent)` | `K2Node_CallFunction_240` | `Transformation\|GetWorldLocation` | 38300, 300 | | **W2** = `GetWorldLocation(Wall2)` | `K2Node_CallFunction_476` | `Transformation\|GetWorldLocation` | 38300, 450 | | **W4** = `GetWorldLocation(Wall4)` | `K2Node_CallFunction_477` | `Transformation\|GetWorldLocation` | 38300, 600 | | **R** = `GetActorLocation(self vide = Room)` | `K2Node_CallFunction_478` | `Transformation\|GetActorLocation` | 38300, 150 | | `W2 − sol` | `K2Node_PromotableOperator_9` | `Math\|Vecteur\|vector-vector` | 38600, 450 | | `W4 − sol` | `K2Node_PromotableOperator_10` | `Math\|Vecteur\|vector-vector` | 38600, 600 | | `BreakVector(W2 − sol)` → X | `K2Node_CallFunction_479` | `Math\|Vecteur\|BreakVector` | 38900, 450 | | `BreakVector(W4 − sol)` → Y | `K2Node_CallFunction_480` | `Math\|Vecteur\|BreakVector` | 38900, 600 | | `MakeVector(X, Y, 0)` | `K2Node_CallFunction_481` | `Math\|Vecteur\|MakeVector` | 39200, 500 | | `Abs` | `K2Node_CallFunction_482` | `Math\|Vecteur\|Vector_GetAbs` (créé par `Math\|Vecteur\|VectorGetAbs`) | 39450, 500 | | `Abs − (30,30,0)` | `K2Node_PromotableOperator_11` | `Math\|Vecteur\|vector-vector` | 39650, 500 | | **E** = `ComponentMax(Abs − 30, (0,0,0))` (écart E1, § 2) | `K2Node_CallFunction_483` | `Math\|Vecteur\|Vector_ComponentMax` | 39800, 500 | | **Min0** = `R − E` | `K2Node_PromotableOperator_12` | `Math\|Vecteur\|vector-vector` | 40000, 200 | | **Max0** = `R + E` | `K2Node_PromotableOperator_13` | `Math\|Vecteur\|vector+vector` | 40000, 400 | Les opérateurs ont été créés par `Utilitaires|Opérateurs|Soustraire` / `Ajouter`, typés « vecteur » par la première liaison (A), comme prévu par la fiche. ### 1.3 Liens faits (`connect_pins`, 18, tous `{"returnValue":null}`) et valeurs | # | Sortie (nœud.index) | Entrée (nœud.broche index) | |---|---|---| | L1 | VariableGet_282.0 | CallFunction_240.self 0 | | L2 | VariableGet_283.0 | CallFunction_476.self 0 | | L3 | VariableGet_284.0 | CallFunction_477.self 0 | | L4 | CallFunction_476.0 | PromotableOperator_9.A 0 | | L5 | CallFunction_240.0 | PromotableOperator_9.B 1 | | L6 | CallFunction_477.0 | PromotableOperator_10.A 0 | | L7 | CallFunction_240.0 | PromotableOperator_10.B 1 | | L8 | PromotableOperator_9.0 | CallFunction_479.InVec 0 | | L9 | PromotableOperator_10.0 | CallFunction_480.InVec 0 | | L10 | CallFunction_479.X 0 | CallFunction_481.X 0 | | L11 | CallFunction_480.Y 1 | CallFunction_481.Y 1 | | L12 | CallFunction_481.0 | CallFunction_482.A 0 | | L13 | CallFunction_482.0 | PromotableOperator_11.A 0 | | L14 | PromotableOperator_11.0 | CallFunction_483.A 0 | | L15 | CallFunction_478.0 | PromotableOperator_12.A 0 | | L16 | CallFunction_483.0 | PromotableOperator_12.B 1 | | L17 | CallFunction_478.0 | PromotableOperator_13.A 0 | | L18 | CallFunction_483.0 | PromotableOperator_13.B 1 | Valeurs : `set_pin_value` PromotableOperator_11.B (index 1) = `30,30,0` (relu : `"value":"30,30,0"`) ; CallFunction_481.Z = `0.0` (défaut, relu) ; CallFunction_483.B = `0, 0, 0` (défaut, relu) ; CallFunction_478.self vide (= Room, relu `connected_pins:[]`). Non reliés, comme prévu : `CustomEvent_49.then` (F2 câble l'exécution), sorties de `PromotableOperator_12` (Min0) et `_13` (Max0) (consommées en F2), sorties inutilisées des `BreakVector`. ### 1.4 Relecture `get_node_infos` final groupé sur 13 nœuds (CustomEvent_49, CallFunction_240, 476, 477, 478, 480, 481, 483, PromotableOperator_9 à 13) : les 18 liens apparaissent des deux côtés (les 3 getters, 479 et 482 sont vus par les `connected_pins` de leurs voisins) ; types de broches tous `Vector` sauf X / Y / Z des `BreakVector` / `MakeVector` (`Float (double-précision)`) ; aucune divergence avec la fiche. Index de broches relus avant câblage (3 lectures intermédiaires) : conformes à la fiche (`BreakVector` X 0 / Y 1 / Z 2 ; opérateurs A 0, B 1, sortie 0 ; `GetWorldLocation` self 0, sortie 0). ### 1.5 Compilation `compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true}` → `{"returnValue":null}`, aucune exception (critère de la fiche, rubrique « Fin de chaque fiche »). `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). Pas de `save_assets` (F7). ## 2. Écarts à la SPEC - **E1 (écart à la fiche, pour suivre la SPEC)** : la SPEC B2b-1 (`CAM-SPEC.md:375`) exige `Ex = Max(Abs(Wall2.X − sol.X) − 30, 0)`, `Ey = Max(Abs(Wall4.Y − sol.Y) − 30, 0)` ; la fiche F1 § 3 s'arrête à `Soustraire B = (30,30,0) → E` (le `Max(…, 0)` n'y figure pas). J'ai ajouté **un nœud**, `K2Node_CallFunction_483` `Vector_ComponentMax(A = Abs − (30,30,0), B = (0,0,0))`, dont la sortie est `E`. Effet : identique à la fiche tant que `|W2.X − sol.X| ≥ 30` et `|W4.Y − sol.Y| ≥ 30` ; sinon la boîte se réduit à `R` sur l'axe au lieu d'avoir `Min0 > Max0` (bornes croisées dans `VectorBoundedToBox`). Z : `MakeVector.Z = 0` → `E.Z = 0`, Z remplacé en F2. Retrait sur décision de l'orchestrateur : `delete_node` CallFunction_483, puis `connect_pins` PromotableOperator_11.0 → PromotableOperator_12.B 1 et → PromotableOperator_13.B 1 (3 appels, relecture). - Aucun autre écart : 5 variables, événement, sol, W2, W4, R, X, Y, `MakeVector(X, Y, 0)`, `Abs`, marge 30, `Min0`, `Max0` conformes ; aucun nœud existant touché ; aucun `break_pins` ni `delete_node` ; aucune garde `IsValid` ajoutée (aucune n'est demandée ; « vide » n'est pas un état normal établi pour ces composants, voir § 5). ## 3. Instantané Fait par l'orchestrateur avant F1 (non refait ici) : `D:\Game\LifePlay_Backup_5.5\CAM-B2b\manifest.csv`, ligne 2 relue : `"Content\BPs\Room.uasset","True","6060745","A5FA970E821DC2D0D9BF220FD43B9DE6","2026-10-13T15:25:45"`. Disque après F1 : `md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"` → `a5fa970e821dc2d0d9bf220fd43b9de6` (= instantané : rien d'enregistré). Retour arrière avant F7 : fermer l'éditeur sans enregistrer suffit ; après F7 : `Tools\Restore.ps1 -Lot CAM-B2b -Only Content\BPs\Room.uasset`, éditeur fermé, sur décision de l'orchestrateur (jamais lancé ici). ## 4. Ce qui n'a pas été fait - F2 et suivantes (partie Z, extérieur, `Définir C2BoxMin/Max`, exécution `then`) : hors périmètre. - Type effectif des 5 variables non relu (`add_variable` rend `null`, aucun outil de lecture des variables appelé). - `hyper_blueprint_debug_inspect`, journal de l'éditeur : non consultés (§ 1.5). - `save_assets` : interdit avant F7. Les modifications vivent en mémoire de l'éditeur PID 10708 : une fermeture ou un plantage avant F7 les perd (l'instantané reste intact). - Preuve en jeu (build empaqueté + `LogStats`) : hors rôle. ## 5. Points à confirmer en VAL 1. E1 : `Vector_ComponentMax` (CallFunction_483) gardé (SPEC) ou retiré (fiche) — décision de l'orchestrateur. 2. Types des variables : `C2BoxMin`, `C2BoxMax` = Vector ; `C2Yaw`, `C2Height`, `C2Dist` = float (sous-type `real` float ou double) — à relire en F2 / F3 (premier getter ou setter) ou par dump. 3. `PromotableOperator_11.B` stocké `30,30,0` : valeur sérialisée à confirmer après `save_assets` (F7) par dump. 4. `Wall2` / `Wall4` (catégorie `Pardéfaut`, `Static Mesh Component Référence d'objet`) : composants toujours présents ou variables affectées à l'exécution ? Lecture sans `IsValid`, comme `isPointInsideRoom` (formule reprise par la SPEC) ; si elles peuvent être vides, `GetWorldLocation` donnerait un `Accessed None` (à vérifier par `LogStats`). 5. Getter `StaticMeshComponent` = composant natif hérité d'`AStaticMeshActor` (`Acteurdemaillagestatique`) : à confirmer comme celui que cite la SPEC (ROOM:4050-4052). 6. Compilation stricte jugée sur l'absence d'exception seulement (pas de liste de diagnostics) ; recontrôle en F7 et par `CompileAllBlueprints` éditeur fermé. ## 6. Fichiers à commiter - `A Docs/Migration/etat/CAM/CAM-B2b-IMPL-F1.md` (dépôt du jeu, branche `ue5.8`). - `Content/BPs/Room.uasset` : rien à commiter pour F1 (non enregistré) ; il le sera après F7 et la VAL. Tours : 56 / 60 ## Constats - `create_node` ne rend que le `refPath` (pas les broches) : une lecture `get_node_infos` groupée après plusieurs créations économise des tours. - `ObtenirStaticMeshComponent` n'existe pas sous `Variables|Pardéfaut` : le getter natif est `Variables|Acteurdemaillagestatique|ObtenirStaticMeshComponent` (premier `create_node` en erreur : « The node could not be created / Variables|Pardéfaut|ObtenirStaticMeshComponent does not exist »). - `find_node_types` filtre « ComponentMax » → `Math|Vecteur|VectorComponentMax` (relu `Math|Vecteur|Vector_ComponentMax`). - `add_variable` accepte `type_name` `Vector` et `float` ; `add_event` rend le `refPath` du `CustomEvent`.