LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2b-IMPL-F6b.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-B2b-F6b — 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-F6b-IMPL : pilotage de C2, ScrollDownUp et RotateCamera (B2b-6, partie 2) (2026-10-13)

Consignes : CAM-B2b-FICHES.md § « Rubriques communes » (l. 23-63), § « F6 » (l. 127-132, ScrollDownUp) et § « F7 » (l. 134-136, RotateCamera seulement). DownUp et la fin de F7 passent à la fiche suivante. SPEC : CAM-SPEC.md § « CAM-B2b », ligne B2b-6 (l. 380). Modèle suivi : CAM-B2b-IMPL-F6a.md et son ordre économe : créer tous les nœuds, faire une lecture groupée, puis couper chaque lien et le remplacer aussitôt.

Contexte : UE-GO de Big Boss B2b du 2026-10-13 (cité par l'orchestrateur). Éditeur headless PID 10708, port 8000, connexion unreal-mcp partagée (MCPA-T1). Room chargé, F1 à F6a en mémoire, non enregistrés. Un seul call_tool par message. 43 appels MCP : 3 get_node_infos, 1 find_node_types, 12 create_node, 2 break_pins, 18 connect_pins, 6 set_pin_value et 1 compile_blueprint. Aucun delete_node, save_assets, write_graph_dsl ni ProgrammaticToolset. Aucune écriture par HyperAIStudio.

1. Fichiers modifiés

  • Content/BPs/Room.uasset est modifié en mémoire de l'éditeur seulement, sans enregistrement (pas de save_assets avant F7). Le § 3 le prouve : le MD5 du disque après F6b est celui de l'instantané.
  • Graphe /Game/BPs/Room.Room:EventGraph :
    • événement ScrollDownUp (CE55, x 4896, y 2544) : nœuds neufs en x 5100-5950, y 2150-2350 ;
    • événement RotateCamera (CE19, x 5184, y 5232) : nœuds neufs en x 5400-6250, y 5550-5800.

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

La lecture est conforme aux faits de la fiche :

  • K2Node_CustomEvent_55 (AddEvent|Custom|ScrollDownUp) :
    • then out 1 → IfThenElse_10.execute 0 ;
    • Values out 2 (Float (double-précision)) → CommutativeAssociativeBinaryOperator_2.0, CallFunction_26.2, CommutativeAssociativeBinaryOperator_20.0, _10.0 et _22.0.
  • K2Node_CustomEvent_19 (AddEvent|Custom|RotateCamera) :
    • then out 1 → IfThenElse_25.execute 0 ;
    • DeltaSeconds out 2 (Float (double-précision)) → CommutativeAssociativeBinaryOperator_45.1, _12.1 et _15.1.
  • K2Node_IfThenElse_10 : execute ← CE55.1 ; Condition ← CommutativeAssociativeBinaryOperator_17.0 ; then 0 → IfThenElse_12.0 ; else 1 libre.
  • K2Node_IfThenElse_25 : execute ← CE19.1 ; Condition ← CommutativeAssociativeBinaryOperator_19.0 ; then 0 → IfThenElse_18.0 ; else 1 libre.
  • K2Node_PromotableOperator_8 (Utilitaires|Equal(Object)) : A ← CallFunction_439.0, B ← VariableGet_268.0 ; out 0 (Booléen) → IfThenElse_91.1, _96.1 et _97.1.

Recherche du Clamp : find_node_types {type_id_filter:"Clamp"} sur le graphe. Le résultat flottant est Math|Flottant|Clamp(Float), à côté de Math|Integer|Clamp(Integer), Math|Integer64|Clamp(Integer64), Math|Flottant| ClampAngle, MapRangeClamped et d'autres.

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

Événement Rôle refPath (suffixe) type_id demandé → relu Broches relues Position
ScrollDownUp Branche C2 K2Node_IfThenElse_98 Utilitaires|ContrôleDeFlux|Branche → idem execute 0, Condition 1 ; then 0, else 1 5100, 2350
ScrollDownUp Obtenir C2Dist K2Node_VariableGet_294 Variables|Pardéfaut|ObtenirC2Dist → |GetC2Dist C2Dist out 0 (double) 5100, 2150
ScrollDownUp Values × 15 K2Node_PromotableOperator_31 Utilitaires|Opérateurs|Multiplier → Math|Flottant|float*float A 0, B 1 ; out 0 (double) 5300, 2250
ScrollDownUp C2Dist − produit K2Node_PromotableOperator_32 Utilitaires|Opérateurs|Soustraire → Math|Flottant|float-float A 0, B 1 ; out 0 (double) 5500, 2150
ScrollDownUp Clamp K2Node_CallFunction_509 Math|Flottant|Clamp(Float) → idem Value 0, Min 1, Max 2 ; ReturnValue out 0 (double) 5700, 2200
ScrollDownUp Définir C2Dist K2Node_VariableSet_69 Variables|Pardéfaut|DéfinirC2Dist → |SetC2Dist execute 0, C2Dist 1 ; then 0, Output_Get 1 5950, 2300
RotateCamera Branche C2 K2Node_IfThenElse_99 Utilitaires|ContrôleDeFlux|Branche → idem execute 0, Condition 1 ; then 0, else 1 5450, 5800
RotateCamera Obtenir C2Height K2Node_VariableGet_295 Variables|Pardéfaut|ObtenirC2Height → |GetC2Height C2Height out 0 (double) 5400, 5550
RotateCamera DeltaSeconds × 3 K2Node_PromotableOperator_33 Utilitaires|Opérateurs|Multiplier → Math|Flottant|float*float A 0, B 1 ; out 0 (double) 5600, 5650
RotateCamera C2Height + produit K2Node_PromotableOperator_34 Utilitaires|Opérateurs|Ajouter → Math|Flottant|float+float A 0, B 1 ; out 0 (double) 5800, 5550
RotateCamera Clamp K2Node_CallFunction_510 Math|Flottant|Clamp(Float) → idem Value 0, Min 1, Max 2 ; ReturnValue out 0 (double) 6000, 5600
RotateCamera Définir C2Height K2Node_VariableSet_70 Variables|Pardéfaut|DéfinirC2Height → |SetC2Height execute 0, C2Height 1 ; then 0, Output_Get 1 6250, 5700

À la création, les opérateurs portent le type_id trompeur déjà vu en F3 à F6a, avec des broches Caractère de remplacement :

  • Utilitaires|Gestiondutemps|Seconds*FrameRate pour PO31 et PO33 ;
  • …|FrameNumber-Int pour PO32 ;
  • …|FrameNumber+Int pour PO34.

À la relecture finale, ils sont typés float*float, float-float et float+float, en double précision. À la création, le Clamp a pour défauts Min 0.0 et Max 1.0, remplacés ensuite (§ 1.5). PO8 est réutilisé sans copie (nœud pur).

1.3 Liens coupés (break_pins, 2, tous {"returnValue":null})

# Sortie Entrée
C1 CustomEvent_55.then 1 IfThenElse_10.execute 0
C2 CustomEvent_19.then 1 IfThenElse_25.execute 0

Aucun autre lien n'a été coupé, et rien d'autre n'a été touché dans ces deux événements.

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

# Sortie Entrée Événement
L1 CustomEvent_55.then 1 IfThenElse_98.execute 0 ScrollDownUp
L2 IfThenElse_98.else 1 IfThenElse_10.execute 0 ScrollDownUp
L3 PromotableOperator_8.0 IfThenElse_98.Condition 1 ScrollDownUp
L4 CustomEvent_55.Values 2 PromotableOperator_31.A 0 ScrollDownUp
L5 VariableGet_294.0 (C2Dist) PromotableOperator_32.A 0 ScrollDownUp
L6 PromotableOperator_31.0 PromotableOperator_32.B 1 ScrollDownUp
L7 PromotableOperator_32.0 CallFunction_509.Value 0 ScrollDownUp
L8 CallFunction_509.0 VariableSet_69.C2Dist 1 ScrollDownUp
L9 IfThenElse_98.then 0 VariableSet_69.execute 0 ScrollDownUp
L10 CustomEvent_19.then 1 IfThenElse_99.execute 0 RotateCamera
L11 IfThenElse_99.else 1 IfThenElse_25.execute 0 RotateCamera
L12 PromotableOperator_8.0 IfThenElse_99.Condition 1 RotateCamera
L13 CustomEvent_19.DeltaSeconds 2 PromotableOperator_33.A 0 RotateCamera
L14 VariableGet_295.0 (C2Height) PromotableOperator_34.A 0 RotateCamera
L15 PromotableOperator_33.0 PromotableOperator_34.B 1 RotateCamera
L16 PromotableOperator_34.0 CallFunction_510.Value 0 RotateCamera
L17 CallFunction_510.0 VariableSet_70.C2Height 1 RotateCamera
L18 IfThenElse_99.then 0 VariableSet_70.execute 0 RotateCamera

Les sorties VariableSet_69.then et VariableSet_70.then restent libres : elles marquent la fin de l'événement côté C2, comme le schéma de la fiche (identique à F6a).

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

Broche Avant (relu à la création) Après (relu)
PromotableOperator_31.B 1 (neuf, "", joker) 15.0 (Float (double-précision))
CallFunction_509.Min 1 0.0 -75.0
CallFunction_509.Max 2 1.0 125.0
PromotableOperator_33.B 1 (neuf, "", joker) 3.0 (Float (double-précision))
CallFunction_510.Min 1 0.0 -40.0
CallFunction_510.Max 2 1.0 150.0

Chaque set_pin_value sur un opérateur a été posé juste après la liaison de A, qui type l'opérateur (L4, L13). Les conditions des Branches 98 et 99 gardent leur valeur par défaut true, sans effet puisque la broche est liée (L3, L12).

1.6 Relecture et chaîne obtenue

get_node_infos final groupé sur 17 nœuds : les 12 créés, plus CE55, CE19, IfThenElse_10, IfThenElse_25 et PO8. Les 18 liens apparaissent des deux côtés et les 6 valeurs sont relues. Liens non touchés, relus intacts :

  • CE55.Values → CommutativeAssociativeBinaryOperator_2.0, CallFunction_26.2, _20.0, _10.0, _22.0 (plus PO31.0) ;
  • CE19.DeltaSeconds → CommutativeAssociativeBinaryOperator_45.1, _12.1, _15.1 (plus PO33.0) ;
  • IfThenElse_10 : Condition ← CommutativeAssociativeBinaryOperator_17, then → IfThenElse_12, else libre ;
  • IfThenElse_25 : Condition ← CommutativeAssociativeBinaryOperator_19, then → IfThenElse_18, else libre ;
  • PO8 : A ← 439, B ← VariableGet_268, sortie → IfThenElse_91, _96, _97 (plus 98.1 et 99.1).

Aucune divergence.

Chaîne obtenue :

  • ScrollDownUp (CE55) → Branche 98 (GetViewTarget(PC) == CamRoom).
    • Vrai : Définir C2Dist (69) := Clamp(C2Dist − Values × 15, −75, 125), puis fin.
    • Faux : IfThenElse_10, chaîne d'origine inchangée.
  • RotateCamera (CE19) → Branche 99 (même condition).
    • Vrai : Définir C2Height (70) := Clamp(C2Height + DeltaSeconds × 3, −40, 150), puis fin.
    • Faux : IfThenElse_25, chaîne d'origine inchangée.

1.7 Compilation

compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true} a renvoyé {"returnValue":null}, sans exception : c'est le critère de la rubrique « Fin de chaque fiche ». hyper_blueprint_debug_inspect n'a pas été appelé, car il était absent du serveur le 2026-10-10 (mémoire unreal-mcp-reconnect, non revérifié). Le journal de l'éditeur n'a pas été lu, faute du chemin -abslog. Pas de save_assets : il est réservé à F7.

2. Écarts à la SPEC

  • Aucun écart de câblage. La ligne B2b-6 (CAM-SPEC.md:380) et la fiche (CAM-B2b-FICHES.md:132 et :136) sont réalisées telles quelles pour ScrollDownUp et RotateCamera. Seuls les liens CE.then → branche d'origine ont été coupés.
  • Formules : C2Dist := Clamp(C2Dist − Values × 15, −75, 125) et C2Height := Clamp(C2Height + D × 3, −40, 150). Les opérandes ne sont pas inversés : A de PO32 = C2Dist, B = produit, relu.
  • Typage : Values et DeltaSeconds sont en double précision, comme Clamp(Float) (Value, Min, Max et sortie en double) : aucune conversion implicite.
  • Nœuds par événement : un Obtenir et un Clamp distincts dans chacun, comme le prescrit la fiche (« (N) »). PO8 est désormais partagé par cinq Branches (91, 96, 97, 98, 99).
  • Garde Accessed None : aucune IsValid ajoutée, car ni la fiche ni la SPEC n'en demandent, et les nœuds neufs ne lisent que des flottants. En revanche, PO8 (→ 439 GetViewTarget, self ← VariableGet_262 ; → VariableGet_268 CamRoom) est désormais évalué à chaque appel de ScrollDownUp et de RotateCamera, ce qui n'était pas le cas avant. Même réserve qu'en F6a (§ 5, points 3 et 4).
  • Comportement : identique à l'ancien quand C2 n'est pas la vue (sortie else → branche d'origine). Quand C2 est la vue, la chaîne d'origine n'est plus exécutée : c'est le changement voulu par la SPEC (« vrai → réglage ; faux → branche existante »).
  • Positions des nœuds : choisies près des événements (cosmétique, non prescrit). Elles peuvent chevaucher visuellement des nœuds proches : nœuds LeftRight de F6a (x 5250-5850, y 2750-2950), IfThenElse_25 (5888, 5328). Sans effet sur le graphe.

3. Instantané

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

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-13T16:06:13+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 à F6b ;
  • 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

  • DownUp (CE8 → IfThenElse_8, Clamp(C2Height + AxisValue × 3, −40, 150)) : renvoyé à la fiche suivante (F7).
  • Fin de F7 : relecture de CE1, CE4, CE8, CE19, CE55, 459, 467, 474, 61 et 62, compilation stricte, puis save_assets de /Game/BPs/Room seul. Hors périmètre.
  • hyper_blueprint_debug_inspect et journal de l'éditeur : non consultés (§ 1.7).
  • save_assets : interdit avant F7. F1 à F6b vivent en mémoire de l'éditeur PID 10708 : une fermeture ou un plantage avant F7 les perd, l'instantané restant 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. Vue autre que C2 : ScrollDownUp et RotateCamera prennent else → IfThenElse_10 / IfThenElse_25, avec leurs chaînes d'origine inchangées. Établi par le câblage ; à confirmer en jeu (zoom et tangage de l'ancienne caméra identiques).
  2. Vue C2 :
    • ScrollDownUp retire Values × 15 à C2Dist, borné à [−75, 125] (distance 100 à 300 cm selon la SPEC) ;
    • RotateCamera ajoute DeltaSeconds × 3 à C2Height, borné à [−40, 150]. L'effet passe par ComputeC2Target (F3) au prochain appel. Signes et gains sont à juger à l'essai (SPEC : « ajustables à l'essai »).
  3. LogStats : aucun Accessed None nouveau sur CallFunction_439 / VariableGet_262. PO8 est maintenant évalué à chaque ScrollDownUp et à chaque RotateCamera ; ce dernier est probablement appelé à chaque image pendant la rotation (estimé, appelant non lu).
  4. Cas limite (estimé, déjà noté en F6a) : si GetViewTarget rend None et que CamRoom est aussi None, PO8 vaut true (None == None), et ces événements écrivent alors C2Dist / C2Height au lieu de piloter l'ancienne caméra.
  5. RotateCamera.DeltaSeconds est un delta de tangage selon la fiche, pas un temps (nom hérité). Si l'appelant passe une valeur par image, le gain ×3 dépend de la fréquence d'image. Estimé, à juger à l'essai.
  6. V5 (CAM-SPEC.md:382) pour ces deux événements : then → nouvelle branche (98, 99) ; else → branche d'origine (10, 25).
  7. Valeurs sérialisées après save_assets (F7), à relire par dump (LPDumpFunction) : PO31.B = 15.0 ; 509 Min −75.0, Max 125.0 ; PO33.B = 3.0 ; 510 Min −40.0, Max 150.0.
  8. Compilation stricte jugée sur la seule absence d'exception ; à recontrôler en F7 et par CompileAllBlueprints.

6. Fichiers à commiter

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

Tours : 48 / 60 (ce Write et la remise du compte rendu compris ; 43 appels MCP, un par message)

Constats

  • Math|Flottant|Clamp(Float) crée un K2Node_CallFunction. Broches : Value 0 (défaut 0.0), Min 1 (défaut 0.0), Max 2 (défaut 1.0), ReturnValue out 0, toutes en Float (double-précision) dès la création (pas de joker).
  • Correspondances relevées :
    • Variables|Pardéfaut|ObtenirC2Dist → |GetC2Dist ; ObtenirC2Height → |GetC2Height ;
    • DéfinirC2Dist → |SetC2Dist ; DéfinirC2Height → |SetC2Height ; broches comme SetC2Yaw (execute 0, valeur 1 ; then 0, Output_Get 1).
  • Utilitaires|Opérateurs|Soustraire naît en Utilitaires|Gestiondutemps|FrameNumber-Int. Lier A à un double le type en Math|Flottant|float-float (A − B, A index 0).
  • DownUp (F7), dans le même schéma : 6 créations, 1 coupure, 9 liaisons, 3 valeurs, soit 19 appels plus 1 lecture groupée. Le Clamp se crée directement par Math|Flottant|Clamp(Float), sans find_node_types.
  • À verser : lp-mcp § 3 — type_id Math|Flottant|Clamp(Float) et index Value 0 / Min 1 / Max 2 / sortie 0 ; Soustraire naît en FrameNumber-Int puis devient float-float à la liaison de A.