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

Fiche CAM-B2n — Niveau N3 — Modèle prévu non indiqué par la fiche | utilisé claude-opus-5-5 — Agent A-MCP-BP (implémenteur Blueprint par MCP) — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot

CAM-B2n-IMPL : orbite de la caméra de scène autour du couple, Room (2026-10-14)

Résultat : fait, avec l'amendement B2n-a (option A). Les 7 nœuds et les 14 liens sont posés (L1 à L13, L11 remplacé par L11a et L11b). L'axe vaut 0,0,1. Tous les nœuds touchés ont été relus. La compilation stricte n'a donné aucun diagnostic, et seul Room a été sauvegardé. Le travail s'est fait en deux passages dans le même éditeur (pid 1272) :

  • premier passage : arrêt sur l'écart E1, après la création de 101 et 535 ;
  • reprise : sur décision de l'orchestrateur, consignée dans CAM-B2n-FICHE.md § « Amendement B2n-a ».

1. Fichiers modifiés

  • Content/BPs/Room.uasset (dépôt du jeu, copie 5.8). Sauvegardé par save_assets le 2026-10-14 ; journal de l'éditeur l. 2481 à 2487.
    • MD5 avant B2n (état laissé par B2k) : 6be71e0110c4187fa02d7ac9c1c92306 ;
    • MD5 après B2n : 3a451fddf991ac01a699af7bd1fbdc12.
  • Docs/Migration/etat/CAM/CAM-B2n-IMPL.md (ce livrable).

2. Écarts à la SPEC

  • E1 (amendé, option A) : GetActorArrayAverageLocation est BlueprintCallable, il a des broches d'exécution. Source : D:/Game/Launcher/Engine/UE_5.8/Engine/Source/Runtime/Engine/Classes/Kismet/GameplayStatics.h:76. Il est donc placé dans le fil d'exécution : L11a 101.then → 535.execute, puis L11b 535.then → 538.execute. Ces deux liens remplacent L11.
  • E2 (amendé) : la soustraction et l'addition passent par les opérateurs génériques Utilitaires|Opérateurs|Soustraire et Ajouter, de classe K2Node_PromotableOperator.
    • À la création, leur type_id affiché est Utilitaires|Gestiondutemps|FrameNumber-Int (+Int), avec des broches de type « Caractère de remplacement ».
    • Après le branchement d'un vecteur, ils deviennent Math|Vecteur|vector-vector et Math|Vecteur|vector+vector, avec des broches Vector (relu).
  • Ordre des écritures : j'ai posé L3 juste après la reprise, avant de créer les 5 autres nœuds, parce que c'était la condition d'arrêt et qu'un refus aurait ainsi laissé le moins d'écritures possible. J'ai posé L5 juste après la création de Soustraire, pour vérifier le typage vecteur avant de poursuivre. Le graphe final est celui de la fiche amendée.
  • Tours : 63 au total pour un budget de 60, sous le plafond de 75. Le dépassement vient de la reprise ordonnée en cours de route, sans nouveau budget, et de deux lectures du journal avant la sauvegarde.

3. Instantané

D:\Game\LifePlay_Backup_5.5\CAM-B2kmn\manifest.csv (instantané commun du passage, pris par l'orchestrateur) :

"Rel","Existed","Size","MD5","Date"
"Content\BPs\Room.uasset","True","6387514","18565365B1195BF2416A1048BF9051B6","2026-10-14T00:59:11"
"Content\BPs\PC.uasset","True","3404928","A19510E613F31905437BAB48F38C6154","2026-10-14T00:59:11"

Retour arrière, éditeur fermé : .\Tools\Restore.ps1 -Lot CAM-B2kmn -Only Content\BPs\Room.uasset. Il ramène Room à l'état d'avant B2k (18565365…), ce qui annule aussi B2k. L'état de B2k seul (6be71e01…) n'a pas d'instantané séparé.

4. Ce qui n'a pas été fait

  • hyper_blueprint_debug_inspect : outil absent du serveur. Je l'ai remplacé par compile_blueprint {warnings_as_errors:true} et la lecture du journal.
  • Ni CompileAllBlueprints, ni build, ni jeu : cela revient à la VAL et au BUILD, éditeur fermé.
  • Aucun IsValid ajouté (voir § Garde en Constats).

5. Points à confirmer en VAL

  • V5, dump de Room comparé à l'état de B2k :
    • 7 nœuds de plus : IfThenElse_101, CallFunction_535 à _538, PromotableOperator_46 et _47 ;
    • 14 liens de plus (§ Liens) et 537.Axis = (0, 0, 1) ;
    • aucune autre différence ; le nœud 512 de B2k est présent et inchangé.
  • 537.Axis est enregistré sous la chaîne 0,0,1, alors que 497 porte 0.0,0.0,1.0. Le dump doit montrer Z = 1.
  • CustomEvent_1.DeltaSeconds (Float double précision) alimente 537.AngleDeg (Float simple précision). La conversion implicite a été acceptée sans diagnostic. Elle est à voir dans V6.
  • V6 : CompileAllBlueprints éditeur fermé = référence.
  • V7 (CAM-COMMUN-6-TESTS.md), à l'essai en jeu :
    • pendant le sexe, la souris fait tourner la caméra autour du couple, cadrage gardé ;
    • hors sexe, rien ne change ;
    • surveiller le cas SexPersons vide pendant SexOn (orbite autour de l'origine).
  • L'éditeur a fait une sauvegarde automatique de Room dans Saved/Autosaves/Game/BPs/Room_Auto1.uasset (journal l. 2407, pendant l'arrêt du premier passage). Elle n'est pas dans Content ; à ignorer.

6. Fichiers à commiter

Dépôt du jeu (copie 5.8, branche ue5.8) :

M Content/BPs/Room.uasset
A Docs/Migration/etat/CAM/CAM-B2n-IMPL.md

Room.uasset contient aussi la modification de B2k (nœud 512), qui ne peut pas en être séparée : le ticket au gardien doit le dire.

Tours : 63 / 60

Constats

Appels MCP (un par message)

Premier passage :

  1. AssetTools.load_asset {"asset_path":"/Game/BPs/Room"} → /Game/BPs/Room.Room.
  2. get_node_infos sur 149, 148, 147, 146, CommutativeAssociativeBinaryOperator_26, IfThenElse_19, IfThenElse_26, VariableGet_102, VariableGet_86, VariableGet_106, CustomEvent_1 → conforme à « État ».
  3. find_node_types (filtre par sous-chaîne du type_id) :
    • ActorLocation, contexte 102 Out0 → Transformation|GetActorLocation et Transformation|SetActorLocation ;
    • AverageLocation → Transformation|GetActorArrayAverageLocation ;
    • vector-vector → [] ; RotateAngleAxis → [] ; Math|Vecteur| → sans + ni - ;
    • Subtract, puis - avec contexte → sans rapport ;
    • Opérat → Utilitaires|Opérateurs|Soustraire et Ajouter.
  4. get_node_infos 497 → Math|Vecteur|RotateVectorAroundAxis ; PromotableOperator_17 et _3 → Math|Vecteur|vector*vector.
  5. create_node Branche (7200, 4704) → K2Node_IfThenElse_101, relu.
  6. create_node Transformation|GetActorArrayAverageLocation (7200, 5200) → K2Node_CallFunction_535, relu : execute et then présents, arrêt (E1). is_dirty → true.

Reprise (amendement B2n-a) : 7. get_node_infos 101, 535, 106 → inchangés. 8. connect_pins L3, puis relecture : accepté (Matrice de Person vers Matrice de Acteur). 106 sort toujours vers MacroInstance_13. 9. create_node Transformation|GetActorLocation (7200, 5350) → K2Node_CallFunction_536, relu. 10. create_node Utilitaires|Opérateurs|Soustraire (7550, 5300) → K2Node_PromotableOperator_46, relu (générique). Puis L5 et relecture → Math|Vecteur|vector-vector. 11. create_node Math|Vecteur|RotateVectorAroundAxis (7800, 5300) → K2Node_CallFunction_537, relu. 12. create_node Utilitaires|Opérateurs|Ajouter (8100, 5250) → K2Node_PromotableOperator_47, relu (générique). 13. create_node Transformation|SetActorLocation (8400, 4704) → K2Node_CallFunction_538, relu. bSweep et bTeleport valent false par défaut ; je ne les ai pas modifiés. 14. connect_pins, dans l'ordre : L1, L2, L11a, L11b, L4, L6, L7, L8. Ensuite set_pin_value 537.Axis = 0,0,1, accepté du premier coup. Puis L9, L10, L12, L13. Chaque appel a renvoyé null. 15. Relecture get_node_infos de 17 nœuds : 149, 101, 535 à 538, 46, 47, 102, 86, 106, CustomEvent_1, 19, 26, 29, 96, MacroInstance_13. Résultat conforme (§ Relecture). 16. AssetTools.is_dirty {"asset_path":"/Game/BPs/Room"} → true. 17. BlueprintTools.compile_blueprint {"blueprint":{"refPath":"/Game/BPs/Room.Room"},"warnings_as_errors":true} → {"returnValue":null}, sans erreur. 18. AssetTools.save_assets {"asset_paths":["/Game/BPs/Room"]} → {"returnValue":true}.

Les 7 nœuds (préfixe /Game/BPs/Room.Room:EventGraph.)

Nœud refPath type_id relu Position
Branche K2Node_IfThenElse_101 `Utilitaires ContrôleDeFlux
Moyenne K2Node_CallFunction_535 `Transformation GetActorArrayAverageLocation`
Position caméra K2Node_CallFunction_536 `Transformation GetActorLocation`
Soustraction K2Node_PromotableOperator_46 `Math Vecteur
Rotation K2Node_CallFunction_537 `Math Vecteur
Addition K2Node_PromotableOperator_47 `Math Vecteur
Déplacement K2Node_CallFunction_538 `Transformation SetActorLocation`

PinID des nœuds créés (direction, index)

  • 101 : execute In0, Condition In1, then Out0, else Out1 (vide).
  • 535 : execute In0, Actors In1 (« Matrice de Acteur »), then Out0, ReturnValue Out1 (Vector).
  • 536 : self In0, ReturnValue Out0 (Vector).
  • 46 et 47 : A In0, B In1, ReturnValue Out0 (Vector après typage).
  • 537 : InVect In0, AngleDeg In1 (Float simple précision), Axis In2, ReturnValue Out0.
  • 538 :
    • entrées : execute In0, self In1, NewLocation In2, bSweep In3 (false), bTeleport In4 (false) ;
    • sorties : then Out0 (vide), SweepHitResult Out1, ReturnValue Out2.
  • Broches existantes utilisées :
    • 149 then Out0 ;
    • 86 SexOn Out0 ;
    • 106 SexPersons Out0 ;
    • 102 SceneCamera Out0 ;
    • CustomEvent_1 DeltaSeconds Out2.

Liens posés (14)

Lien Sortie Entrée
L1 CallFunction_149 Out0 (then) IfThenElse_101 In0 (execute)
L2 VariableGet_86 Out0 (SexOn) IfThenElse_101 In1 (Condition)
L3 VariableGet_106 Out0 (SexPersons) CallFunction_535 In1 (Actors)
L4 VariableGet_102 Out0 (SceneCamera) CallFunction_536 In0 (self)
L5 CallFunction_536 Out0 PromotableOperator_46 In0 (A)
L6 CallFunction_535 Out1 PromotableOperator_46 In1 (B)
L7 PromotableOperator_46 Out0 CallFunction_537 In0 (InVect)
L8 CustomEvent_1 Out2 (DeltaSeconds) CallFunction_537 In1 (AngleDeg)
L9 CallFunction_535 Out1 PromotableOperator_47 In0 (A)
L10 CallFunction_537 Out0 PromotableOperator_47 In1 (B)
L11a IfThenElse_101 Out0 (then) CallFunction_535 In0 (execute)
L11b CallFunction_535 Out0 (then) CallFunction_538 In0 (execute)
L12 VariableGet_102 Out0 (SceneCamera) CallFunction_538 In1 (self)
L13 PromotableOperator_47 Out0 CallFunction_538 In2 (NewLocation)

Valeur posée : CallFunction_537 In2 (Axis) = 0,0,1, relue 0,0,1.

Relecture (étape 5 de la fiche)

  • 149.then → 101 seul. Ses entrées sont inchangées : execute ← 19 Out1, self ← 102, NewRotation ← 148.
  • 102 Out0 → 146, 149, 229, 228, 536, 538.
  • 86 Out0 → CommutativeAssociativeBinaryOperator_19, 29, 28, 453, 101 ; self ← 103.
  • 106 Out0 → MacroInstance_13 In1, 535 In1 ; self ← 105.
  • CustomEvent_1 :
    • DeltaSeconds Out2 → CommutativeAssociativeBinaryOperator_26, _16, _27, PromotableOperator_28, 537 ;
    • then Out1 → 96.
  • Inchangés :
    • 19 : then → 29, else → 149 ;
    • 26 : then → 19, else vide, Condition ← CommutativeAssociativeBinaryOperator_19 ;
    • 29 : then → MacroInstance_13, else → IfThenElse_21 ;
    • 96 : then → CallFunction_516, else → 26 ;
    • MacroInstance_13 : LoopBody → 153, Array Element → 150 et 153, Array ← 106.
  • Nœuds créés : tous leurs liens correspondent au tableau ci-dessus. 101.else et 538.then sont vides.

Compilation

compile_blueprint en mode strict (warnings_as_errors:true) → null, sans erreur. Journal de l'éditeur :

  • l. 2476 : LogBlueprint: Compiling Blueprint '/Game/BPs/Room.Room' ;
  • l. 2477 : LogUObjectHash, puis plus aucune ligne d'erreur ou d'avertissement jusqu'à l'appel suivant. C'est la même forme que la compilation de B2k (l. 2273-2274).

Sauvegarde

Journal de l'éditeur D:\Game\LifePlay_Backup_5.5\CAM-B2kmn\editeur\editeur-B2kmn.log :

2481 [2026.10.13-23.14.29:576][908]LogFileHelpers: Saving Package: /Game/BPs/Room
2485 ...Cmd: OBJ SAVEPACKAGE PACKAGE="/Game/BPs/Room" FILE=".../LifePlay-master 5.8/Content/BPs/Room.uasset" SILENT=true
2486 ...LogSavePackage: Moving output files for package: /Game/BPs/Room

Dans les lignes 2478 à 2511, aucun autre paquet n'est sauvegardé, et il n'y a ni Error ni Warning. Les horodatages du journal sont en UTC.

MD5 (2026-10-14, md5sum dans la copie 5.8, après la sauvegarde)

3a451fddf991ac01a699af7bd1fbdc12 *Content/BPs/Room.uasset
f45be57a39d13d3eb19d0b543153ab0b *Content/BPs/PC.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
  • Room diffère de 6be71e01….
  • PC (f45be57a…), GI (e64b5b37…) et Person (8668a47c…) sont inchangés.
  • git status --short -- Content/ affiche les 4 fichiers en M. Pour PC, GI et Person, ces modifications sont antérieures à B2n.

Garde Accessed None

  • Aucun IsValid ajouté :
    • SceneCamera est déjà lu sans garde par 146 et 149 sur ce chemin ;
    • GI.SexPersons n'est lu que si SexOn est vrai (101, puis 535). Avant B2n, GI était déjà lu sur ce chemin par 86, via 103. 106 le lit via un autre getter, 105 : il s'agit probablement de la même variable (estimé).
  • SexPersons vide pendant SexOn : la moyenne vaut (0, 0, 0), sans Accessed None. Ce cas est à surveiller en V7.

À verser

lp-mcp § 3 :

  • GetActorArrayAverageLocation est BlueprintCallable (GameplayStatics.h:76) et doit être mis dans le fil d'exécution ;
  • les opérateurs vectoriels se créent par Utilitaires|Opérateurs|Ajouter / Soustraire. À la création, le type_id affiché est Utilitaires|Gestiondutemps|FrameNumber±Int, avec des broches génériques ; il devient Math|Vecteur|vector±vector dès qu'un vecteur est branché ;
  • RotateAngleAxis a pour type_id Math|Vecteur|RotateVectorAroundAxis ;
  • find_node_types filtre par sous-chaîne du type_id ;
  • connect_pins, set_pin_value et compile_blueprint renvoient null en cas de succès : seule la relecture prouve le résultat ;
  • AssetTools.is_dirty {asset_path} fonctionne ;
  • un tableau de Person se branche sur un tableau d'Actor ;
  • set_pin_value d'un vecteur accepte 0,0,1.