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é parsave_assetsle 2026-10-14 ; journal de l'éditeur l. 2481 à 2487.- MD5 avant B2n (état laissé par B2k) :
6be71e0110c4187fa02d7ac9c1c92306; - MD5 après B2n :
3a451fddf991ac01a699af7bd1fbdc12.
- MD5 avant B2n (état laissé par B2k) :
Docs/Migration/etat/CAM/CAM-B2n-IMPL.md(ce livrable).
2. Écarts à la SPEC
- E1 (amendé, option A) :
GetActorArrayAverageLocationestBlueprintCallable, 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 : L11a101.then→535.execute, puis L11b535.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|SoustraireetAjouter, de classeK2Node_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-vectoretMath|Vecteur|vector+vector, avec des brochesVector(relu).
- À la création, leur type_id affiché est
- 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é parcompile_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
IsValidajouté (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_46et_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é.
- 7 nœuds de plus :
537.Axisest enregistré sous la chaîne0,0,1, alors que 497 porte0.0,0.0,1.0. Le dump doit montrer Z = 1.CustomEvent_1.DeltaSeconds(Float double précision) alimente537.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
SexPersonsvide pendantSexOn(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 :
AssetTools.load_asset {"asset_path":"/Game/BPs/Room"}→/Game/BPs/Room.Room.get_node_infossur 149, 148, 147, 146,CommutativeAssociativeBinaryOperator_26,IfThenElse_19,IfThenElse_26,VariableGet_102,VariableGet_86,VariableGet_106,CustomEvent_1→ conforme à « État ».find_node_types(filtre par sous-chaîne du type_id) :ActorLocation, contexte 102 Out0 →Transformation|GetActorLocationetTransformation|SetActorLocation;AverageLocation→Transformation|GetActorArrayAverageLocation;vector-vector→[];RotateAngleAxis→[];Math|Vecteur|→ sans+ni-;Subtract, puis-avec contexte → sans rapport ;Opérat→Utilitaires|Opérateurs|SoustraireetAjouter.
get_node_infos497 →Math|Vecteur|RotateVectorAroundAxis;PromotableOperator_17et_3→Math|Vecteur|vector*vector.create_nodeBranche (7200, 4704) →K2Node_IfThenElse_101, relu.create_nodeTransformation|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.
- entrées : execute In0, self In1, NewLocation In2, bSweep In3 (
- Broches existantes utilisées :
- 149 then Out0 ;
- 86 SexOn Out0 ;
- 106 SexPersons Out0 ;
- 102 SceneCamera Out0 ;
CustomEvent_1DeltaSeconds 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_13In1, 535 In1 ; self ← 105. CustomEvent_1:- DeltaSeconds Out2 →
CommutativeAssociativeBinaryOperator_26,_16,_27,PromotableOperator_28, 537 ; - then Out1 → 96.
- DeltaSeconds Out2 →
- 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 enM. Pour PC, GI et Person, ces modifications sont antérieures à B2n.
Garde Accessed None
- Aucun
IsValidajouté :SceneCameraest déjà lu sans garde par 146 et 149 sur ce chemin ;GI.SexPersonsn'est lu que siSexOnest 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é).
SexPersonsvide pendantSexOn: la moyenne vaut (0, 0, 0), sansAccessed None. Ce cas est à surveiller en V7.
À verser
lp-mcp § 3 :
GetActorArrayAverageLocationestBlueprintCallable(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é estUtilitaires|Gestiondutemps|FrameNumber±Int, avec des broches génériques ; il devientMath|Vecteur|vector±vectordès qu'un vecteur est branché ; RotateAngleAxisa pour type_idMath|Vecteur|RotateVectorAroundAxis;find_node_typesfiltre par sous-chaîne du type_id ;connect_pins,set_pin_valueetcompile_blueprintrenvoientnullen cas de succès : seule la relecture prouve le résultat ;AssetTools.is_dirty {asset_path}fonctionne ;- un tableau de
Personse branche sur un tableau d'Actor; set_pin_valued'un vecteur accepte0,0,1.