LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2b-IMPL-F5.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
Raw Blame History

Fiche CAM-B2b-F5 — 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-F5-IMPL : repli vers le haut (B2b-3) (2026-10-13)

Consignes : CAM-B2b-FICHES.md § « Rubriques communes » (l. 23-63) et § « F5 » (l. 115-125) ; SPEC CAM-SPEC.md § « CAM-B2b », ligne B2b-3 (l. 377). 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 à F4 en mémoire. Un seul call_tool par message ; 54 appels MCP au total (15 create_node, 29 connect_pins, 6 set_pin_value, 3 get_node_infos, 1 compile_blueprint). Aucun break_pins, 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 de save_assets avant F7). Preuve : MD5 disque après F5 = MD5 de l'instantané (§ 3).
  • Graphe /Game/BPs/Room.Room:EventGraph, fin de ComputeC2Target (CE47), après VariableSet_61 / _62 (x 36900) ; nœuds neufs en x 36700-40300, y 1500-2350.

1.1 Lecture avant écriture (get_node_infos groupé, 7 nœuds existants)

Conforme à la fiche : VariableSet_61 (|SetC2Target, execute ← IfThenElse_90.0, C2Target ← CallFunction_496) et VariableSet_62 (|SetC2Target, execute ← IfThenElse_90.1, C2Target ← CallFunction_495) : then 0 libre pour les deux ; CallFunction_455 (Transformation|GetSocketLocation, self ← VariableGet_264, head) sortie 0 → 457, 459, 464, 473, 499 ; CallFunction_497 (Math|Vecteur|RotateVectorAroundAxis, InVect ← PO17, AngleDeg ← 288, Axis 0.0,0.0,1.0) sortie 0 → PO3.A ; MakeArray_5 ([0] ← 261, [1] ← 268) → 459.6, 499.6 ; VariableGet_286 (|GetC2BoxMin) → 495, 496, 502 ; VariableGet_287 (|GetC2BoxMax) → 495, 496, 502.

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
Branche du repli K2Node_IfThenElse_95 Utilitaires|ContrôleDeFlux|Branche → idem execute 0, Condition 1 ; then 0, else 1 37400, 1550
Obtenir C2Target K2Node_VariableGet_291 Variables|Pardéfaut|ObtenirC2Target → |GetC2Target C2Target out 0 (Vector) 36700, 1900
Distance(C2Target, tête) K2Node_CallFunction_503 Math|Vecteur|Distance(Vector) → idem V1 0, V2 1 ; out 0 (Float (double-précision)) 36950, 1900
Distance < 80 K2Node_PromotableOperator_22 Utilitaires|Opérateurs|Inférieurà(<) → Math|Flottant|float<float (après liaison A) A 0, B 1 (double) ; out 0 (Booléen) 37150, 1900
Bdir × 60 K2Node_PromotableOperator_23 Utilitaires|Opérateurs|Multiplier → Math|Vecteur|vector*vector A 0, B 1 ; out 0 37650, 2350
tête + (0,0,100) K2Node_PromotableOperator_24 Utilitaires|Opérateurs|Ajouter → Math|Vecteur|vector+vector A 0, B 1 ; out 0 37650, 2150
(tête + 100 Z) + Bdir × 60 K2Node_PromotableOperator_25 Utilitaires|Opérateurs|Ajouter → Math|Vecteur|vector+vector A 0, B 1 ; out 0 37900, 2250
Desired2 = borne K2Node_CallFunction_504 Math|Vecteur|VectorBoundedtoBox → Math|Vecteur|Vector_BoundedToBox InVect 0, InBoxMin 1, InBoxMax 2 ; out 0 38150, 2250
Trace du repli K2Node_CallFunction_505 Collision|SphereTraceByChannel → idem execute 0, Start 1, End 2, Radius 3, TraceChannel 4, bTraceComplex 5, ActorsToIgnore 6, DrawDebugType 7, bIgnoreSelf 8, TraceColor 9, TraceHitColor 10, DrawTime 11 ; then 0, OutHit 1, ReturnValue 2 38450, 1500
BreakHitResult K2Node_CallFunction_506 Collision|BreakHitResult → idem Hit 0 ; Location out 4, Normal out 6 (18 sorties) 38900, 2000
Normal × 20 K2Node_PromotableOperator_26 Utilitaires|Opérateurs|Multiplier → Math|Vecteur|vector*vector A 0, B 1 ; out 0 39250, 2250
Location + (Normal × 20) K2Node_PromotableOperator_27 Utilitaires|Opérateurs|Ajouter → Math|Vecteur|vector+vector A 0, B 1 ; out 0 39500, 2050
SelectVector K2Node_CallFunction_507 Math|Vecteur|SelectVector → idem A 0, B 1, bPickA 2 ; out 0 39750, 1950
Borne finale K2Node_CallFunction_508 Math|Vecteur|VectorBoundedtoBox → Math|Vecteur|Vector_BoundedToBox InVect 0, InBoxMin 1, InBoxMax 2 ; out 0 40000, 1950
Définir C2Target (repli) K2Node_VariableSet_66 Variables|Pardéfaut|DéfinirC2Target → |SetC2Target execute 0, C2Target 1 ; then 0, Output_Get 1 40300, 1500

À la création, les opérateurs portent le type_id trompeur déjà vu en F3 et F4 (…|Seconds*FrameRate, …|FrameNumber+Int, et pour le comparateur Math|Durée|Timespan<Timespan), avec des broches Caractère de remplacement. À la relecture finale, ils sont typés Vector, ou Float (double-précision) pour PO22. Réutilisés sans copie (nœuds purs) : 455 (tête), 497 (Bdir), MakeArray_5, VariableGet_286, VariableGet_287.

1.3 Liens coupés

sans objet : la fiche F5 n'en prescrit aucun (61.then et 62.then étaient libres, relu au § 1.1) ; aucun break_pins.

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

# Sortie Entrée Point de la fiche
L1 VariableSet_61.then 0 IfThenElse_95.execute 0 1
L2 VariableSet_62.then 0 IfThenElse_95.execute 0 1
L3 VariableGet_291.0 (C2Target) CallFunction_503.V1 0 2
L4 CallFunction_455.0 (tête) CallFunction_503.V2 1 2
L5 CallFunction_503.0 (distance) PromotableOperator_22.A 0 2
L6 PromotableOperator_22.0 IfThenElse_95.Condition 1 2
L7 CallFunction_497.0 (Bdir) PromotableOperator_23.A 0 3
L8 CallFunction_455.0 (tête) PromotableOperator_24.A 0 3
L9 PromotableOperator_24.0 PromotableOperator_25.A 0 3
L10 PromotableOperator_23.0 PromotableOperator_25.B 1 3
L11 PromotableOperator_25.0 CallFunction_504.InVect 0 3
L12 VariableGet_286.0 (C2BoxMin) CallFunction_504.InBoxMin 1 3
L13 VariableGet_287.0 (C2BoxMax) CallFunction_504.InBoxMax 2 3
L14 IfThenElse_95.then 0 CallFunction_505.execute 0 3
L15 CallFunction_455.0 (tête) CallFunction_505.Start 1 3
L16 CallFunction_504.0 (Desired2) CallFunction_505.End 2 3
L17 MakeArray_5.0 ([MC, CamRoom]) CallFunction_505.ActorsToIgnore 6 3
L18 CallFunction_505.OutHit 1 CallFunction_506.Hit 0 3
L19 CallFunction_506.Normal 6 PromotableOperator_26.A 0 3
L20 CallFunction_506.Location 4 PromotableOperator_27.A 0 3
L21 PromotableOperator_26.0 PromotableOperator_27.B 1 3
L22 PromotableOperator_27.0 CallFunction_507.A 0 3
L23 CallFunction_504.0 (Desired2) CallFunction_507.B 1 3
L24 CallFunction_505.ReturnValue 2 CallFunction_507.bPickA 2 3
L25 CallFunction_507.0 CallFunction_508.InVect 0 3
L26 VariableGet_286.0 (C2BoxMin) CallFunction_508.InBoxMin 1 3
L27 VariableGet_287.0 (C2BoxMax) CallFunction_508.InBoxMax 2 3
L28 CallFunction_508.0 VariableSet_66.C2Target 1 3
L29 CallFunction_505.then 0 VariableSet_66.execute 0 3

IfThenElse_95.else 1 : laissé libre (fiche : « Faux → rien (fin) »).

1.5 Valeurs (set_pin_value, 6, toutes {"returnValue":null}, relues)

Broche Avant (relu à la création) Après (relu)
PromotableOperator_22.B 1 (neuf, "", joker) 80.0 (Float (double-précision))
PromotableOperator_23.B 1 (neuf, "") 60.0,60.0,60.0
PromotableOperator_24.B 1 (neuf, "") 0.0,0.0,100.0
CallFunction_505.Radius 3 0.0 20.0
CallFunction_505.TraceChannel 4 TraceTypeQuery1 TraceTypeQuery2
PromotableOperator_26.B 1 (neuf, "") 20.0,20.0,20.0

Valeurs non prescrites de 505, laissées par défaut et relues identiques à 459 et 499 (F4 § 1.5) : bTraceComplex false, DrawDebugType None, bIgnoreSelf true, TraceColor (R=1,G=0,B=0,A=1), TraceHitColor (R=0,G=1,B=0,A=1), DrawTime 5.000000. IfThenElse_95.Condition garde la valeur par défaut true, sans effet puisque la broche est liée (L6).

1.6 Relecture et chaîne obtenue

get_node_infos final groupé sur les 21 nœuds touchés ou réutilisés : les 15 créés, plus 61, 62, 455, 497, MakeArray_5, 286 et 287. Les 29 liens apparaissent des deux côtés et les 6 valeurs sont relues. Types : vecteurs Vector, bPickA et Condition Booléen, distance et PO22 Float (double-précision), Radius Float (simple précision). Liens non touchés relus intacts : 61.execute ← IfThenElse_90.0, 61.C2Target ← 496 ; 62.execute ← IfThenElse_90.1, 62.C2Target ← 495 ; 455.self ← 264, head ; 455 → 457, 459, 464, 473, 499 (plus 503, PO24, 505) ; 497 ← PO17, 288, Axis (0,0,1), 497 → PO3.A (plus PO23) ; MakeArray_5 → 459.6, 499.6 (plus 505.6), [0] ← 261, [1] ← 268 ; 286 / 287 → 495, 496, 502 (plus 504, 508). Aucune divergence.

Chaîne obtenue en fin de ComputeC2Target : IfThenElse_90 (impact / sans impact) → Définir C2Target (61 ou 62) → Branche 95 (Distance(C2Target, tête) < 80). Si vrai : SphereTraceByChannel(tête → Desired2, r 20, TraceTypeQuery2, ignorer [MC, CamRoom] + self) (505), puis Définir C2Target (66) := Bound(touché ? Location + Normal × 20 : Desired2, C2BoxMin, C2BoxMax), avec Desired2 = Bound(tête + (0,0,100) + Bdir × 60, C2BoxMin, C2BoxMax) (504). Si faux : fin, et C2Target garde la valeur de 61 ou 62, comme après F4.

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 : le chemin -abslog n'a pas été fourni. Pas de save_assets (réservé à F7).

2. Écarts à la SPEC

  • Aucun écart de câblage : la ligne B2b-3 (CAM-SPEC.md:377) et la fiche F5 (CAM-B2b-FICHES.md:115-125) sont réalisées telles quelles (points 1 à 3) ; aucun nœud hors fiche touché ; aucun lien existant coupé.
  • Bdir × 60 et Hit.Normal × 20 (SPEC, scalaires) sont réalisés par vector*vector avec B = (60,60,60) et (20,20,20), comme le prescrit la fiche : c'est équivalent composante par composante.
  • « Location » est la sortie Location (4) de BreakHitResult, centre de la sphère au contact, et non ImpactPoint (5) : même choix que 460 → PO7 (ComputeC2Target) et 500 → PO21 (F4).
  • Seuil 80 : float<float en double précision (la sortie de Distance(Vector) est en double), B = 80.0.
  • Garde Accessed None : aucune IsValid ajoutée, car la fiche n'en demande pas. Les nœuds neufs ne lisent aucune référence d'objet : vecteurs, structure de touche, booléen. MakeArray_5 est réutilisé tel quel, comme en 459 et 499. SelectVector est pur et évalue A et B, mais aucun des deux ne déréférence d'objet : aucune cascade de branches n'est requise. En revanche, 455 (GetSocketLocation, self ← VariableGet_264) est désormais lu en plus par 503 (condition) et par 505 (Start, puis End via PO24). Si sa cible est nulle, un Accessed None déjà présent serait compté plus souvent (point 4 du § 5).
  • Ordre des écritures : chaque set_pin_value d'un opérateur a été posé juste après la liaison de son A, qui le type (comme en F3 et F4). Typage et valeurs sont confirmés à la relecture finale (§ 1.6).
  • Positions des nœuds : choisies hors des nœuds existants (cosmétique, non prescrit).

3. Instantané

Fait par l'orchestrateur avant F1 (non refait, consigne). Manifeste relu et disque mesuré après F5 :

date -Iseconds; md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"; grep -i "Room.uasset" "/d/Game/LifePlay_Backup_5.5/CAM-B2b/manifest.csv"
2026-10-13T15:56:18+02:00
a5fa970e821dc2d0d9bf220fd43b9de6 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset
"Content\BPs\Room.uasset","True","6060745","A5FA970E821DC2D0D9BF220FD43B9DE6","2026-10-13T15:25:45"

Le MD5 du disque est celui de l'instantané : rien n'a été enregistré. Retour arrière avant F7 : fermer l'éditeur sans enregistrer, ce qui perd F1 à F5. 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

  • F6 et F7 (pilotage, compilation finale, enregistrement) : hors périmètre.
  • hyper_blueprint_debug_inspect, journal de l'éditeur : non consultés (§ 1.7).
  • save_assets : interdit avant F7 ; F1 à F5 vivent en mémoire de l'éditeur PID 10708 (une fermeture ou un plantage avant F7 les perd ; l'instantané reste intact).
  • Comportement à l'exécution : non mesuré (aucune PIE, aucun build) ; seulement déduit du câblage.
  • Preuve en jeu (build empaqueté + LogStats) : hors rôle.

5. Points à confirmer en VAL

  1. Cas « distance ≥ 80 » : 95 sort par else (libre), donc C2Target = valeur de 61 ou 62, comme après F4 ; comportement inchangé hors repli (établi par le câblage ; à confirmer en jeu).
  2. Changement voulu (distance < 80) : la cible passe à Bound(tête + (0,0,100) + Bdir × 60), ou au point de contact reculé de 20 le long de la normale, toujours borné par C2BoxMin / C2BoxMax. À confirmer en jeu : près d'un mur, C2 se replie vers le haut et vers l'intérieur, sans sortir de la pièce.
  3. Bdir unitaire et horizontal (estimé) : 497 = RotateVectorAroundAxis(Normalize2D(Fwd) × −1, C2Yaw, (0,0,1)) (F3) ; Normalize2D rend Z = 0 et une rotation autour de Z garde la norme. Desired2 serait donc à 60 cm en arrière (horizontal) et à 100 cm au-dessus de la tête, soit environ 117 cm, avant la borne (non lu dans le moteur).
  4. LogStats : aucun Accessed None nouveau, en particulier sur VariableGet_264 (cible de 455), désormais lu aussi par 503 et 505.
  5. Un seul passage : si la borne ou la touche ramènent la cible à moins de 80 cm, rien ne relance le repli (pas de boucle, voulu par la SPEC). À observer en jeu dans un coin bas de plafond.
  6. Ordre d'exécution : ComputeC2Target (CE47) est appelé par 467 (poursuite) avant la trace 499 (F4) et par PlaceC2. Le repli s'exécute donc dans le même appel, avant que 499 et 474 lisent C2Target (estimé : un événement appelé s'exécute de façon synchrone).
  7. Valeurs sérialisées après save_assets (F7), par dump (LPDumpFunction) : 505.Radius = 20, 505.TraceChannel = TraceTypeQuery2, PO22.B = 80, PO23.B = (60,60,60), PO24.B = (0,0,100), PO26.B = (20,20,20).
  8. V5 (CAM-SPEC.md:382) : SphereTraceSingle 3 (459, 499, 505) ; Vector_BoundedToBox 5 (495, 496, 502, 504, 508 ; attendu ≥ 4) ; Vector_Distance 1 (503) ; RotateAngleAxis 1 (497).
  9. Compilation stricte jugée sur l'absence d'exception seulement ; recontrôle en F7 et par CompileAllBlueprints.

6. Fichiers à commiter

  • A Docs/Migration/etat/CAM/CAM-B2b-IMPL-F5.md (dépôt du jeu, branche ue5.8).
  • Content/BPs/Room.uasset : rien à commiter pour F5 (non enregistré) ; il le sera après F7 et la VAL.

Tours : 62 / 60 (ce Write et la remise du compte rendu compris ; dépassement de 2 dans la marge maxTurns, sans étape ouverte après le budget : la compilation a eu lieu au tour 59)

Constats

  • Utilitaires|Opérateurs|Inférieurà(<) se crée directement par create_node (pas besoin de find_node_types) ; à la création, il est relu Math|Durée|Timespan<Timespan, broches joker. Relié en A à un double, il devient Math|Flottant|float<float et accepte aussitôt set_pin_value B = "80.0".
  • Math|Vecteur|Distance(Vector) : V1 0, V2 1 ; sortie 0 en Float (double-précision).
  • Variables|Pardéfaut|ObtenirC2Target → |GetC2Target (sortie 0) ; DéfinirC2Target → |SetC2Target (execute 0, C2Target 1 ; then 0, Output_Get 1).
  • Une Branche neuve a Condition = true par défaut.
  • Économie : 1 lecture des existants, création de tous les nœuds, 1 lecture groupée, câblage et valeurs, 1 relecture finale (21 nœuds), compilation. Au total, 54 appels pour 15 nœuds, 29 liens et 6 valeurs. Avec 5 tours de lecture des consignes, le budget de 60 est juste : une fiche de cette taille devrait compter environ 65 tours.