14 KiB
Fiche CAM-B2b-F3 — 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-F3-IMPL : appel de la boîte, borne de Desired, rayon 20 (B2b-2) ; lacet, distance, hauteur (B2b-5) (2026-10-13)
Consignes : CAM-B2b-FICHES.md § « Rubriques communes » (l. 23-63) et § « F3 » (l. 88-104) ; SPEC CAM-SPEC.md
§ « CAM-B2b », lignes B2b-2 (l. 376) et B2b-5 (l. 379). UE-GO / BUILD-GO de Big Boss du 2026-10-13 (cité par
l'orchestrateur). Éditeur headless PID 10708, port 8000, connexion unreal-mcp partagée (MCPA-T1) ; Room chargé avec
F1 + F2 en mémoire. Un seul call_tool par message ; 51 appels MCP au total (13 create_node, 6 break_pins,
23 connect_pins, 5 set_pin_value, 3 get_node_infos, 1 compile_blueprint). Aucun delete_node, save_assets,
write_graph_dsl ni ProgrammaticToolset.
1. Fichiers modifiés
Content/BPs/Room.uasset: modifié en mémoire de l'éditeur seulement, non enregistré (pas desave_assetsavant F7). Preuve : MD5 disque avant et après F3 = MD5 de l'instantané (§ 3).- Graphe
/Game/BPs/Room.Room:EventGraph, zone deComputeC2Target(CE47 en 34000, 1500) ; nœuds neufs en x 34100-36650, y 1300-2750.
1.1 Lecture avant écriture (get_node_infos groupé, 10 nœuds existants)
Conforme à la fiche : CustomEvent_47.then (out 1) → CallFunction_459.execute (in 0) ; CallFunction_458.0 →
459.End (in 2) et → VariableSet_62.C2Target (in 1) ; 459.Radius (in 3) = 12.0 (Float (simple précision)) ;
CallFunction_454.0 → PromotableOperator_3.A (in 0) ; PO3.B (in 1) = -175.0,-175.0,-175.0, sans lien
(constante) ; PO5.0 → 458.Z (in 2), PO5.B = 60.0 ; PO6.B (in 1) = 12.0,12.0,12.0 ; PO7.0 →
VariableSet_61.C2Target (in 1).
1.2 Nœuds créés (préfixe refPath : /Game/BPs/Room.Room:EventGraph.)
| Rôle | refPath (suffixe) |
type_id demandé → relu |
Broches relues | Position |
|---|---|---|---|---|
Appel ComputeRoomBox |
K2Node_CallFunction_494 |
Appelerunefonction|ComputeRoomBox → |ComputeRoomBox |
execute 0, self 1 (vide = Room) ; then 0 | 34350, 1300 |
Obtenir C2BoxMin |
K2Node_VariableGet_286 |
Variables|Pardéfaut|ObtenirC2BoxMin → |GetC2BoxMin |
out 0 Vector |
35100, 2400 |
Obtenir C2BoxMax |
K2Node_VariableGet_287 |
Variables|Pardéfaut|ObtenirC2BoxMax → |GetC2BoxMax |
out 0 Vector |
35100, 2500 |
DesiredB = borne de Desired |
K2Node_CallFunction_495 |
Math|Vecteur|VectorBoundedtoBox → Math|Vecteur|Vector_BoundedToBox |
InVect 0, InBoxMin 1, InBoxMax 2 ; out 0 | 35550, 2300 |
| Borne de PO7 (→ 61) | K2Node_CallFunction_496 |
idem → Math|Vecteur|Vector_BoundedToBox |
idem | 36650, 2300 |
Normalize2D × (−1) |
K2Node_PromotableOperator_17 |
Utilitaires|Opérateurs|Multiplier → Math|Vecteur|vector*vector (après liaison A) |
A 0, B 1 ; out 0 | 34450, 2300 |
Bdir = rotation de lacet |
K2Node_CallFunction_497 |
Math|Vecteur|RotateVectorAroundAxis → idem |
InVect 0, AngleDeg 1 (Float (simple précision)), Axis 2 ; out 0 |
34700, 2450 |
Obtenir C2Yaw |
K2Node_VariableGet_288 |
Variables|Pardéfaut|ObtenirC2Yaw → |GetC2Yaw |
out 0 Float (double-précision) |
34400, 2550 |
Obtenir C2Dist |
K2Node_VariableGet_289 |
Variables|Pardéfaut|ObtenirC2Dist → |GetC2Dist |
out 0 Float (double-précision) |
34100, 2750 |
d = C2Dist + 175 |
K2Node_PromotableOperator_18 |
Utilitaires|Opérateurs|Ajouter → Math|Flottant|float+float (après liaison A) |
A 0, B 1 ; out 0 | 34300, 2750 |
MakeVector(d, d, d) |
K2Node_CallFunction_498 |
Math|Vecteur|MakeVector → idem |
X 0, Y 1, Z 2 ; out 0 | 34500, 2750 |
Hauteur = PO5 + C2Height |
K2Node_PromotableOperator_19 |
Utilitaires|Opérateurs|Ajouter → Math|Flottant|float+float (après liaison A) |
A 0, B 1 ; out 0 | 35200, 2150 |
Obtenir C2Height |
K2Node_VariableGet_290 |
Variables|Pardéfaut|ObtenirC2Height → |GetC2Height |
out 0 Float (double-précision) |
34950, 2250 |
Les trois opérateurs avaient à la création un type_id trompeur (Utilitaires|Gestiondutemps|Seconds*FrameRate,
…|FrameNumber+Int) et des broches Caractère de remplacement ; relus typés à la relecture finale.
1.3 Liens coupés (break_pins, 6, tous {"returnValue":null})
| # | Sortie | Entrée | Point de la fiche |
|---|---|---|---|
| C1 | CustomEvent_47.then 1 | CallFunction_459.execute 0 | 1 |
| C2 | CallFunction_458.0 (Desired) |
CallFunction_459.End 2 | 2 |
| C3 | CallFunction_458.0 | VariableSet_62.C2Target 1 | 2 |
| C4 | PromotableOperator_7.0 | VariableSet_61.C2Target 1 | 4 |
| C5 | CallFunction_454.0 (Normalize2D) |
PromotableOperator_3.A 0 | 5 |
| C6 | PromotableOperator_5.0 | CallFunction_458.Z 2 | 5 (hauteur) |
1.4 Liens faits (connect_pins, 23, tous {"returnValue":null})
| # | Sortie | Entrée |
|---|---|---|
| L1 | CustomEvent_47.then 1 | CallFunction_494.execute 0 |
| L2 | CallFunction_494.then 0 | CallFunction_459.execute 0 |
| L3 | CallFunction_458.0 | CallFunction_495.InVect 0 |
| L4 | VariableGet_286.0 | CallFunction_495.InBoxMin 1 |
| L5 | VariableGet_287.0 | CallFunction_495.InBoxMax 2 |
| L6 | CallFunction_495.0 | CallFunction_459.End 2 |
| L7 | CallFunction_495.0 | VariableSet_62.C2Target 1 |
| L8 | PromotableOperator_7.0 | CallFunction_496.InVect 0 |
| L9 | VariableGet_286.0 | CallFunction_496.InBoxMin 1 |
| L10 | VariableGet_287.0 | CallFunction_496.InBoxMax 2 |
| L11 | CallFunction_496.0 | VariableSet_61.C2Target 1 |
| L12 | CallFunction_454.0 | PromotableOperator_17.A 0 |
| L13 | PromotableOperator_17.0 | CallFunction_497.InVect 0 |
| L14 | VariableGet_288.0 (C2Yaw) |
CallFunction_497.AngleDeg 1 |
| L15 | CallFunction_497.0 (Bdir) |
PromotableOperator_3.A 0 |
| L16 | VariableGet_289.0 (C2Dist) |
PromotableOperator_18.A 0 |
| L17 | PromotableOperator_18.0 | CallFunction_498.X 0 |
| L18 | PromotableOperator_18.0 | CallFunction_498.Y 1 |
| L19 | PromotableOperator_18.0 | CallFunction_498.Z 2 |
| L20 | CallFunction_498.0 | PromotableOperator_3.B 1 (constante −175 remplacée ; relue "" après liaison) |
| L21 | PromotableOperator_5.0 | PromotableOperator_19.A 0 |
| L22 | VariableGet_290.0 (C2Height) |
PromotableOperator_19.B 1 |
| L23 | PromotableOperator_19.0 | CallFunction_458.Z 2 |
1.5 Valeurs (set_pin_value, 5, toutes {"returnValue":null}, relues)
| Broche | Avant | Après (relu) |
|---|---|---|
| CallFunction_459.Radius 3 | 12.0 |
20.0 |
| PromotableOperator_6.B 1 | 12.0,12.0,12.0 |
20.0,20.0,20.0 |
| PromotableOperator_17.B 1 | (neuf) | -1.0,-1.0,-1.0 |
| CallFunction_497.Axis 2 | (neuf, 0, 0, 0) |
0.0,0.0,1.0 |
| PromotableOperator_18.B 1 | (neuf) | 175.0 |
1.6 Relecture et chaîne obtenue
get_node_infos final groupé sur les 23 nœuds touchés (13 créés + CE47, 454, 458, 459, PO3, PO5, PO6, PO7, 61, 62) :
les 6 coupures sont absentes des deux côtés (454.0 ne sort plus que vers PO17 ; 458.0 ne sort plus que vers 495 ;
PO7.0 ne sort plus que vers 496 ; PO5.0 ne sort plus que vers PO19 ; CE47.then ne sort plus que vers 494) ; les
23 liens apparaissent des deux côtés ; les 5 valeurs relues ; types : vecteurs Vector, d, hauteur et composantes
Float (double-précision), AngleDeg et Radius Float (simple précision). Liens non touchés relus intacts :
459.Start ← 455, 459.ActorsToIgnore ← MakeArray_5, 459.then / ReturnValue → IfThenElse_90, 459.OutHit → 460,
458.X / Y ← 456, PO5.A ← 457.Z, PO3.0 → PO4.B, PO6.A ← 460.Normal, PO7.A ← 460.Location, 61 / 62.execute ← IfThenElse_90.
Aucune divergence.
Chaîne : ComputeC2Target → ComputeRoomBox (C2BoxMin, C2BoxMax) → SphereTraceByChannel(tête → Bound(Desired), r 20) ; Desired = MakeVector(456.X, 456.Y, tête.Z + 60 + C2Height), avec en amont
PO3 = RotateVectorAroundAxis(Normalize2D(Fwd) × −1, C2Yaw, (0,0,1)) × (C2Dist + 175) ; touché →
C2Target := Bound(Location + Normal × 20) ; libre → C2Target := Bound(Desired).
1.7 Compilation
compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true} → {"returnValue":null},
aucune exception (critère de la 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
- E3 (SPEC incohérente, fiche suivie) : la colonne « valeurs » de B2b-5 (
CAM-SPEC.md:379) dit « à C2Yaw = 0, C2Height = 0, C2Dist = 175 : identique à B2 », alors que B2b-0 (CAM-SPEC.md:374) fixeC2Dist= 0 (décalage, distance = 175 +C2Dist) et que la fiche F3 (CAM-B2b-FICHES.md:100-104) prescritd = C2Dist + 175et le contrôle àC2Dist = 0. Appliqué :d = C2Dist + 175(PO18). ÀC2Dist = 175, la distance serait 350. Le texte de la colonne B2b-5 est à corriger par l'orchestrateur (point 7). Bdir × (175 + C2Dist)(SPEC, scalaire) est réalisé parvector*vectoravecMakeVector(d, d, d)(fiche) : équivalent composante par composante.AngleDeg(simple précision) est alimenté parC2Yaw(double précision) : conversion implicite du moteur, la compilation stricte l'accepte.- Garde
Accessed None: aucuneIsValidajoutée (aucune demandée). Les nœuds neufs ne lisent aucune référence d'objet (vecteurs, flottants, appel d'événement surself). En revanche,ComputeRoomBox(F1-F2 : lectures deStaticMeshComponent,Wall2,Wall4,WallT) s'exécute désormais à chaqueComputeC2Target(point 3). - Lecture intermédiaire des opérateurs après typage non faite (économie de tours) :
set_pin_valueposé juste après la liaison A, typage et valeurs confirmés à la relecture finale (§ 1.6). - Positions des nœuds : choisies hors des nœuds existants (cosmétique, non prescrites).
- Aucun autre écart : points 1 à 5 de la fiche faits dans l'ordre, aucun nœud hors fiche touché.
3. Instantané
Fait par l'orchestrateur avant F1 (non refait, consigne) : D:\Game\LifePlay_Backup_5.5\CAM-B2b\manifest.csv,
Room A5FA970E… (ligne citée par CAM-B2b-IMPL-F2.md § 3, non relue ici). Disque mesuré :
md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"
a5fa970e821dc2d0d9bf220fd43b9de6 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset (2026-10-13T15:41:43+02:00, avant F3)
a5fa970e821dc2d0d9bf220fd43b9de6 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset (2026-10-13T15:45:08+02:00, après F3)
= instantané : rien d'enregistré. Retour arrière avant F7 : fermer l'éditeur sans enregistrer (perd F1 à F3) ; 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
- F4 et suivantes (poursuite protégée, repli, pilotage) : hors périmètre.
Bdir=K2Node_CallFunction_497pour F5. hyper_blueprint_debug_inspect, journal de l'éditeur : non consultés (§ 1.7).save_assets: interdit avant F7 ; F1 à F3 vivent en mémoire de l'éditeur PID 10708 (une fermeture ou un plantage avant F7 les perd ; l'instantané reste intact).- Contrôle du point 6 de la fiche (
Desired= valeur de B2 aux trois variables nulles) : non mesuré à l'exécution, seulement déduit du câblage (point 1). - Preuve en jeu (build empaqueté +
LogStats) : hors rôle.
5. Points à confirmer en VAL
- Point 6 de la fiche, estimé par le câblage : à
C2Yaw = 0,RotateVectorAroundAxisrend son entrée, doncPO3 = −Normalize2D × (175,175,175) = Normalize2D × (−175,−175,−175)(= B2) ; àC2Height = 0,458.Z = PO5(= B2) ;458.X / Yinchangés (← 456). À mesurer (dump ou trace d'exécution). - Changement voulu :
Desiredborné par la boîte avant la trace (459.End) et avantC2Target(62) ; le cas touché (61) borné aussi. À confirmer en jeu : C2 jamais hors de la pièce. ComputeRoomBoxappelé à chaqueComputeC2Target(fréquence d'appel de CE47 non relue ici) : aucunAccessed NonesurStaticMeshComponent,Wall2,Wall4,WallTdansLogStats.- Conversion double → simple de
C2YawversAngleDeg: sans perte utile pour un angle en degrés ; à revoir si la compilation deCompileAllBlueprints(éditeur fermé) l'avertit. - Valeurs sérialisées après
save_assets(F7) :459.Radius = 20,PO6.B = (20,20,20),PO17.B = (−1,−1,−1),497.Axis = (0,0,1),PO18.B = 175,PO3.Blié (plus de constante −175), par dump (LPDumpFunction). - Compilation stricte jugée sur l'absence d'exception seulement ; recontrôle en F7 et par
CompileAllBlueprints. - E3 : corriger la colonne B2b-5 de
CAM-SPEC.md:379(« C2Dist = 175 » → « C2Dist = 0 ») ; les bornes de B2b-6 (C2Dist ∈ [−75, 125], distance 100 à 300) sont cohérentes avecd = C2Dist + 175.
6. Fichiers à commiter
A Docs/Migration/etat/CAM/CAM-B2b-IMPL-F3.md(dépôt du jeu, brancheue5.8).Content/BPs/Room.uasset: rien à commiter pour F3 (non enregistré) ; il le sera après F7 et la VAL.
Tours : 57 / 60
Constats
Appelerunefonction|ComputeRoomBoxcrée|ComputeRoomBox: execute 0, self 1, then 0 (self vide = Room).Math|Vecteur|VectorBoundedtoBoxse relitMath|Vecteur|Vector_BoundedToBox: InVect 0, InBoxMin 1, InBoxMax 2, out 0.Math|Vecteur|RotateVectorAroundAxis: InVect 0, AngleDeg 1 (simple précision, accepte un getter double), Axis 2.Utilitaires|Opérateurs|MultiplierapparaîtUtilitaires|Gestiondutemps|Seconds*FrameRateà la création ; relié en A à un vecteur, il devientvector*vectoret accepte aussitôtset_pin_valueB = "x,y,z".- Lier une entrée constante (PO3.B) efface sa valeur (relue
"") : vérifier l'absence de lien avant, comme demandé. - Économie : créer tous les nœuds, une lecture groupée (13 nœuds), câbler et poser les valeurs, une relecture finale (23 nœuds) : 51 appels pour 13 nœuds, 6 coupures, 23 liens, 5 valeurs.