LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2g-IMPL.md

182 lines
13 KiB
Markdown
Raw Normal View History

Fiche CAM-B2g + CAM-B2h — Niveau N3 — Modèle prévu non précisé par la fiche | utilisé claude-opus-5-5 — Agent lp-mcp-bp (A-MCP-BP) — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot
# CAM-B2g-IMPL : B2g (GI.Wall ignoré par les sondes C2) et B2h (OU CamC1On sur 96 et 97), Room enregistré (2026-10-13)
Résultat : **réussi**, en deux passages dans le même éditeur headless (pid 11516).
- **Passage 1** : A (B2g) fait et relu. Arrêt avant toute écriture de B, sur l'écart E1 (§ 2).
- **Tranché par l'orchestrateur** : option 1. La liste du § 10 B.8 du DIAG était incomplète ; le DIAG a reçu
l'amendement E1 (je ne l'ai pas relu). `IfThenElse_100` reste sur PO_8 et les écritures de B ne changent pas.
- **Passage 2** : B fait et relu, compilation stricte sans diagnostic, `save_assets` de Room seul.
- Room passe de `f2b082d2…` à `0c8eb59f…`. GI et Person sont inchangés.
Spécification : `Docs/Migration/etat/CAM/CAM-COMMUN3-DIAG.md` § 10 A et B, § 7 (partie 1). Préfixe des nœuds :
`/Game/BPs/Room.Room:EventGraph.`. Un seul appel MCP par message. Outils : `editor_toolset.toolsets.asset.AssetTools`
(AT) et `editor_toolset.toolsets.blueprint.BlueprintTools` (BT).
## 1. Fichiers modifiés
- `Content/BPs/Room.uasset` : 1 nœud créé, 1 broche ajoutée, 5 liens créés, 2 liens remplacés.
- MD5 `f2b082d2911d9f7c7be60c2cf30ee6d5` (6 378 021 octets) devient `0c8eb59f55cb02ad2c4fa1413840b84b`
(6 380 477 octets, 2026-10-13 21:14).
- Seule sauvegarde du journal de l'éditeur : l. 2294, `LogFileHelpers: Saving Package: /Game/BPs/Room`.
- `Content/BPs/GI.uasset` = `e64b5b37c9ef0db7735de0d6e3bd7c1c` et `Content/BPs/Person.uasset` =
`8668a47c627f7a5254910cf0ac33b12a`, comme attendu. Ni l'un ni l'autre n'a été chargé.
- `git status` les marque `M`. C'était déjà le cas au début de la session : modifications des lots précédents, pas de
cette fiche.
- `Docs/Migration/etat/CAM/CAM-B2g-IMPL.md` : ce livrable.
### Appels MCP, dans l'ordre
| # | Appel | Arguments | Retour |
|---|---|---|---|
| 1 | AT.`load_asset` | `{asset_path:"/Game/BPs/Room"}` | `{"refPath":"/Game/BPs/Room.Room"}` |
| 2 | BT.`get_node_infos` | `K2Node_MakeArray_5`, `K2Node_VariableGet_260` | état avant A, conforme (tableau A) |
| 3 | BT.`add_node_pin` | `{node:{refPath:"…K2Node_MakeArray_5"}}` | `{"direction":"EGPD_Input","index_id":2,"node":{"refPath":"…K2Node_MakeArray_5"}}` |
| 4 | BT.`connect_pins` | `{EGPD_Output,0,VariableGet_260}` → `{EGPD_Input,2,MakeArray_5}` | `null` : pas d'erreur, type accepté (Static Mesh Actor vers Acteur) |
| 5 | BT.`get_node_infos` | `MakeArray_5`, `VariableGet_260`, `_261`, `_268` | relecture A, conforme |
| 6 | BT.`get_node_infos` | `CommutativeAssociativeBinaryOperator_19`, `VariableGet_269`, `PromotableOperator_8`, `IfThenElse_96`, `_97` | état avant B ; **écart E1** |
| 7 | BT.`get_node_infos` | `IfThenElse_100`, `_91`, `_98`, `_99` | description de E1 (lecture) |
| 8 | BT.`get_node_infos` | `VariableSet_71`, `_69`, `_70`, `CustomEvent_8` | description de E1 (lecture) |
| 9 | AT.`is_dirty` | `{asset_path:"/Game/BPs/Room"}` | `true`. **Fin du passage 1.** |
| 10 | BT.`find_node_types` | `{graph:{refPath:"/Game/BPs/Room.Room:EventGraph"}, type_id_filter:"ORBoolean", context_pins:[]}` | `["Math|Booléen|XORBoolean","Math|Booléen|ORBoolean","Math|Booléen|NORBoolean"]` |
| 11 | BT.`create_node` | `{graph:{refPath:"…:EventGraph"}, type_id:"Math|Booléen|ORBoolean", pos:{x:5350,y:4600}}` | `{"refPath":"…K2Node_CommutativeAssociativeBinaryOperator_60"}` |
| 12 | BT.`get_node_infos` | `CommutativeAssociativeBinaryOperator_60` | A `{EGPD_Input,0}`, B `{EGPD_Input,1}`, ReturnValue `{EGPD_Output,0}`, tous `false` et libres |
| 13 | BT.`connect_pins` | `{EGPD_Output,0,PromotableOperator_8}` → `{EGPD_Input,0,CABO_60}` (OR.A) | `null` |
| 14 | BT.`connect_pins` | `{EGPD_Output,0,VariableGet_269}` → `{EGPD_Input,1,CABO_60}` (OR.B) | `null` |
| 15 | BT.`connect_pins` | `{EGPD_Output,0,CABO_60}` → `{EGPD_Input,1,IfThenElse_96}` (Condition) | `null` |
| 16 | BT.`connect_pins` | `{EGPD_Output,0,CABO_60}` → `{EGPD_Input,1,IfThenElse_97}` (Condition) | `null` |
| 17 | BT.`get_node_infos` | `CABO_60`, `PromotableOperator_8`, `VariableGet_269`, `IfThenElse_96`, `_97`, `MakeArray_5` | relecture de l'étape 7 corrigée, conforme (tableau B) |
| 18 | AT.`is_dirty` | `{asset_path:"/Game/BPs/Room"}` | `true` |
| 19 | BT.`compile_blueprint` | `{blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true}` | `null` (pas d'exception) |
| 20 | AT.`save_assets` | `{asset_paths:["/Game/BPs/Room"]}` | `true`, confirmé par le journal et le MD5 |
`CABO_60` = `K2Node_CommutativeAssociativeBinaryOperator_60`, le nœud OU créé. Aucun `break_pins`, `delete_node` ni
`set_pin_value`. Aucune écriture par HyperAIStudio.
### Tableau A : B2g, `GI.Wall` dans `MakeArray_5`
| Broche (PinID) | Avant (appel 2) | Après (appels 5 et 17) |
|---|---|---|
| `MakeArray_5` `[0]` `{EGPD_Input,0}` | ← `VariableGet_261` sortie 0 (`PlayerCharacter`) | identique |
| `MakeArray_5` `[1]` `{EGPD_Input,1}` | ← `VariableGet_268` sortie 0 (`CamRoom`) | identique |
| `MakeArray_5` `[2]` `{EGPD_Input,2}` | absente | **← `VariableGet_260` sortie 0 (`Wall`)**, type « Acteur Référence d'objet » |
| `MakeArray_5` `Array` `{EGPD_Output,0}` | → `CallFunction_459`, `_499`, `_505` (entrée 6 = `ActorsToIgnore`) | identique |
| `VariableGet_260` `Wall` `{EGPD_Output,0}` (`|GetWall`, Static Mesh Actor) | → `CallFunction_88` [1], `CallFunction_438` [1] | → 88 [1], 438 [1], **`MakeArray_5` [2]** |
| `VariableGet_260` `self` `{EGPD_Input,0}` | ← `VariableGet_257` (GI) | identique |
Le nœud 260 est réutilisé : aucun nœud créé pour A. Positions : `MakeArray_5` (35500, 2050), `VariableGet_260`
(29900, 2200).
### Tableau B : B2h, OU `CamC1On` sur les conditions de 96 et 97
| Broche (PinID) | Avant (appel 6) | Après (appel 17) |
|---|---|---|
| `CABO_60` (`Math|Booléen|ORBoolean`, (5350, 4600)) | absent | créé |
| `CABO_60` A `{EGPD_Input,0}` | sans objet | ← `PromotableOperator_8` sortie 0 |
| `CABO_60` B `{EGPD_Input,1}` | sans objet | ← `VariableGet_269` sortie 0 (`CamC1On`) |
| `CABO_60` ReturnValue `{EGPD_Output,0}` | sans objet | → `IfThenElse_96` [1], `IfThenElse_97` [1] |
| `PromotableOperator_8` ReturnValue `{EGPD_Output,0}` | → 91, **96**, **97**, 98, 99, 100 (entrée 1 de chacune) | → 91, 98, 99, 100 (entrée 1), **`CABO_60` [0]** ; plus 96 ni 97 |
| `PromotableOperator_8` A / B | ← `CallFunction_439` / ← `VariableGet_268` | identique |
| `VariableGet_269` `CamC1On` `{EGPD_Output,0}` | → `IfThenElse_77`, `_82`, `_84` (entrée 1) | → 77, 82, 84, **`CABO_60` [1]** |
| `IfThenElse_96` Condition `{EGPD_Input,1}` (défaut `true`) | ← `PromotableOperator_8` | **← `CABO_60`** |
| `IfThenElse_96` execute / then / else | ← `CustomEvent_1` / → `CallFunction_516` / → `IfThenElse_26` | identique |
| `IfThenElse_97` Condition `{EGPD_Input,1}` (défaut `true`) | ← `PromotableOperator_8` | **← `CABO_60`** |
| `IfThenElse_97` execute / then / else | ← `CustomEvent_4` / → `CallFunction_518` / → `IfThenElse_9` | identique |
Garde `Accessed None` (lp-mcp § 1 règle 4) : aucun `IsValid` ajouté.
- Le OU est un nœud pur : ses deux entrées sont toujours évaluées.
- Estimé sans risque nouveau :
- `VariableGet_269` lit une variable de Room elle-même (aucune broche `self`, `input_pins` vide), sans cible nulle
possible ;
- `PromotableOperator_8` (`Equal(Object)`) était déjà évalué par ces mêmes branches avant le correctif, et une
comparaison d'objets nuls ne lève pas `Accessed None`.
- Changement voulu par la SPEC (§ 7) : quand `CamC1On` est vrai, 96 et 97 prennent `then` (vers 516 et 518) même si la
vue n'est pas `CamRoom`. En C2, rien ne change. Hors C1 et C2, on passe par `else` comme avant.
### Compilation et sauvegarde (journal `D:\Game\LifePlay_Backup_5.5\CAM-B2g\editeur\editeur-B2g.log`)
- 2286 lignes avant la compilation. Après : `LogBlueprint: Compiling Blueprint '/Game/BPs/Room.Room'`, puis 0 ligne
`error` ou `warning` (insensible à la casse) jusqu'à la fin, sauvegarde et validation comprises.
- `hyper_blueprint_debug_inspect` n'a pas été appelé : il est absent du serveur (repli prévu : `warnings_as_errors` et
le journal).
- Sauvegarde, l. 2294 : `Saving Package: /Game/BPs/Room`, puis `Moving '…/Saved/Room8CBB1E72….tmp' to
'…/Content/BPs/Room.uasset'`, puis `AssetCheck: /Game/BPs/Room Validation de la ressource`. Le journal n'a pas
d'autre ligne `Saving Package`.
## 2. Écarts à la SPEC
- **E1 (passage 1, tranché)** : `PromotableOperator_8.ReturnValue` a 6 consommateurs (91, 96, 97, 98, 99, 100), pas 5.
- `IfThenElse_100` : `CustomEvent_8` (`AddEvent|Custom|DownUp`) → `then` vers `VariableSet_71` (`|SetC2Height`),
`else` vers `IfThenElse_8`.
- Arrêt avant écriture B. L'orchestrateur a choisi l'option 1 : liste amendée, 100 reste sur PO_8, écritures
inchangées.
- Après correctif, PO_8 → 91, 98, 99, 100 et OR.A, conforme à la liste amendée.
- Position du OU : (5350, 4600), à côté de 96 (5650, 4450). La SPEC dit seulement « près de 96 ».
- Pas d'autre écart. GI et Person n'ont pas été ouverts. Ni build, ni commandlet, ni jeu.
## 3. Instantané
- `D:\Game\LifePlay_Backup_5.5\CAM-B2g\manifest.csv` (pris par l'orchestrateur), relu :
`"Content\BPs\Room.uasset","True","6378021","F2B082D2911D9F7C7BE60C2CF30EE6D5","2026-10-13T21:08:59"`.
- MD5 sur le disque avant l'appel 1 = celui du manifeste.
- Retour arrière **proposé, non lancé**, par l'orchestrateur, éditeur fermé :
1. `.\Tools\Snapshot.ps1 -Lot CAM-B2g-retour -Path Content\BPs\Room.uasset` ;
2. `.\Tools\Restore.ps1 -Lot CAM-B2g -WhatIf` ;
3. `.\Tools\Restore.ps1 -Lot CAM-B2g -Only Content\BPs\Room.uasset`.
Contrôle : `md5sum Content/BPs/Room.uasset` = `f2b082d2…`.
## 4. Ce qui n'a pas été fait
- Le nombre de nœuds de Room (SPEC V5 : 1261 attendu) n'a pas été compté.
- Les nœuds 88 et 438 n'ont pas été relus : leurs liens se lisent sur la sortie de 260.
- `CompileAllBlueprints` éditeur fermé, build empaqueté, `LogStats`, essai en jeu : hors fiche (lp-mcp § 1 règles 3 et 5).
- L'éditeur n'est pas fermé (rôle de l'orchestrateur, puis `BUILD-FIN`).
## 5. Points à confirmer en VAL
- Room = `0c8eb59f55cb02ad2c4fa1413840b84b` ; GI = `e64b5b37…` et Person = `8668a47c…` inchangés.
- V5, diff de Room limité à :
- `MakeArray_5` [2] ← `VariableGet_260.Wall` ;
- 1 nœud `CommutativeAssociativeBinaryOperator_60` (`ORBoolean`), avec A ← PO_8 et B ← 269 ;
- conditions de 96 et 97 ← `CABO_60`.
- V5 : Room = 1261 nœuds (non compté ici).
- PO_8 → 91, 98, 99, 100 et `CABO_60` [0], et plus 96 ni 97.
- 269 → 77, 82, 84 et `CABO_60` [1].
- Les then / else de 96 et 97 sont inchangés.
- `CompileAllBlueprints` éditeur fermé : 0 erreur ou avertissement nouveau sur Room.
- En jeu (build empaqueté, COMMUN-4) :
- C1 : souris et flèches gauche/droite tournent la vue (avec la partie D, `Walk` de STG, dans le même build) ;
- C2 : rien ne change ;
- D8 : plus de caméra collée à 26 cm, +26, près de la plaque `Wall`.
## 6. Fichiers à commiter
- M `Content/BPs/Room.uasset` (dépôt du jeu, branche ue5.8).
- A `Docs/Migration/etat/CAM/CAM-B2g-IMPL.md` (dépôt du jeu, branche ue5.8).
- Pas GI ni Person : leur `M` vient de lots antérieurs.
## Mesuré
```
$ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset (avant l'appel 1)
f2b082d2911d9f7c7be60c2cf30ee6d5 *Content/BPs/Room.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
$ wc -l editeur-B2g.log (avant l'appel 19)
2286
$ tail -n +2287 editeur-B2g.log | grep -ciE "error|warning" (après les appels 19 et 20)
0
$ grep -n "Saving Package" editeur-B2g.log
2294:[2026.10.13-19.14.18:546][ 77]LogFileHelpers: Saving Package: /Game/BPs/Room
$ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/Person.uasset (après l'appel 20)
0c8eb59f55cb02ad2c4fa1413840b84b *Content/BPs/Room.uasset
e64b5b37c9ef0db7735de0d6e3bd7c1c *Content/BPs/GI.uasset
8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset
$ ls -l Content/BPs/Room.uasset
-rw-r--r-- 1 <compte> 197609 6380477 Oct 13 21:14 Content/BPs/Room.uasset
```
Tours : 32 / 60
## Constats
- À verser dans lp-mcp § 3 (vérifié aujourd'hui) :
- `add_node_pin {node:{refPath}}` rend le PinID de la nouvelle entrée ;
- `connect_pins` accepte Static Mesh Actor vers une entrée Acteur de `MakeArray` ;
- `connect_pins` vers une entrée déjà reliée remplace l'ancien lien (PO_8 détaché de 96 et 97) ;
- `add_node_pin`, `create_node` et `connect_pins` mettent `is_dirty` à vrai sans la Branche isolée de B2f-a ;
- le `type_id` du OU booléen est `Math|Booléen|ORBoolean`, à trouver par le filtre `ORBoolean` (3 résultats :
XOR, OR, NOR) ;
- `is_dirty` prend `{asset_path}`.
- Pour la rédaction des SPEC MCP : lister **tous** les `connected_pins` d'une sortie partagée, relus juste avant
l'écriture (PO_8 : 6 liens, 5 cités ; amendement E1).
- Le dossier d'instantané `CAM-B2g` contient un sous-dossier `Source` absent du manifeste (une seule ligne, Room). Il
n'a pas été lu : à vérifier par l'orchestrateur (incertain).