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

194 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Fiche CAM-B2b-F3 — 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-F3-IMPL : appel de la boîte, borne de `Desired`, rayon 20 (B2b-2) ; lacet, distance, hauteur (B2b-5) (2026-10-13)
Consignes : `CAM-B2b-FICHES.md` § « Rubriques communes » (l. 23-63) et § « F3 » (l. 88-104) ; SPEC `CAM-SPEC.md`
§ « CAM-B2b », lignes B2b-2 (l. 376) et B2b-5 (l. 379). 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 chargé avec
F1 + F2 en mémoire. Un seul `call_tool` par message ; 51 appels MCP au total (13 `create_node`, 6 `break_pins`,
23 `connect_pins`, 5 `set_pin_value`, 3 `get_node_infos`, 1 `compile_blueprint`). Aucun `delete_node`, `save_assets`,
`write_graph_dsl` ni `ProgrammaticToolset`.
## 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 avant et après F3 = MD5 de l'instantané (§ 3).
- Graphe `/Game/BPs/Room.Room:EventGraph`, zone de `ComputeC2Target` (CE47 en 34000, 1500) ; nœuds neufs en
x 34100-36650, y 1300-2750.
### 1.1 Lecture avant écriture (`get_node_infos` groupé, 10 nœuds existants)
Conforme à la fiche : `CustomEvent_47.then` (out 1) → `CallFunction_459.execute` (in 0) ; `CallFunction_458.0` →
`459.End` (in 2) et → `VariableSet_62.C2Target` (in 1) ; `459.Radius` (in 3) = `12.0` (`Float (simple précision)`) ;
`CallFunction_454.0` → `PromotableOperator_3.A` (in 0) ; `PO3.B` (in 1) = `-175.0,-175.0,-175.0`, **sans lien**
(constante) ; `PO5.0` → `458.Z` (in 2), `PO5.B` = `60.0` ; `PO6.B` (in 1) = `12.0,12.0,12.0` ; `PO7.0` →
`VariableSet_61.C2Target` (in 1).
### 1.2 Nœuds créés (préfixe `refPath` : `/Game/BPs/Room.Room:EventGraph.`)
| Rôle | `refPath` (suffixe) | `type_id` demandé → relu | Broches relues | Position |
|---|---|---|---|---|
| Appel `ComputeRoomBox` | `K2Node_CallFunction_494` | `Appelerunefonction\|ComputeRoomBox` → `\|ComputeRoomBox` | execute 0, self 1 (vide = Room) ; then 0 | 34350, 1300 |
| Obtenir `C2BoxMin` | `K2Node_VariableGet_286` | `Variables\|Pardéfaut\|ObtenirC2BoxMin` → `\|GetC2BoxMin` | out 0 `Vector` | 35100, 2400 |
| Obtenir `C2BoxMax` | `K2Node_VariableGet_287` | `Variables\|Pardéfaut\|ObtenirC2BoxMax` → `\|GetC2BoxMax` | out 0 `Vector` | 35100, 2500 |
| **`DesiredB`** = borne de `Desired` | `K2Node_CallFunction_495` | `Math\|Vecteur\|VectorBoundedtoBox` → `Math\|Vecteur\|Vector_BoundedToBox` | InVect 0, InBoxMin 1, InBoxMax 2 ; out 0 | 35550, 2300 |
| Borne de PO7 (→ 61) | `K2Node_CallFunction_496` | idem → `Math\|Vecteur\|Vector_BoundedToBox` | idem | 36650, 2300 |
| `Normalize2D × (−1)` | `K2Node_PromotableOperator_17` | `Utilitaires\|Opérateurs\|Multiplier` → `Math\|Vecteur\|vector*vector` (après liaison A) | A 0, B 1 ; out 0 | 34450, 2300 |
| **`Bdir`** = rotation de lacet | `K2Node_CallFunction_497` | `Math\|Vecteur\|RotateVectorAroundAxis` → idem | InVect 0, AngleDeg 1 (`Float (simple précision)`), Axis 2 ; out 0 | 34700, 2450 |
| Obtenir `C2Yaw` | `K2Node_VariableGet_288` | `Variables\|Pardéfaut\|ObtenirC2Yaw` → `\|GetC2Yaw` | out 0 `Float (double-précision)` | 34400, 2550 |
| Obtenir `C2Dist` | `K2Node_VariableGet_289` | `Variables\|Pardéfaut\|ObtenirC2Dist` → `\|GetC2Dist` | out 0 `Float (double-précision)` | 34100, 2750 |
| **`d`** = `C2Dist + 175` | `K2Node_PromotableOperator_18` | `Utilitaires\|Opérateurs\|Ajouter` → `Math\|Flottant\|float+float` (après liaison A) | A 0, B 1 ; out 0 | 34300, 2750 |
| **`MakeVector(d, d, d)`** | `K2Node_CallFunction_498` | `Math\|Vecteur\|MakeVector` → idem | X 0, Y 1, Z 2 ; out 0 | 34500, 2750 |
| **Hauteur** = `PO5 + C2Height` | `K2Node_PromotableOperator_19` | `Utilitaires\|Opérateurs\|Ajouter` → `Math\|Flottant\|float+float` (après liaison A) | A 0, B 1 ; out 0 | 35200, 2150 |
| Obtenir `C2Height` | `K2Node_VariableGet_290` | `Variables\|Pardéfaut\|ObtenirC2Height` → `\|GetC2Height` | out 0 `Float (double-précision)` | 34950, 2250 |
Les trois opérateurs avaient à la création un `type_id` trompeur (`Utilitaires|Gestiondutemps|Seconds*FrameRate`,
`…|FrameNumber+Int`) et des broches `Caractère de remplacement` ; relus typés à la relecture finale.
### 1.3 Liens coupés (`break_pins`, 6, tous `{"returnValue":null}`)
| # | Sortie | Entrée | Point de la fiche |
|---|---|---|---|
| C1 | CustomEvent_47.then 1 | CallFunction_459.execute 0 | 1 |
| C2 | CallFunction_458.0 (`Desired`) | CallFunction_459.End 2 | 2 |
| C3 | CallFunction_458.0 | VariableSet_62.C2Target 1 | 2 |
| C4 | PromotableOperator_7.0 | VariableSet_61.C2Target 1 | 4 |
| C5 | CallFunction_454.0 (`Normalize2D`) | PromotableOperator_3.A 0 | 5 |
| C6 | PromotableOperator_5.0 | CallFunction_458.Z 2 | 5 (hauteur) |
### 1.4 Liens faits (`connect_pins`, 23, tous `{"returnValue":null}`)
| # | Sortie | Entrée |
|---|---|---|
| L1 | CustomEvent_47.then 1 | CallFunction_494.execute 0 |
| L2 | CallFunction_494.then 0 | CallFunction_459.execute 0 |
| L3 | CallFunction_458.0 | CallFunction_495.InVect 0 |
| L4 | VariableGet_286.0 | CallFunction_495.InBoxMin 1 |
| L5 | VariableGet_287.0 | CallFunction_495.InBoxMax 2 |
| L6 | CallFunction_495.0 | CallFunction_459.End 2 |
| L7 | CallFunction_495.0 | VariableSet_62.C2Target 1 |
| L8 | PromotableOperator_7.0 | CallFunction_496.InVect 0 |
| L9 | VariableGet_286.0 | CallFunction_496.InBoxMin 1 |
| L10 | VariableGet_287.0 | CallFunction_496.InBoxMax 2 |
| L11 | CallFunction_496.0 | VariableSet_61.C2Target 1 |
| L12 | CallFunction_454.0 | PromotableOperator_17.A 0 |
| L13 | PromotableOperator_17.0 | CallFunction_497.InVect 0 |
| L14 | VariableGet_288.0 (`C2Yaw`) | CallFunction_497.AngleDeg 1 |
| L15 | CallFunction_497.0 (`Bdir`) | PromotableOperator_3.A 0 |
| L16 | VariableGet_289.0 (`C2Dist`) | PromotableOperator_18.A 0 |
| L17 | PromotableOperator_18.0 | CallFunction_498.X 0 |
| L18 | PromotableOperator_18.0 | CallFunction_498.Y 1 |
| L19 | PromotableOperator_18.0 | CallFunction_498.Z 2 |
| L20 | CallFunction_498.0 | PromotableOperator_3.B 1 (constante −175 remplacée ; relue `""` après liaison) |
| L21 | PromotableOperator_5.0 | PromotableOperator_19.A 0 |
| L22 | VariableGet_290.0 (`C2Height`) | PromotableOperator_19.B 1 |
| L23 | PromotableOperator_19.0 | CallFunction_458.Z 2 |
### 1.5 Valeurs (`set_pin_value`, 5, toutes `{"returnValue":null}`, relues)
| Broche | Avant | Après (relu) |
|---|---|---|
| CallFunction_459.Radius 3 | `12.0` | `20.0` |
| PromotableOperator_6.B 1 | `12.0,12.0,12.0` | `20.0,20.0,20.0` |
| PromotableOperator_17.B 1 | (neuf) | `-1.0,-1.0,-1.0` |
| CallFunction_497.Axis 2 | (neuf, `0, 0, 0`) | `0.0,0.0,1.0` |
| PromotableOperator_18.B 1 | (neuf) | `175.0` |
### 1.6 Relecture et chaîne obtenue
`get_node_infos` final groupé sur les 23 nœuds touchés (13 créés + CE47, 454, 458, 459, PO3, PO5, PO6, PO7, 61, 62) :
les 6 coupures sont absentes des deux côtés (454.0 ne sort plus que vers PO17 ; 458.0 ne sort plus que vers 495 ;
PO7.0 ne sort plus que vers 496 ; PO5.0 ne sort plus que vers PO19 ; CE47.then ne sort plus que vers 494) ; les
23 liens apparaissent des deux côtés ; les 5 valeurs relues ; types : vecteurs `Vector`, `d`, hauteur et composantes
`Float (double-précision)`, `AngleDeg` et `Radius` `Float (simple précision)`. Liens non touchés relus intacts :
459.Start ← 455, 459.ActorsToIgnore ← MakeArray_5, 459.then / ReturnValue → IfThenElse_90, 459.OutHit → 460,
458.X / Y ← 456, PO5.A ← 457.Z, PO3.0 → PO4.B, PO6.A ← 460.Normal, PO7.A ← 460.Location, 61 / 62.execute ← IfThenElse_90.
Aucune divergence.
Chaîne : `ComputeC2Target` → `ComputeRoomBox` (C2BoxMin, C2BoxMax) → `SphereTraceByChannel(tête → Bound(Desired),
r 20)` ; `Desired = MakeVector(456.X, 456.Y, tête.Z + 60 + C2Height)`, avec en amont
`PO3 = RotateVectorAroundAxis(Normalize2D(Fwd) × −1, C2Yaw, (0,0,1)) × (C2Dist + 175)` ; touché →
`C2Target := Bound(Location + Normal × 20)` ; libre → `C2Target := Bound(Desired)`.
### 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` 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
- **E3 (SPEC incohérente, fiche suivie)** : la colonne « valeurs » de B2b-5 (`CAM-SPEC.md:379`) dit « à C2Yaw = 0,
C2Height = 0, **C2Dist = 175** : identique à B2 », alors que B2b-0 (`CAM-SPEC.md:374`) fixe `C2Dist` = 0 (décalage,
distance = 175 + `C2Dist`) et que la fiche F3 (`CAM-B2b-FICHES.md:100-104`) prescrit `d = C2Dist + 175` et le
contrôle à `C2Dist = 0`. Appliqué : `d = C2Dist + 175` (PO18). À `C2Dist = 175`, la distance serait 350. Le texte de
la colonne B2b-5 est à corriger par l'orchestrateur (point 7).
- `Bdir × (175 + C2Dist)` (SPEC, scalaire) est réalisé par `vector*vector` avec `MakeVector(d, d, d)` (fiche) :
équivalent composante par composante.
- `AngleDeg` (simple précision) est alimenté par `C2Yaw` (double précision) : conversion implicite du moteur, la
compilation stricte l'accepte.
- Garde `Accessed None` : aucune `IsValid` ajoutée (aucune demandée). Les nœuds neufs ne lisent aucune référence
d'objet (vecteurs, flottants, appel d'événement sur `self`). En revanche, `ComputeRoomBox` (F1-F2 : lectures de
`StaticMeshComponent`, `Wall2`, `Wall4`, `WallT`) s'exécute désormais à chaque `ComputeC2Target` (point 3).
- Lecture intermédiaire des opérateurs après typage non faite (économie de tours) : `set_pin_value` posé juste après
la liaison A, typage et valeurs confirmés à la relecture finale (§ 1.6).
- Positions des nœuds : choisies hors des nœuds existants (cosmétique, non prescrites).
- Aucun autre écart : points 1 à 5 de la fiche faits dans l'ordre, aucun nœud hors fiche touché.
## 3. Instantané
Fait par l'orchestrateur avant F1 (non refait, consigne) : `D:\Game\LifePlay_Backup_5.5\CAM-B2b\manifest.csv`,
Room `A5FA970E…` (ligne citée par `CAM-B2b-IMPL-F2.md` § 3, non relue ici). Disque mesuré :
```
md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"
a5fa970e821dc2d0d9bf220fd43b9de6 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset (2026-10-13T15:41:43+02:00, avant F3)
a5fa970e821dc2d0d9bf220fd43b9de6 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset (2026-10-13T15:45:08+02:00, après F3)
```
= instantané : rien d'enregistré. Retour arrière avant F7 : fermer l'éditeur sans enregistrer (perd F1 à F3) ; 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
- F4 et suivantes (poursuite protégée, repli, pilotage) : hors périmètre. `Bdir` = `K2Node_CallFunction_497` pour F5.
- `hyper_blueprint_debug_inspect`, journal de l'éditeur : non consultés (§ 1.7).
- `save_assets` : interdit avant F7 ; F1 à F3 vivent en mémoire de l'éditeur PID 10708 (une fermeture ou un plantage
avant F7 les perd ; l'instantané reste intact).
- Contrôle du point 6 de la fiche (`Desired` = valeur de B2 aux trois variables nulles) : non mesuré à l'exécution,
seulement déduit du câblage (point 1).
- Preuve en jeu (build empaqueté + `LogStats`) : hors rôle.
## 5. Points à confirmer en VAL
1. Point 6 de la fiche, estimé par le câblage : à `C2Yaw = 0`, `RotateVectorAroundAxis` rend son entrée, donc
`PO3 = −Normalize2D × (175,175,175) = Normalize2D × (−175,−175,−175)` (= B2) ; à `C2Height = 0`, `458.Z = PO5`
(= B2) ; `458.X / Y` inchangés (← 456). À mesurer (dump ou trace d'exécution).
2. Changement voulu : `Desired` borné par la boîte avant la trace (459.End) et avant `C2Target` (62) ; le cas touché
(61) borné aussi. À confirmer en jeu : C2 jamais hors de la pièce.
3. `ComputeRoomBox` appelé à chaque `ComputeC2Target` (fréquence d'appel de CE47 non relue ici) : aucun
`Accessed None` sur `StaticMeshComponent`, `Wall2`, `Wall4`, `WallT` dans `LogStats`.
4. Conversion double → simple de `C2Yaw` vers `AngleDeg` : sans perte utile pour un angle en degrés ; à revoir si la
compilation de `CompileAllBlueprints` (éditeur fermé) l'avertit.
5. Valeurs sérialisées après `save_assets` (F7) : `459.Radius = 20`, `PO6.B = (20,20,20)`, `PO17.B = (−1,−1,−1)`,
`497.Axis = (0,0,1)`, `PO18.B = 175`, `PO3.B` lié (plus de constante −175), par dump (`LPDumpFunction`).
6. Compilation stricte jugée sur l'absence d'exception seulement ; recontrôle en F7 et par `CompileAllBlueprints`.
7. E3 : corriger la colonne B2b-5 de `CAM-SPEC.md:379` (« C2Dist = 175 » → « C2Dist = 0 ») ; les bornes de B2b-6
(`C2Dist ∈ [−75, 125]`, distance 100 à 300) sont cohérentes avec `d = C2Dist + 175`.
## 6. Fichiers à commiter
- `A Docs/Migration/etat/CAM/CAM-B2b-IMPL-F3.md` (dépôt du jeu, branche `ue5.8`).
- `Content/BPs/Room.uasset` : rien à commiter pour F3 (non enregistré) ; il le sera après F7 et la VAL.
Tours : 57 / 60
## Constats
- `Appelerunefonction|ComputeRoomBox` crée `|ComputeRoomBox` : execute 0, self 1, then 0 (self vide = Room).
- `Math|Vecteur|VectorBoundedtoBox` se relit `Math|Vecteur|Vector_BoundedToBox` : InVect 0, InBoxMin 1, InBoxMax 2, out 0.
- `Math|Vecteur|RotateVectorAroundAxis` : InVect 0, AngleDeg 1 (simple précision, accepte un getter double), Axis 2.
- `Utilitaires|Opérateurs|Multiplier` apparaît `Utilitaires|Gestiondutemps|Seconds*FrameRate` à la création ; relié en A
à un vecteur, il devient `vector*vector` et accepte aussitôt `set_pin_value` B = "x,y,z".
- Lier une entrée constante (PO3.B) efface sa valeur (relue `""`) : vérifier l'absence de lien avant, comme demandé.
- Économie : créer tous les nœuds, une lecture groupée (13 nœuds), câbler et poser les valeurs, une relecture finale
(23 nœuds) : 51 appels pour 13 nœuds, 6 coupures, 23 liens, 5 valeurs.