LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2b-IMPL-F2.md

166 lines
12 KiB
Markdown
Raw Normal View History

Fiche CAM-B2b-F2 — 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-F2-IMPL : `ComputeRoomBox`, partie Z, extérieur et affectations (2026-10-13)
Consignes : `CAM-B2b-FICHES.md` § « Rubriques communes » (l. 23-63) et § « F2 » (l. 80-86) ; SPEC `CAM-SPEC.md`
§ « CAM-B2b », ligne B2b-1 (l. 375). UE-GO / BUILD-GO de Big Boss du 2026-10-13 (cité par l'orchestrateur). Éditeur
headless PID 10708, port 8000, connexion `unreal-mcp` partagée (MCPA-T1) ; Room déjà chargé avec F1 en mémoire.
Un seul `call_tool` par message ; 48 appels MCP au total (2 `find_node_types`, 16 `create_node`, 22 `connect_pins`,
4 `set_pin_value`, 3 `get_node_infos`, 1 `compile_blueprint`). Aucun `break_pins`, `delete_node`, `save_assets`.
## 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 : MD5 disque après F2 = MD5 de l'instantané (§ 3).
- Graphe `/Game/BPs/Room.Room:EventGraph`, positions x 38000-41800, y 0-1000.
### 1.1 Identifiants trouvés
- `find_node_types {filter:"SelectFloat"}` → `["Math|Flottant|SelectFloat"]`.
- `find_node_types {filter:"WallT"}` → `["Variables|Pardéfaut|ObtenirWallT","Variables|Pardéfaut|DéfinirWallT",
"Variables|Pardéfaut|ObtenirWallTransforms","Variables|Pardéfaut|DéfinirWallTransforms"]`.
- Setters : `Variables|Pardéfaut|DéfinirC2BoxMin` / `DéfinirC2BoxMax` acceptés tels quels (relus `|SetC2BoxMin` /
`|SetC2BoxMax`, broche valeur de type `Vector` : confirme le type des deux variables, point 2 de F1 pour ces deux-là).
### 1.2 Nœuds créés (préfixe `refPath` : `/Game/BPs/Room.Room:EventGraph.`)
| Rôle | `refPath` (suffixe) | `type_id` relu | Position |
|---|---|---|---|
| `BreakVector(Min0)` | `K2Node_CallFunction_484` | `Math\|Vecteur\|BreakVector` | 40300, 200 |
| `BreakVector(Max0)` | `K2Node_CallFunction_485` | `Math\|Vecteur\|BreakVector` | 40300, 400 |
| `BreakVector(sol)` | `K2Node_CallFunction_486` | `Math\|Vecteur\|BreakVector` | 40300, 700 |
| Getter `WallT` | `K2Node_VariableGet_285` | `\|GetWallT` (sortie `Static Mesh Component Référence d'objet`) | 38000, 850 |
| `GetWorldLocation(WallT)` | `K2Node_CallFunction_487` | `Transformation\|GetWorldLocation` | 38300, 850 |
| `BreakVector(WallT)` | `K2Node_CallFunction_488` | `Math\|Vecteur\|BreakVector` | 40300, 850 |
| **ZMin** = `sol.Z + 50` | `K2Node_PromotableOperator_14` | `Math\|Flottant\|float+float` (créé par `Utilitaires\|Opérateurs\|Ajouter`) | 40600, 700 |
| **ZTopIn** = `WallT.Z − 25` | `K2Node_PromotableOperator_15` | `Math\|Flottant\|float-float` (créé par `Utilitaires\|Opérateurs\|Soustraire`) | 40600, 850 |
| `GetWorldScale(StaticMeshComponent)` | `K2Node_CallFunction_489` | `Transformation\|GetWorldScale` | 38300, 1000 |
| `BreakVector(échelle)` | `K2Node_CallFunction_490` | `Math\|Vecteur\|BreakVector` | 40300, 1000 |
| **Ext** = `échelle.Z < 0.05` | `K2Node_PromotableOperator_16` | `Math\|Flottant\|float<float` (créé par `Utilitaires\|Opérateurs\|Inférieurà(<)`) | 40600, 1000 |
| **ZTop** = `SelectFloat(1000000, ZTopIn, Ext)` | `K2Node_CallFunction_491` | `Math\|Flottant\|SelectFloat` (A 0, B 1, bPickA 2) | 40900, 900 |
| `MakeVector(Min0.X, Min0.Y, ZMin)` | `K2Node_CallFunction_492` | `Math\|Vecteur\|MakeVector` | 41200, 200 |
| `MakeVector(Max0.X, Max0.Y, ZTop)` | `K2Node_CallFunction_493` | `Math\|Vecteur\|MakeVector` | 41200, 450 |
| **Définir C2BoxMin** | `K2Node_VariableSet_64` | `\|SetC2BoxMin` (execute 0, valeur 1 ; then 0) | 41500, 0 |
| **Définir C2BoxMax** | `K2Node_VariableSet_65` | `\|SetC2BoxMax` (execute 0, valeur 1 ; then 0) | 41800, 0 |
Les trois opérateurs étaient génériques à la création (`Caractère de remplacement`) ; relus typés après la première
liaison (A), avant `set_pin_value` (lecture intermédiaire groupée).
### 1.3 Liens faits (`connect_pins`, 22, tous `{"returnValue":null}`)
| # | Sortie (nœud.broche index) | Entrée (nœud.broche index) |
|---|---|---|
| L1 | PromotableOperator_12.0 (Min0) | CallFunction_484.InVec 0 |
| L2 | PromotableOperator_13.0 (Max0) | CallFunction_485.InVec 0 |
| L3 | CallFunction_240.0 (sol) | CallFunction_486.InVec 0 |
| L4 | VariableGet_285.0 (WallT) | CallFunction_487.self 0 |
| L5 | CallFunction_487.0 | CallFunction_488.InVec 0 |
| L6 | CallFunction_486.Z 2 | PromotableOperator_14.A 0 |
| L7 | CallFunction_488.Z 2 | PromotableOperator_15.A 0 |
| L8 | VariableGet_282.0 (StaticMeshComponent, réutilisé) | CallFunction_489.self 0 |
| L9 | CallFunction_489.0 | CallFunction_490.InVec 0 |
| L10 | CallFunction_490.Z 2 | PromotableOperator_16.A 0 |
| L11 | PromotableOperator_16.0 | CallFunction_491.bPickA 2 |
| L12 | PromotableOperator_15.0 | CallFunction_491.B 1 |
| L13 | CallFunction_484.X 0 | CallFunction_492.X 0 |
| L14 | CallFunction_484.Y 1 | CallFunction_492.Y 1 |
| L15 | PromotableOperator_14.0 | CallFunction_492.Z 2 |
| L16 | CallFunction_485.X 0 | CallFunction_493.X 0 |
| L17 | CallFunction_485.Y 1 | CallFunction_493.Y 1 |
| L18 | CallFunction_491.0 | CallFunction_493.Z 2 |
| L19 | CallFunction_492.0 | VariableSet_64.C2BoxMin 1 |
| L20 | CallFunction_493.0 | VariableSet_65.C2BoxMax 1 |
| L21 | CustomEvent_49.then 1 | VariableSet_64.execute 0 |
| L22 | VariableSet_64.then 0 | VariableSet_65.execute 0 |
Valeurs (`set_pin_value`, toutes `{"returnValue":null}`, relues) : PromotableOperator_14.B 1 = `50.0` ;
PromotableOperator_15.B 1 = `25.0` ; PromotableOperator_16.B 1 = `0.05` ; CallFunction_491.A 0 = `1000000.0`.
Non reliés, comme prévu : `VariableSet_65.then` (fin de `ComputeRoomBox`), sorties `Output_Get` des deux setters,
Z de `BreakVector(Min0)` / `(Max0)`, X / Y des `BreakVector` de sol, de WallT et de l'échelle.
### 1.4 Relecture
`get_node_infos` final groupé sur les 16 nœuds créés et `CustomEvent_49` : les 22 liens apparaissent des deux côtés
pour les nœuds relus (L1, L2, L3, L8 côté entrée seulement, les nœuds source de F1 n'étant pas relus) ; les quatre
valeurs relues (`50.0`, `25.0`, `0.05`, `1000000.0`) ; types : vecteurs `Vector`, composantes et opérandes
`Float (double-précision)`, `Ext` et `bPickA` `Booléen`. Index de broches relus avant câblage (lecture groupée de
11 nœuds après les créations) : conformes à la fiche (`BreakVector` X 0 / Y 1 / Z 2, `MakeVector` X 0 / Y 1 / Z 2,
`VariableSet` exécution 0 / valeur 1 / then 0, `CustomEvent_49` then 1, `SelectFloat` A 0 / B 1 / bPickA 2).
Aucune divergence.
Chaîne obtenue : `ComputeRoomBox` → `C2BoxMin := (Min0.X, Min0.Y, sol.Z + 50)` → `C2BoxMax := (Max0.X, Max0.Y,
SelectFloat(1000000, WallT.Z − 25, échelleMonde(StaticMeshComponent).Z < 0.05))`.
### 1.5 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` non appelé (absent
du serveur le 2026-10-10, mémoire `unreal-mcp-reconnect` ; non revérifié) ; journal de l'éditeur non lu (chemin
`-abslog` non fourni). Pas de `save_assets` (F7).
## 2. Écarts à la SPEC
- **E2 (fiche ≠ SPEC, fiche suivie)** : la SPEC B2b-1 (`CAM-SPEC.md:375`) teste
`StaticMeshComponent.RelativeScale3D.Z < 0,05` ; la fiche F2 § 3 (`CAM-B2b-FICHES.md:83`) prescrit
`GetWorldScale(StaticMeshComponent)`, appliqué ici. Estimé : identique tant que `StaticMeshComponent` est la racine
de Room et que Room n'est attachée à aucun parent mis à l'échelle (échelle monde = échelle relative). Si Room était
attachée, le seuil porterait sur l'échelle composée. À trancher en VAL (point 1).
- Garde `Accessed None` : aucune `IsValid` ajoutée (aucune demandée). `SelectFloat` est pur : `WallT.GetWorldLocation`
est évalué aussi en extérieur (`lp-mcp` § 1 règle 4). Estimé sans risque : `WallT` existe en extérieur (mis à
l'échelle et masqué par le C++, `CAM-B2b-AMENDEMENT.md:19`, `CAM-SPEC.md:456` citant
`LPOutdoorRoomSubsystem.cpp:55-60`) ; non vérifié en jeu (point 2).
- E1 de F1 (`Vector_ComponentMax`, CallFunction_483) reste en place : F2 consomme Min0 / Max0 tels quels.
- Aucun autre écart : BreakVector ×4, WallT, ZMin (+50), ZTopIn (−25), seuil 0.05, SelectFloat (1000000, ZTopIn),
MakeVector ×2, deux setters, exécution `then` → C2BoxMin → C2BoxMax, conformes ; aucun nœud existant modifié hors
ajout de liens sortants sur PO12, PO13, CallFunction_240, VariableGet_282 et de la sortie `then` de CE49 (libres).
## 3. Instantané
Fait par l'orchestrateur avant F1 (non refait, consigne) : `D:\Game\LifePlay_Backup_5.5\CAM-B2b\manifest.csv`,
ligne 2 relue : `"Content\BPs\Room.uasset","True","6060745","A5FA970E821DC2D0D9BF220FD43B9DE6","2026-10-13T15:25:45"`.
Disque avant et après F2 : `md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"` →
`a5fa970e821dc2d0d9bf220fd43b9de6` (= instantané : rien d'enregistré). Retour arrière avant F7 : fermer l'éditeur
sans enregistrer (perd F1 et F2) ; 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
- F3 et suivantes (appel de `ComputeRoomBox` depuis CE47, bornes, lacet, repli, poursuite, pilotage) : hors périmètre.
- `hyper_blueprint_debug_inspect`, journal de l'éditeur : non consultés (§ 1.5).
- `save_assets` : interdit avant F7. F1 + F2 vivent en mémoire de l'éditeur PID 10708 : une fermeture ou un plantage
avant F7 les perd (l'instantané reste intact).
- Valeurs effectives de `C2BoxMin` / `C2BoxMax` à l'exécution : non mesurées (aucun appel de l'événement avant F3).
- Preuve en jeu (build empaqueté + `LogStats`) : hors rôle.
## 5. Points à confirmer en VAL
1. E2 : `GetWorldScale` (fiche) au lieu de `RelativeScale3D` (SPEC) pour le seuil extérieur 0.05 : Room jamais
attachée à un parent mis à l'échelle ? (sinon remplacer par `GetRelativeScale3D`, décision de l'orchestrateur).
2. `WallT` toujours valide (intérieur et extérieur) : `SelectFloat` évalue `WallT.GetWorldLocation` dans les deux cas ;
à vérifier par `LogStats` (aucun `Accessed None` sur `ComputeRoomBox`).
3. Extérieur : `ZTop = 1000000` (pas de borne haute utile) ; intérieur : `ZTop = WallT.Z − 25`, `ZMin = sol.Z + 50`.
Si `WallT.Z − 25 < sol.Z + 50` (pièce très basse), `C2BoxMin.Z > C2BoxMax.Z` : comportement de
`VectorBoundedToBox` à bornes croisées non vérifié (aucune garde prévue par la SPEC).
4. Valeurs sérialisées (`50`, `25`, `0.05`, `1000000`) à confirmer après `save_assets` (F7) par dump
(`LPDumpFunction`).
5. Compilation stricte jugée sur l'absence d'exception seulement ; recontrôle en F7 et par `CompileAllBlueprints`
éditeur fermé.
## 6. Fichiers à commiter
- `A Docs/Migration/etat/CAM/CAM-B2b-IMPL-F2.md` (dépôt du jeu, branche `ue5.8`).
- `Content/BPs/Room.uasset` : rien à commiter pour F2 (non enregistré) ; il le sera après F7 et la VAL.
Tours : 54 / 60
## Constats
- `find_node_types "SelectFloat"` → `Math|Flottant|SelectFloat` ; getter `WallT` = `Variables|Pardéfaut|ObtenirWallT`.
- Setters de variables neuves : `Variables|Pardéfaut|Définir<Var>` marche directement (`|Set<Var>` relu).
- Les opérateurs `Utilitaires|Opérateurs|*` apparaissent à la création avec un `type_id` trompeur
(`Utilitaires|Gestiondutemps|FrameNumber+Int`, `Math|Durée|Timespan<Timespan`) et des broches
`Caractère de remplacement` ; ils se typent correctement à la première liaison (`float+float`, `float-float`,
`float<float`). Ne pas en conclure à une erreur de création.
- Grouper la relecture : créer tous les nœuds, puis un seul `get_node_infos` (11 nœuds) avant câblage, une lecture
des opérateurs après typage, une relecture finale (17 nœuds) : 48 appels pour 16 nœuds et 22 liens.