LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2b-IMPL-F6a.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

14 KiB
Raw Blame History

Fiche CAM-B2b-F6a — 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-F6a-IMPL : pilotage de C2, CircleCamera et LeftRight (B2b-6, partie 1) (2026-10-13)

Consignes : CAM-B2b-FICHES.md § « Rubriques communes » (l. 23-63) et § « F6 » (l. 127-132), réduit par la fiche F6a à CircleCamera et LeftRight (ScrollDownUp passe en F6b). SPEC : CAM-SPEC.md § « CAM-B2b », ligne B2b-6 (l. 380). BUILD-GO / 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 à F5 en mémoire, non enregistrés. Un seul call_tool par message. 31 appels MCP : 9 create_node, 2 break_pins, 15 connect_pins, 1 set_pin_value, 3 get_node_infos, 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 : modifié en mémoire de l'éditeur seulement, non enregistré (pas de save_assets avant F7). Preuve au § 3 : le MD5 du disque après F6a est celui de l'instantané.
  • Graphe /Game/BPs/Room.Room:EventGraph : événement CircleCamera (CE1, x 5296, y 4688) et événement LeftRight (CE4, x 5072, y 3168). Nœuds neufs en x 5650-6050, y 4250-4450 (CircleCamera) et x 5250-5850, y 2750-2950 (LeftRight).

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

Lecture conforme aux faits de la fiche :

  • K2Node_CustomEvent_1 (AddEvent|Custom|CircleCamera) : then out 1 → IfThenElse_26.execute 0 ; DeltaSeconds out 2 (Float (double-précision)) → CommutativeAssociativeBinaryOperator_26.1, _16.1, _27.1.
  • K2Node_CustomEvent_4 (AddEvent|Custom|LeftRight) : then out 1 → IfThenElse_9.execute 0 ; AxisValue out 2 (Float (double-précision)) → CommutativeAssociativeBinaryOperator_47.0, _13.0, _24.0.
  • K2Node_IfThenElse_26 : execute ← CE1.1 ; Condition ← CommutativeAssociativeBinaryOperator_19.0 ; then 0 → IfThenElse_19.0 ; else 1 libre.
  • K2Node_IfThenElse_9 : execute ← CE4.1 ; Condition ← CommutativeAssociativeBinaryOperator_17.0 ; then 0 → IfThenElse_14.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.

Les deux paramètres d'événement sont en double précision (la fiche prévoyait peut-être de la simple) : aucune conversion implicite n'est nécessaire.

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
CircleCamera Branche C2 K2Node_IfThenElse_96 Utilitaires|ContrôleDeFlux|Branche → idem execute 0, Condition 1 ; then 0, else 1 5650, 4450
CircleCamera Obtenir C2Yaw K2Node_VariableGet_292 Variables|Pardéfaut|ObtenirC2Yaw → |GetC2Yaw C2Yaw out 0 (double) 5650, 4250
CircleCamera C2Yaw + DeltaSeconds K2Node_PromotableOperator_28 Utilitaires|Opérateurs|Ajouter → Math|Flottant|float+float A 0, B 1 ; out 0 (double) 5850, 4250
CircleCamera Définir C2Yaw K2Node_VariableSet_67 Variables|Pardéfaut|DéfinirC2Yaw → |SetC2Yaw execute 0, C2Yaw 1 ; then 0, Output_Get 1 6050, 4400
LeftRight Branche C2 K2Node_IfThenElse_97 Utilitaires|ContrôleDeFlux|Branche → idem execute 0, Condition 1 ; then 0, else 1 5250, 2950
LeftRight Obtenir C2Yaw K2Node_VariableGet_293 Variables|Pardéfaut|ObtenirC2Yaw → |GetC2Yaw C2Yaw out 0 (double) 5250, 2750
LeftRight AxisValue × 2 K2Node_PromotableOperator_29 Utilitaires|Opérateurs|Multiplier → Math|Flottant|float*float A 0, B 1 ; out 0 (double) 5450, 2850
LeftRight C2Yaw + produit K2Node_PromotableOperator_30 Utilitaires|Opérateurs|Ajouter → Math|Flottant|float+float A 0, B 1 ; out 0 (double) 5650, 2750
LeftRight Définir C2Yaw K2Node_VariableSet_68 Variables|Pardéfaut|DéfinirC2Yaw → |SetC2Yaw execute 0, C2Yaw 1 ; then 0, Output_Get 1 5850, 2900

À la création, les opérateurs portent le type_id trompeur déjà vu en F3 à F5 : Utilitaires|Gestiondutemps| FrameNumber+Int pour PO28 et PO30, …|Seconds*FrameRate pour PO29, avec des broches Caractère de remplacement. À la relecture finale, ils sont typés float+float / float*float en double précision. 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_1.then 1 IfThenElse_26.execute 0
C2 CustomEvent_4.then 1 IfThenElse_9.execute 0

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

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

# Sortie Entrée Événement
L1 CustomEvent_1.then 1 IfThenElse_96.execute 0 CircleCamera
L2 IfThenElse_96.else 1 IfThenElse_26.execute 0 CircleCamera
L3 PromotableOperator_8.0 IfThenElse_96.Condition 1 CircleCamera
L4 VariableGet_292.0 (C2Yaw) PromotableOperator_28.A 0 CircleCamera
L5 CustomEvent_1.DeltaSeconds 2 PromotableOperator_28.B 1 CircleCamera
L6 PromotableOperator_28.0 VariableSet_67.C2Yaw 1 CircleCamera
L7 IfThenElse_96.then 0 VariableSet_67.execute 0 CircleCamera
L8 CustomEvent_4.then 1 IfThenElse_97.execute 0 LeftRight
L9 IfThenElse_97.else 1 IfThenElse_9.execute 0 LeftRight
L10 PromotableOperator_8.0 IfThenElse_97.Condition 1 LeftRight
L11 CustomEvent_4.AxisValue 2 PromotableOperator_29.A 0 LeftRight
L12 VariableGet_293.0 (C2Yaw) PromotableOperator_30.A 0 LeftRight
L13 PromotableOperator_29.0 PromotableOperator_30.B 1 LeftRight
L14 PromotableOperator_30.0 VariableSet_68.C2Yaw 1 LeftRight
L15 IfThenElse_97.then 0 VariableSet_68.execute 0 LeftRight

VariableSet_67.then et VariableSet_68.then : laissés libres (fin de l'événement côté C2, comme le prescrit la fiche).

1.5 Valeurs (set_pin_value, 1, {"returnValue":null}, relue)

Broche Avant (relu à la création) Après (relu)
PromotableOperator_29.B 1 (neuf, "", joker) 2.0 (Float (double-précision))

Le set_pin_value a été posé juste après L11, la liaison de A qui type l'opérateur. Les conditions des Branches 96 et 97 gardent la valeur par défaut true, sans effet puisque la broche est liée (L3, L10).

1.6 Relecture et chaîne obtenue

get_node_infos final groupé sur 15 nœuds : les 9 créés, plus CE1, CE4, IfThenElse_26, IfThenElse_9, PO8 et CallFunction_439 (amont de PO8, lu pour la garde). Les 15 liens apparaissent des deux côtés ; la valeur 2.0 est relue. Liens non touchés, relus intacts :

  • CE1.DeltaSeconds → CommutativeAssociativeBinaryOperator_26, _16, _27 (plus PO28) ;
  • CE4.AxisValue → CommutativeAssociativeBinaryOperator_47, _13, _24 (plus PO29) ;
  • IfThenElse_26 : Condition ← CommutativeAssociativeBinaryOperator_19, then → IfThenElse_19, else libre ;
  • IfThenElse_9 : Condition ← CommutativeAssociativeBinaryOperator_17, then → IfThenElse_14, else libre ;
  • PO8 : A ← 439, B ← VariableGet_268, sortie → IfThenElse_91.1 (plus 96.1 et 97.1) ;
  • CallFunction_439 (Pion|GetViewTarget) : self ← VariableGet_262 (Controller), sortie → PromotableOperator_0.0 et PO8.0.

Aucune divergence.

Chaîne obtenue :

  • CircleCamera (CE1) → Branche 96 (GetViewTarget(PC) == CamRoom). Si vrai : Définir C2Yaw (67) := C2Yaw + DeltaSeconds, puis fin. Si faux : IfThenElse_26, chaîne d'origine inchangée.
  • LeftRight (CE4) → Branche 97 (même condition). Si vrai : Définir C2Yaw (68) := C2Yaw + AxisValue × 2, puis fin. Si faux : IfThenElse_9, chaîne d'origine inchangée.

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 n'a pas été appelé : 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 : son 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-6 (CAM-SPEC.md:380), pour CircleCamera et LeftRight, et la fiche F6 (CAM-B2b-FICHES.md:127-131) sont réalisées telles quelles. Seuls les liens CE.then → branche d'origine ont été coupés.
  • Fait différent de la fiche, sans effet : DeltaSeconds et AxisValue sont en double précision, pas en simple. Il n'y a donc aucune conversion implicite.
  • Deux Obtenir C2Yaw distincts (292, 293), un par événement, comme le prescrit la fiche (« (N) Obtenir C2Yaw ») ; PO8 est partagé par trois Branches (91, 96, 97).
  • Garde Accessed None : aucune IsValid ajoutée, car ni la fiche ni la SPEC n'en demandent. 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 CircleCamera et de LeftRight, ce qui n'était pas le cas avant. Si la cible de 262 (le contrôleur) est nulle à ce moment, un Accessed None apparaît là où il n'y en avait pas. Voir le § 5, points 3 et 4.
  • Comportement : identique à l'ancien quand C2 n'est pas la vue (sortie else vers la 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 existants proches, sans effet sur le graphe.

3. Instantané

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

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:01:23+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 à F6a. 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

  • ScrollDownUp (CE55 → IfThenElse_10, Clamp de C2Dist) : renvoyé à F6b par la fiche.
  • F7 (RotateCamera, DownUp, relecture 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 à F6a 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 : CircleCamera et LeftRight prennent else → IfThenElse_26 / IfThenElse_9, chaînes d'origine inchangées. Établi par le câblage ; à confirmer en jeu (pilotage de l'ancienne caméra identique).
  2. Vue C2 : CircleCamera ajoute DeltaSeconds à C2Yaw, et LeftRight ajoute AxisValue × 2. L'effet sur C2 passe par Bdir (F3, 497) au prochain ComputeC2Target. Signes et gains à juger à l'essai (SPEC : « ajustables à l'essai »).
  3. LogStats : aucun Accessed None nouveau sur CallFunction_439 / VariableGet_262. PO8 est maintenant évalué à chaque LeftRight, événement d'axe probablement appelé à chaque image (estimé, non lu), et à chaque CircleCamera.
  4. Cas limite (estimé) : si GetViewTarget rend None et que CamRoom est aussi None (avant sa création), PO8 vaut true (None == None). Les deux événements écrivent alors C2Yaw au lieu de piloter l'ancienne caméra. À vérifier : CamRoom existe-t-elle toujours avant le premier appel possible de ces événements ?
  5. C2Yaw n'est pas borné (la SPEC ne le borne pas) : il croît sans fin à force de tourner. RotateVectorAroundAxis accepte tout angle ; la précision double suffit (estimé).
  6. V5 (CAM-SPEC.md:382) pour ces deux événements : then → nouvelle branche (96, 97) ; else → branche d'origine (26, 9).
  7. Valeur sérialisée après save_assets (F7), par dump (LPDumpFunction) : PO29.B = 2.0.
  8. Compilation stricte jugée sur l'absence d'exception seulement ; à recontrôler en F7 et par CompileAllBlueprints.

6. Fichiers à commiter

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

Tours : 38 / 55 (ce Write et la remise du compte rendu compris ; 31 appels MCP, un par message)

Constats

  • DeltaSeconds (CE1) et AxisValue (CE4) sont en Float (double-précision) : relier A d'un Ajouter ou d'un Multiplier à ces broches le type directement en float+float / float*float, sans conversion.
  • Variables|Pardéfaut|ObtenirC2Yaw → |GetC2Yaw (sortie 0) ; DéfinirC2Yaw → |SetC2Yaw (execute 0, C2Yaw 1 ; then 0, Output_Get 1).
  • CallFunction_439 = Pion|GetViewTarget, self ← VariableGet_262 (Controller), sortie aussi vers PromotableOperator_0.
  • Pour F6b et F7, le même schéma coûte 2 + 4 à 5 créations + 1 lecture + 1 coupure + 7 à 9 liaisons + 0 à 3 valeurs par événement. Ordre économe : créer tous les nœuds, faire une lecture groupée, puis couper chaque lien et le remplacer aussitôt.