11 KiB
11 KiB
CAM-B2b : fiches lp-mcp-bp (2026-10-13)
GO d'écriture de Big Boss du 2026-10-13 : option 1, écritures par lp-mcp-bp, un appel MCP à la fois. SPEC :
CAM-SPEC.md § « CAM-B2b » (amendement B2b, MD5 0f801b71). Room seul.
Découpage et barème
Budget : 75 tours par agent ; ≈ 3 appels par nœud. B2b compte ≈ 70 nœuds, soit ≈ 200 appels. Il est découpé en 7 fiches d'environ 50 appels, exécutées l'une après l'autre dans le même éditeur. Chaque fiche :
- grille a1 b1 c1 d1 e1 f1 = 6 → N2, ajustée à N3 (agent
lp-mcp-bp, écriture MCP sous instantané) ; - S = C3 1 (
lp-mcp§ 3) + f 1 = 2 < 3 : pas de scission supplémentaire.
| Fiche | Contenu (SPEC B2b) | Appels estimés |
|---|---|---|
| F1 | B2b-0 (5 variables) + ComputeRoomBox, partie XY |
≈ 55 |
| F2 | ComputeRoomBox, partie Z, extérieur et affectations |
≈ 45 |
| F3 | B2b-2 (appel de la boîte, borne de Desired, rayon 20) + B2b-5 (lacet, distance, hauteur) |
≈ 50 |
| F4 | B2b-4 (trajectoire protégée de la poursuite) | ≈ 40 |
| F5 | B2b-3 (repli vers le haut) | ≈ 55 |
| F6 | B2b-6 : CircleCamera, LeftRight, ScrollDownUp |
≈ 50 |
| F7 | B2b-6 : RotateCamera, DownUp ; compilation stricte finale ; save_assets |
≈ 40 |
| Après F7, l'orchestrateur ferme l'éditeur, puis lance V5 et V6. |
Rubriques communes à toutes les fiches
- Préalables : BUILD-GO de Big Boss (2026-10-13, conditions 1 à 6) ; instantané
Backup_5.5\CAM-B2b\fait par l'orchestrateur (RoomA5FA970E) ; éditeur headless déjà ouvert (port 8000) ; la session qui te lance est connectée àunreal-mcp. Chargeselect:mcp__unreal-mcp__call_toolpar ToolSearch. Outil absent :BLOCKED-MCP. - Règle absolue : un seul appel
mcp__unreal-mcp__call_toolpar message, lectures comprises. Jamais deux. - Graphe :
{"refPath":"/Game/BPs/Room.Room:EventGraph"}; nœud :/Game/BPs/Room.Room:EventGraph.K2Node_<Nom>; broche :{"direction":"EGPD_Input|EGPD_Output","index_id":n,"node":{"refPath":…}}. - Outils (toolset
editor_toolset.toolsets.blueprint.BlueprintTools) :create_node {graph, type_id, pos},connect_pins {output_pin, input_pin},break_pins,set_pin_value {pin, value}(vecteur : "x,y,z"),get_node_infos {nodes:[{refPath}]},find_node_types {graph, type_id_filter, context_pins:[]},add_variable {blueprint:{refPath:"/Game/BPs/Room.Room"}, name, type_name},add_event {blueprint, event_name, position},compile_blueprint {blueprint, warnings_as_errors}. Toolseteditor_toolset.toolsets.asset.AssetTools:save_assets {asset_paths:["/Game/BPs/Room"]}, F7 seulement. - Identifiants connus (éditeur en français) :
Utilitaires|ContrôleDeFlux|Branche(exécution 0, Condition 1 ; then 0, else 1) ;Utilitaires|Opérateurs|Ajouter/Soustraire/Multiplier/Inférieurà(<)(typés à la 1re liaison) ;Math|Vecteur|BreakVector(X 0, Y 1, Z 2) /MakeVector;Math|Vecteur|VectorBoundedtoBox/SelectVector/RotateVectorAroundAxis/VectorGetAbs/Distance(Vector);Transformation|GetWorldLocation/GetActorLocation/GetWorldScale;Collision|SphereTraceByChannel(Start 1, End 2, Radius 3, TraceChannel 4, ActorsToIgnore 6 ; then 0, OutHit 1, ReturnValue 2) ;Collision|BreakHitResult(Location 4, Normal 6) ;Variables|Pardéfaut|Obtenir<Var>/Définir<Var>;Appelerunefonction|<Événement>. Un identifiant inconnu se cherche parfind_node_typesavec un filtre court (ex. « Clamp », « SelectFloat », « Abs »). Après chaquecreate_node, relire les index de broches parget_node_infosavant de câbler.
- Nœuds existants (relus en B2) : 455
GetSocketLocation(Mesh,'head')(out 0) ; 458MakeVector=Desired(out 0 → 459.End et 62.in1) ; 459SphereTraceByChannel; 460BreakHitResult; PO3vector*vector(A ← 454Normalize2D, B = (−175,−175,−175), out → PO4.B) ; PO5float+float(A ← 457.Z, B 60, out → 458.Z) ; PO6 (Normal × (12,12,12)) ; PO7 (Location + PO6, out → 61.in1) ; 61 / 62 =Définir C2Target; MakeArray_5 = [MC, CamRoom] ; CE47ComputeC2Target(then 1 → 459) ; 467 appelComputeC2Target(then → 474) ; 468VInterpTo(out → 474.in2 et 473.in0) ; 473FindLookAtRotation; 474SetActorLocationAndRotation; 268Obtenir CamRoom; 261PlayerCharacter; PO8 =GetViewTarget(GI.PC) == CamRoom(bool, réutilisable). - Interdits : aucun autre asset ; ne touche à aucun nœud hors fiche ; ni
delete_nodenibreak_pinshors des liens nommés ; pas dewrite_graph_dsl; pas deProgrammaticToolsetpour écrire ; pas desave_assetsavant F7 ; pas de git ; tu ne fermes pas l'éditeur. - Arrêt : refus de permission, erreur inattendue, écart à la SPEC ou index de broche différent de la fiche → arrêt et compte rendu (état de reprise : nœuds créés, liens faits), sans contourner.
- Fin de chaque fiche :
compile_blueprint {warnings_as_errors:true}sur Room. Une exception → arrêt. Puisget_node_infosdes nœuds créés. - Livrable : ajoute ta section à
Docs\Migration\etat\CAM\CAM-B2b-IMPL-F<n>.md(un fichier par fiche, un seul Write) : nœuds créés (refPath,type_id), liens, valeurs, compilation, écarts, tours. - Compte rendu : court, en français, avec les noms des nœuds créés (utiles à la fiche suivante).
F1 — variables et ComputeRoomBox, partie XY
add_variable×5 :C2BoxMinVector ;C2BoxMaxVector ;C2Yawfloat ;C2Heightfloat ;C2Distfloat. Le défaut deC2Dist(175) se règle en F3 par la valeur d'entrée des nœuds, pas par le CDO : voir F3.add_eventComputeRoomBox(position x 38000, y 0).- Nœuds (positions x 38000-40000, y 0-800) :
- getters
StaticMeshComponent,Wall2,Wall4→GetWorldLocation×3 (sol, W2, W4) ; GetActorLocation(self vide = Room) →R;SoustrairevecteurW2 − sol→BreakVector→ X ;SoustrairevecteurW4 − sol→BreakVector→ Y ;MakeVector(X, Y, 0)→VectorGetAbs→Soustrairevecteur, B = (30,30,0) →E;Min0=R − E(Soustraire) ;Max0=R + E(Ajouter).
- getters
- Laisser
Min0etMax0non affectés (F2 termine). Compilation stricte :Min0etMax0sans consommateur ne donnent aucun avertissement (nœuds purs). Compte rendu : noms des nœudssol(GetWorldLocation),Min0,Max0, duCustomEventdeComputeRoomBox.
F2 — ComputeRoomBox, partie Z, extérieur et affectations
BreakVector(Min0),BreakVector(Max0),BreakVector(sol); getterWallT→GetWorldLocation→BreakVector.ZMin=sol.Z + 50;ZTopIn=WallT.Z − 25.- Extérieur :
GetWorldScale(StaticMeshComponent)→BreakVector→Z < 0.05(Inférieurà(<)) →SelectFloat(A = 1000000, B = ZTopIn, bPickA = <résultat>)→ZTop. ChercherSelectFloatparfind_node_types. MakeVector(Min0.X, Min0.Y, ZMin)→Définir C2BoxMin;MakeVector(Max0.X, Max0.Y, ZTop)→Définir C2BoxMax.- Exécution :
ComputeRoomBox.then→Définir C2BoxMin→Définir C2BoxMax.
F3 — B2b-2 (appel de la boîte, borne de Desired) et B2b-5 (lacet, distance, hauteur)
break_pinsCE47.then (out 1) → 459.execute (in 0) ; (N)Appelerunefonction|ComputeRoomBox; CE47.then → (N). Puis (N).then → 459.execute.- (N)
Obtenir C2BoxMin,Obtenir C2BoxMax; (N)VectorBoundedtoBox(InVect ← 458, Min, Max)=DesiredB.break_pins458 → 459.End ;DesiredB→ 459.End (in 2) ;break_pins458 → 62.in1 ;DesiredB→ 62.in1.
set_pin_value459.Radius (in 3) = "20.0" ; PO6.B (in 1) = "20.0,20.0,20.0".- (N)
VectorBoundedtoBox(PO7, Min, Max):break_pinsPO7 → 61.in1, puis (N) → 61.in1. - B2b-5 :
break_pins454 → PO3.A ; (N)Multipliervecteur (A ← 454, B = "-1,-1,-1") ;- (N)
RotateVectorAroundAxis(InVect ← ce produit, AngleDeg ← Obtenir C2Yaw, Axis = "0,0,1")=Bdir→ PO3.A ; - PO3.B, aujourd'hui une constante (−175 ×3) : (N)
Obtenir C2Dist→ (N)Ajouterfloat (A ← C2Dist, B = 175) → (N)MakeVector(d, d, d)→ PO3.B. Comme le défaut deC2Distvaut 0, la distance réelle est 175 + C2Dist ; les bornes deviennent C2Dist ∈ [−75, 125] (F6) ; - hauteur :
break_pinsPO5 → 458.Z (in 2) ; (N)Ajouterfloat (A ← PO5, B ←Obtenir C2Height) → 458.Z.
- Contrôle : à
C2Yaw= 0,C2Height= 0,C2Dist= 0,Desired= la valeur de B2.
F4 — B2b-4 (trajectoire protégée de la poursuite)
break_pins467.then (out 0) → 474.execute (in 0) ; (N)SphereTraceByChannel(Start ← 455, End ← 468, Radius 20, TraceChannel "TraceTypeQuery2", ActorsToIgnore ← MakeArray_5) ; 467.then → (N).exec ; (N).then → 474.exec.- (N)
BreakHitResult← OutHit ; (N)Multipliervecteur (Normal × "20,20,20") ; (N)Ajouter(Location + ce produit) ; (N)SelectVector(A ← cette somme, B ← 468, bPickA ← trace.ReturnValue); (N)VectorBoundedtoBox(← SelectVector, C2BoxMin, C2BoxMax)=Safe. break_pins468 → 474.NewLocation (in 2) et 468 → 473.Start (in 0) ;Safe→ 474.in2 et 473.in0.
F5 — B2b-3 (repli vers le haut)
- Après 61 et 62, qui n'ont pas de
then: (N) Branche ; 61.then → Branche.exec ; 62.then → Branche.exec. - Condition : (N)
Obtenir C2Target→ (N)Distance(Vector)(← C2Target, ← 455) → (N)Inférieurà(<), B = 80. - Vrai :
Desired2=VectorBoundedtoBox(455 + (0,0,100) + Bdir × (60,60,60), Min, Max), avecBdir(nœud F3) multiplié par "60,60,60" ;- (N)
SphereTraceByChannel(Start ← 455, End ← Desired2, 20, TraceTypeQuery2, MakeArray_5); BreakHitResult;Location + Normal × (20,20,20);SelectVector(somme, Desired2, ReturnValue);VectorBoundedtoBox;- (N)
Définir C2Target. Faux → fin.
F6 — B2b-6 : CircleCamera (CE1 → IfThenElse_26), LeftRight (CE4 → IfThenElse_9), ScrollDownUp (CE55 → IfThenElse_10)
Pour chacun : break_pins CE.then (out 1) → branche d'origine ; (N) Branche (Condition ← PO8) ; CE.then → (N) ;
(N).else → branche d'origine ; (N).then → réglage :
CircleCamera:Définir C2Yaw←C2Yaw + DeltaSeconds(paramètre de CE1, out 2) ;LeftRight:Définir C2Yaw←C2Yaw + AxisValue × 2;ScrollDownUp:Définir C2Dist←Clamp(C2Dist − Values × 15, −75, 125)(nœudClampfloat : chercher « Clamp »).
F7 — B2b-6 : RotateCamera (CE19 → IfThenElse_25), DownUp (CE8 → IfThenElse_8) ; fin
Même schéma que F6 :
RotateCamera:Définir C2Height←Clamp(C2Height + DeltaSeconds × 3, −40, 150);DownUp:Définir C2Height←Clamp(C2Height + AxisValue × 3, −40, 150). Puis :- relecture
get_node_infos: CE1, CE4, CE8, CE19, CE55, 459, 467, 474, 61, 62 ; - compilation stricte ;
save_assets/Game/BPs/Roomseul. Fin : ne ferme pas l'éditeur.