Fiche CAM-B2p-R — 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-B2p-R-IMPL : vue de scène pendant le sexe (S1, S2, 303 → 441) et flèches = couple sans Maj (O1) (Room, 2026-10-14) Résultat : **réussi**, en un passage, dans l'éditeur headless déjà lancé par l'orchestrateur (pid 22448, port 8000). - État lu conforme au tableau « État attendu » de la fiche (12 nœuds), plus 11 nœuds témoins relevés avant écriture. - 3 nœuds créés, 13 liens posés (L1 à L13), aucun `break_pins`, `delete_node` ni `set_pin_value`. - Relecture conforme à l'étape 5, témoins identiques. `is_dirty` = vrai. Compilation stricte sans diagnostic. - `save_assets` de Room seul. Room passe de `c5ab7241…` à `931387479e2d15f80bc4f36398907712`. - GI, PC et Person sont inchangés et n'ont pas été chargés. Spécification : `Docs/Migration/etat/CAM/CAM-B2p-R-FICHE.md` (étapes 1 à 6), SPEC `CAM-B2p-SPEC.md` P1 et P2. Préfixe des nœuds : `/Game/BPs/Room.Room:EventGraph.`. Un seul appel MCP par message, lectures comprises. Outils : `editor_toolset.toolsets.asset.AssetTools` (AT) et `editor_toolset.toolsets.blueprint.BlueprintTools` (BT). Abréviations : `77`, `78`, `79`, `80`, `81`, `91`, `92`, `14`, `17` = `K2Node_IfThenElse_n` ; `43`, `45` = `K2Node_CustomEvent_n` ; `394`, `303`, `441`, `440`, `329`, `539` à `542` = `K2Node_CallFunction_n` ; `258`, `62`, `85` = `K2Node_VariableGet_n`. PinID au format `{direction, index_id}` du nœud nommé. Nœuds créés : | Rôle | `refPath` (suffixe) | `type_id` relu | Position | |---|---|---|---| | **S1** (Branche, P1, sur `ApplyRoomCamera`) | `K2Node_IfThenElse_102` | `Utilitaires|ContrôleDeFlux|Branche` | (30100, 1300) | | **S2** (Branche, P1, sur `UpdateRoomCam`) | `K2Node_IfThenElse_103` | `Utilitaires|ContrôleDeFlux|Branche` | (30000, 4300) | | **O1** (OU, P2) | `K2Node_CommutativeAssociativeBinaryOperator_63` | `Math|Booléen|ORBoolean` | (5824, 3408) | Broches relevées à l'appel 10 : S1 et S2 execute `{EGPD_Input,0}`, Condition `{EGPD_Input,1}` (défaut `true`), then `{EGPD_Output,0}`, else `{EGPD_Output,1}` ; O1 A `{EGPD_Input,0}`, B `{EGPD_Input,1}` (défauts `false`), ReturnValue `{EGPD_Output,0}`. ## 1. Fichiers modifiés - `Content/BPs/Room.uasset` : 3 nœuds ajoutés, 13 liens posés. 4 de ces liens en remplacent un : 43.then → 77, 45.then → 91, 62 → 14.Condition et 62 → 17.Condition. - Avant : MD5 `c5ab724101fa898457293d64059d21a9`, celui du manifeste de l'instantané. Relu à 10:04:51, puis à 10:05:57, juste avant la première écriture. - Après : `931387479e2d15f80bc4f36398907712` (6 428 769 octets, 2026-10-14 10:07:40 heure locale). - Journal de l'éditeur `D:\Game\LifePlay-master 5.8\Saved\Logs\portage\CAM-B2p-R-editeur_20261014-100330.log`, l. 2340 : `LogFileHelpers: Saving Package: /Game/BPs/Room`. C'est la seule ligne `Saving Package` du journal. - `Content/BPs/GI.uasset` `bd0a2256b875a3ac875630e4b85d92d7`, `Content/BPs/PC.uasset` `f45be57a39d13d3eb19d0b543153ab0b`, `Content/BPs/Person.uasset` `8668a47c627f7a5254910cf0ac33b12a` : identiques avant et après. Aucun des trois n'a été chargé (30 appels, tous listés au § 1.1). - `Docs/Migration/etat/CAM/CAM-B2p-R-IMPL.md` : ce livrable. ### 1.1 Appels MCP, dans l'ordre (30, un par message) | # | Appel | Arguments | Retour | |---|---|---|---| | 1 | AT.`load_asset` | `{asset_path:"/Game/BPs/Room"}` | `{"refPath":"/Game/BPs/Room.Room"}` | | 2 | BT.`get_node_infos` | 43, 77, 45, 91, 258, 394 | état avant (§ 1.2) | | 3 | BT.`get_node_infos` | 303, 441, 14, 17, 62, 85 | état avant (§ 1.2) | | 4 | BT.`get_node_infos` | témoins 78, 79, 80, 81, 92, 329, 440, 539, 540, 541, 542 | état avant (§ 1.4) | | 5 | 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"]` | | 6 | BT.`find_node_types` | même graphe, `type_id_filter:"ContrôleDeFlux|Branche"` | `["Utilitaires|ContrôleDeFlux|Branche"]` | | — | (shell) `md5sum Content/BPs/Room.uasset` | 10:05:57 | `c5ab7241…` = instantané : écriture permise | | 7 | BT.`create_node` S1 | `{graph:{refPath:"…Room.Room:EventGraph"}, type_id:"Utilitaires|ContrôleDeFlux|Branche", pos:{x:30100,y:1300}}` | `K2Node_IfThenElse_102` | | 8 | BT.`create_node` S2 | même type, `pos:{x:30000,y:4300}` | `K2Node_IfThenElse_103` | | 9 | BT.`create_node` O1 | `type_id:"Math|Booléen|ORBoolean"`, `pos:{x:5824,y:3408}` | `K2Node_CommutativeAssociativeBinaryOperator_63` | | 10 | BT.`get_node_infos` | 102, 103, 63 | types et broches conformes, aucun lien | | 11 | BT.`connect_pins` L1 | `43 {EGPD_Output,1}` (then) → `102 {EGPD_Input,0}` (execute) | `null` | | 12 | BT.`get_node_infos` | 43, 77 | 43.then → 102 seul (lien vers 77 remplacé) ; 77.execute **vide** | | 13 | BT.`connect_pins` L2 | `258 {EGPD_Output,0}` (SexOn) → `102 {EGPD_Input,1}` (Condition) | `null` | | 14 | BT.`connect_pins` L3 | `102 {EGPD_Output,0}` (then) → `394 {EGPD_Input,0}` (execute) | `null` | | 15 | BT.`connect_pins` L4 | `102 {EGPD_Output,1}` (else) → `77 {EGPD_Input,0}` (execute) | `null` | | 16 | BT.`get_node_infos` | 102, 394 | 102 conforme ; 394.execute ← 79 [0], 102 [0] (ajout, 79 gardé) | | 17 | BT.`connect_pins` L5 | `45 {EGPD_Output,1}` (then) → `103 {EGPD_Input,0}` (execute) | `null` | | 18 | BT.`connect_pins` L6 | `258 {EGPD_Output,0}` (SexOn) → `103 {EGPD_Input,1}` (Condition) | `null` | | 19 | BT.`connect_pins` L7 | `103 {EGPD_Output,0}` (then) → `394 {EGPD_Input,0}` (execute) | `null` | | 20 | BT.`connect_pins` L8 | `103 {EGPD_Output,1}` (else) → `91 {EGPD_Input,0}` (execute) | `null` | | 21 | BT.`connect_pins` L9 | `303 {EGPD_Output,0}` (then) → `441 {EGPD_Input,0}` (execute) | `null` | | 22 | BT.`connect_pins` L10 | `62 {EGPD_Output,0}` (MoveObject) → `63 {EGPD_Input,0}` (A) | `null` | | 23 | BT.`connect_pins` L11 | `85 {EGPD_Output,0}` (SexOn) → `63 {EGPD_Input,1}` (B) | `null` | | 24 | BT.`connect_pins` L12 | `63 {EGPD_Output,0}` (ReturnValue) → `14 {EGPD_Input,1}` (Condition) | `null` | | 25 | BT.`connect_pins` L13 | `63 {EGPD_Output,0}` (ReturnValue) → `17 {EGPD_Input,1}` (Condition) | `null` | | 26 | BT.`get_node_infos` (étape 5) | 43, 45, 102, 103, 394, 77, 91, 258, 303, 441, 62, 85, 63, 14, 17 | relecture conforme (§ 1.3) | | 27 | BT.`get_node_infos` (étape 5) | témoins 78, 79, 80, 81, 92, 329, 440, 539 à 542 | identiques à l'appel 4 (§ 1.4) | | 28 | AT.`is_dirty` | `{asset_path:"/Game/BPs/Room"}` | `true` | | 29 | BT.`compile_blueprint` | `{blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true}` | `null` (pas d'exception) | | 30 | AT.`save_assets` | `{asset_paths:["/Game/BPs/Room"]}` | `true`, confirmé par le journal et le MD5 | PinID complets des écritures, avec `node:{refPath:"/Game/BPs/Room.Room:EventGraph.K2Node_"}` : - L1 : `output_pin {direction:"EGPD_Output", index_id:1, node:…CustomEvent_43}`, `input_pin {direction:"EGPD_Input", index_id:0, node:…IfThenElse_102}` ; - L2 : `{EGPD_Output,0, …VariableGet_258}` → `{EGPD_Input,1, …IfThenElse_102}` ; - L3 : `{EGPD_Output,0, …IfThenElse_102}` → `{EGPD_Input,0, …CallFunction_394}` ; - L4 : `{EGPD_Output,1, …IfThenElse_102}` → `{EGPD_Input,0, …IfThenElse_77}` ; - L5 : `{EGPD_Output,1, …CustomEvent_45}` → `{EGPD_Input,0, …IfThenElse_103}` ; - L6 : `{EGPD_Output,0, …VariableGet_258}` → `{EGPD_Input,1, …IfThenElse_103}` ; - L7 : `{EGPD_Output,0, …IfThenElse_103}` → `{EGPD_Input,0, …CallFunction_394}` ; - L8 : `{EGPD_Output,1, …IfThenElse_103}` → `{EGPD_Input,0, …IfThenElse_91}` ; - L9 : `{EGPD_Output,0, …CallFunction_303}` → `{EGPD_Input,0, …CallFunction_441}` ; - L10 : `{EGPD_Output,0, …VariableGet_62}` → `{EGPD_Input,0, …CommutativeAssociativeBinaryOperator_63}` ; - L11 : `{EGPD_Output,0, …VariableGet_85}` → `{EGPD_Input,1, …CommutativeAssociativeBinaryOperator_63}` ; - L12 : `{EGPD_Output,0, …CommutativeAssociativeBinaryOperator_63}` → `{EGPD_Input,1, …IfThenElse_14}` ; - L13 : `{EGPD_Output,0, …CommutativeAssociativeBinaryOperator_63}` → `{EGPD_Input,1, …IfThenElse_17}`. Aucune écriture par HyperAIStudio ; aucun outil `hyper_*` appelé. Aucun autre asset chargé. Aucun appel en parallèle. Le journal de l'éditeur compte 30 lignes `Dispatching toolset tool` (0 au début de la fiche) : une par appel ci-dessus. ### 1.2 État lu avant écriture (appels 2 et 3), comparé au tableau « État attendu » | Nœud | type_id, position | Lu | Fiche | |---|---|---|---| | `43` | `AddEvent|Custom|ApplyRoomCamera`, (30000, 1000) | OutputDelegate `{Out,0}` vide ; then `{Out,1}` → `77` [0] | conforme | | `77` | Branche, (30300, 1000) | execute ← `43` [1] ; Condition ← `VariableGet_269` [0] ; then → `78` ; else → `79` | conforme | | `45` | `AddEvent|Custom|UpdateRoomCam`, (30000, 4000) | OutputDelegate `{Out,0}` → `329` [1] (Delegate) ; then `{Out,1}` → `91` [0] | conforme | | `91` | Branche, (30150, 5000) | execute ← `45` [1] ; Condition ← `PromotableOperator_8` [0] ; then → `92` ; else → `81` | conforme | | `258` | `|GetSexOn`, (29900, 2000) | self ← `VariableGet_257` [0] ; SexOn `{Out,0}` → `78` [1], `81` [1] | conforme | | `394` | `Jeu|Joueur|SetViewTargetWithBlend`, (31300, 1600) | execute ← `79` [0] ; self ← `VariableGet_262` ; NewViewTarget ← `GetArrayItem_9` ; then → `303` [0] | conforme | | `303` | `|RestoreC1`, (31000, 1600) | execute ← `394` [0] ; self non relié ; then `{Out,0}` **vide** | conforme | | `441` | `Utilitaires|Temps|ClearandInvalidateTimerbyHandle`, (31900, 4300) | execute ← `440` [0] ; Handle ← `VariableGet_274` [0] ; then vide | conforme | | `14` | Branche, (5984, 3216) | execute ← `IfThenElse_9` ; Condition ← `62` [0] ; then → `27` ; else → `CallFunction_281` | conforme | | `17` | Branche, (6528, 3872) | execute ← `IfThenElse_8` ; Condition ← `62` [0] ; then → `23` ; else → `CallFunction_45` | conforme (le « 45 » de la fiche est ici `K2Node_CallFunction_45`) | | `62` | `|GetMoveObject`, (5664, 3152) | MoveObject `{Out,0}` → `12` [1], `14` [1], `17` [1] | conforme | | `85` | `|GetSexOn`, (5200, 2384) | self ← `VariableGet_40` [0] ; SexOn `{Out,0}` → `CommutativeAssociativeBinaryOperator_17` [1] (B), `24` [1], `27` [1], `23` [1] | conforme | Aucun écart : pas d'arrêt. Les noms des variables lues par `269` (`CamC1On`), `257` (`GI`) et `274` (`RoomCamTimer`) ne sont pas relus par MCP : seuls les liens vers ces nœuds le sont (§ 4). ### 1.3 Relecture finale (appel 26), contrôles de l'étape 5 | Nœud, broche | Avant | Après | Étape 5 | |---|---|---|---| | `43` then `{Out,1}` | → `77` [0] | **→ `102` [0]** (seul lien) | OK | | `45` then `{Out,1}` | → `91` [0] | **→ `103` [0]** (seul lien) | OK | | `45` OutputDelegate `{Out,0}` | → `329` [1] | identique | OK | | `102` (S1) | — | execute ← `43` [1] ; Condition ← `258` [0] ; then → `394` [0] ; else → `77` [0] | OK | | `103` (S2) | — | execute ← `45` [1] ; Condition ← `258` [0] ; then → `394` [0] ; else → `91` [0] | OK | | `394` execute `{In,0}` | ← `79` [0] | **← `79` [0], `102` [0], `103` [0]** ; self, NewViewTarget, then → 303 identiques | OK | | `77` execute `{In,0}` | ← `43` [1] | **← `102` [1]** ; Condition ← 269, then → 78, else → 79 identiques | OK | | `91` execute `{In,0}` | ← `45` [1] | **← `103` [1]** ; Condition ← PromotableOperator_8, then → 92, else → 81 identiques | OK | | `258` SexOn `{Out,0}` | → `78`, `81` | **→ `78` [1], `81` [1], `102` [1], `103` [1]** ; self ← 257 identique | OK | | `303` then `{Out,0}` | vide | **→ `441` [0]** ; execute ← 394 identique | OK | | `441` execute `{In,0}` | ← `440` [0] | **← `440` [0], `303` [0]** ; Handle ← 274 identique ; then vide | OK | | `62` MoveObject `{Out,0}` | → `12`, `14`, `17` | **→ `12` [1], `63` [0]** | OK | | `85` SexOn `{Out,0}` | → OR_17 [1], `24`, `27`, `23` | **→ OR_17 [1], `24` [1], `27` [1], `23` [1], `63` [1]** ; self ← 40 identique | OK | | `63` (O1) | — | A ← `62` [0] ; B ← `85` [0] ; ReturnValue → `14` [1], `17` [1] | OK | | `14` Condition `{In,1}` | ← `62` [0] | **← `63` [0]** ; execute ← 9, then → 27, else → 281 identiques | OK | | `17` Condition `{In,1}` | ← `62` [0] | **← `63` [0]** ; execute ← 8, then → 23, else → CallFunction_45 identiques | OK | ### 1.4 Témoins (appels 4 et 27) : liens identiques, broche par broche | Nœud | Liens lus avant et après | |---|---| | `78` (30600, 900) | execute ← 77 [0] ; Condition ← 258 ; then → VariableSet_63 ; else → 80 | | `79` (30600, 1200) | execute ← 77 [1] ; Condition ← VariableGet_270 ; then → 394 ; else → VariableSet_63 | | `80` (32600, 600) | execute ← 78 [1] ; Condition ← VariableGet_267 ; then → CallFunction_434 ; else → CallFunction_430 | | `81` (30300, 4000) | execute ← 91 [1] ; Condition ← 258 ; then vide ; else → 82 | | `92` (30450, 5000) | execute ← 91 [0] ; Condition ← VariableGet_270 ; then vide ; else → 93 | | `329` `SetTimerbyEvent` | execute ← 434, 94 ; Delegate ← 45 [0] ; Time 0.016 ; bLooping true ; then et ReturnValue → VariableSet_54 | | `440` `RestoreC1` | execute ← 83 [1], 82 [1] ; then → 441 [0] | | `539` `MakeRotator` | Yaw ← CallFunction_514 [2] ; ReturnValue → 540 [2], 542 [2] | | `540` `SetWorldRotation` | execute ← CallFunction_512 ; self ← VariableGet_265 ; NewRotation ← 539 ; then vide | | `541` `SetWorldLocation` | execute ← CallFunction_449 ; self ← 265 ; NewLocation ← PromotableOperator_2 ; then → 542 | | `542` `SetWorldRotation` | execute ← 541 ; self ← 265 ; NewRotation ← 539 ; then → CallFunction_434 | ### 1.5 Compilation et sauvegarde (journal `…\Saved\Logs\portage\CAM-B2p-R-editeur_20261014-100330.log`) - 2 260 lignes au début de la fiche, 0 ligne `Saving Package`, 0 ligne `Dispatching toolset tool`. - Appel 29 : l. 2335, `LogBlueprint: Compiling Blueprint '/Game/BPs/Room.Room'`. De la l. 2335 à la fin (l. 2370), compilation, sauvegarde et validation comprises : 0 ligne `error` ni `warning` (insensible à la casse). - Entre la l. 2261 et la l. 2334, 4 lignes `LogModelContextProtocol: Error:` à 08:05:05-06 (UTC) : `Unknown session id … client should reinitialize` et trois `Call to unknown method "server/discover"`. C'est la reconnexion de session du client MCP, avant et pendant l'appel 1. Ce ne sont pas des diagnostics de Blueprint. `load_asset` n'a été distribué qu'une fois (l. 2271). - `hyper_blueprint_debug_inspect` n'a pas été appelé : il est absent du serveur. Repli prévu : compilation avec `warnings_as_errors` et lecture du journal. - Sauvegarde, l. 2340 : `Saving Package: /Game/BPs/Room`. Puis `Moving '…/Saved/Room20786E154D9D50F036B7399F033F03F3.tmp' to '…/Content/BPs/Room.uasset'` et `AssetCheck: /Game/BPs/Room Validation de la ressource`. ### 1.6 Comportement et garde `Accessed None` (lp-mcp § 1 règle 4) - Hors sexe (`SexOn` faux) : - S1.else → 77 et S2.else → 91 reprennent les voies d'avant, sans changement ; - O1 = `MoveObject OR false` = `MoveObject` ; - seul effet voulu par la fiche : la voie C3 (79.then → 394 → 303) mène maintenant aussi à 441. - Aucun `IsValid` ajouté (la fiche n'en prévoit pas). S1 et S2 lisent `258` (`GI.SexOn`), déjà lu sans garde par 78 et 81 sur ces voies. - O1 est un OU pur : il évalue toujours ses deux entrées. `85` (`GI.SexOn`, self ← `VariableGet_40`) est déjà lu en amont de 14 et de 17. 14.execute ← `IfThenElse_9` et 17.execute ← `IfThenElse_8`. Les conditions de 8 et 9 sont la sortie de `CommutativeAssociativeBinaryOperator_17` (`BooleanOR`), dont l'entrée B ← `85`. Source : dump `CAM-B2s-VAL_LPDumpFunction_20261014-084441.txt` l. 6158-6166 et 5230-5235. Établi : aucune lecture nouvelle. ## 2. Écarts à la SPEC - Aucun écart sur l'état lu, les types, les PinID, les écritures ni la relecture. - Ajouts en lecture seule, non prévus par la fiche : - deux `find_node_types` (appels 5 et 6), demandés par l'orchestrateur ; - lecture des 11 témoins avant écriture (appel 4), pour pouvoir dire « aucun autre lien modifié » à l'étape 5 ; - deux relectures intermédiaires : 43 et 77 après L1 (appel 12), 102 et 394 après L4 (appel 16). - Positions choisies : S1 (30100, 1300), S2 (30000, 4300), O1 (5824, 3408). La fiche dit seulement « près de ». - Le tableau de la fiche note `17` « else → 45 » : c'est `K2Node_CallFunction_45`, pas l'événement `K2Node_CustomEvent_45`. Simple lecture, sans effet. - Room seul chargé et enregistré. Ni build, ni commandlet, ni jeu. L'éditeur n'a été ni lancé ni arrêté. ## 3. Instantané - `D:\Game\LifePlay_Backup_5.5\CAM-B2p-R\manifest.csv`, pris par l'orchestrateur et relu : `"Content\BPs\Room.uasset","True","6422095","C5AB724101FA898457293D64059D21A9","2026-10-14T09:14:57"`. - MD5 de Room sur le disque égal au manifeste, à 10:04:51 et à 10:05:57, avant l'appel 7 (première écriture). - Retour arrière **proposé, non lancé**, par l'orchestrateur, éditeur fermé, sur accord : 1. `.\Tools\Snapshot.ps1 -Lot CAM-B2p-R-retour -Path Content\BPs\Room.uasset` ; 2. `.\Tools\Restore.ps1 -Lot CAM-B2p-R -Only Content\BPs\Room.uasset -WhatIf` ; 3. `.\Tools\Restore.ps1 -Lot CAM-B2p-R -Only Content\BPs\Room.uasset`. Contrôle : `md5sum Content/BPs/Room.uasset` = `c5ab724101fa898457293d64059d21a9`. - Entrée (sk-change-safety) : `2026-10-14 | CAM-B2p-R : S1 (IfThenElse_102) et S2 (IfThenElse_103) sur SexOn devant 77 et 91, 303.then → 441 ; O1 (ORBoolean _63) = MoveObject OR SexOn vers 14 et 17 | Content/BPs/Room.uasset | retour arrière : Restore.ps1 -Lot CAM-B2p-R -Only Content\BPs\Room.uasset | instantané : D:\Game\LifePlay_Backup_5.5\CAM-B2p-R | vérification : relecture conforme, compilation stricte 0 diagnostic, Room = 93138747…`. ## 4. Ce qui n'a pas été fait - Les noms de variables de `269` (`CamC1On`), `257` (`GI`), `274` (`RoomCamTimer`) et `40` (`GI`) ne sont pas relus par MCP. `40` est relu dans le dump (l. 5230 : `variable 'GI'`). - Le nombre de nœuds de l'EventGraph (1276 → 1279) n'est pas compté par MCP : il revient à V5. - `is_dirty` n'est pas relu après la sauvegarde (la fiche ne le demande pas). - Hors fiche (lp-mcp § 1 règles 3 et 5) : - `CompileAllBlueprints` éditeur fermé ; - build empaqueté, `LogStats`, essai en jeu (V7) ; - le repli « `ApplyRoomCamera` différé côté C++ » (non écrit, comme la fiche le prévoit). - L'éditeur n'est pas fermé : c'est le rôle de l'orchestrateur, puis `BUILD-FIN`. ## 5. Points à confirmer en VAL - Room = `931387479e2d15f80bc4f36398907712`. GI = `bd0a2256…`, PC = `f45be57a…`, Person = `8668a47c…`, inchangés. - V5, dump de Room comparé à `CAM-B2s-VAL_LPDumpFunction_20261014-084441.txt` : - l'EventGraph passe de 1276 à 1279 nœuds ; - nœuds nouveaux : `K2Node_IfThenElse_102` (S1), `K2Node_IfThenElse_103` (S2), `K2Node_CommutativeAssociativeBinaryOperator_63` (O1, `BooleanOR`) ; - liens : 43.then → 102 au lieu de 77 ; 45.then → 103 au lieu de 91 ; 102 et 103 Condition ← 258 ; 102.then et 103.then → 394 ; 102.else → 77 ; 103.else → 91 ; 303.then → 441 ; - 62 → 63.A et 85 → 63.B ; 63 → 14.Condition et 17.Condition ; 62 ne sort plus que vers 12 et 63 ; - aucune autre différence (témoins du § 1.4). - V6 : `CompileAllBlueprints` éditeur fermé = référence (Room sans erreur ni avertissement nouveau). - V7 : CAM-41 à CAM-49, CAM-54 et CAM-55 de `CAM-B2p-SPEC.md`, avec B2p-C compilé. En particulier : - CAM-42 depuis C1, C2 et C3, dès l'entrée en sexe et après POV → Scene : vue `SceneCamera`, minuterie arrêtée ; - flèches = couple sans Maj pendant le sexe ; molette avec Maj inchangée (62 → 12) ; - hors sexe, comportement inchangé ; - en fin de sexe, `SexOn` est faux au crochet B1-11 (GI 2699 → `ApplyRoomCamera`). - V7 : `LogStats` sans `Accessed None` nouveau sur Room (aucune lecture nouvelle, § 1.6). ## 6. Fichiers à commiter - M `Content/BPs/Room.uasset` (dépôt du jeu, branche ue5.8). - A `Docs/Migration/etat/CAM/CAM-B2p-R-IMPL.md` (dépôt du jeu, branche ue5.8). - Pas GI, PC ni Person : leur `M` dans `git status` vient de lots antérieurs. Room était déjà `M` au début de la fiche (fiches B2 précédentes) : le commit le prendra dans son état actuel. ## Mesuré ``` $ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/PC.uasset Content/BPs/Person.uasset ; date (avant l'appel 1) c5ab724101fa898457293d64059d21a9 *Content/BPs/Room.uasset bd0a2256b875a3ac875630e4b85d92d7 *Content/BPs/GI.uasset f45be57a39d13d3eb19d0b543153ab0b *Content/BPs/PC.uasset 8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset 2026-10-14 10:04:51 $ cat D:/Game/LifePlay_Backup_5.5/CAM-B2p-R/manifest.csv "Rel","Existed","Size","MD5","Date" "Content\BPs\Room.uasset","True","6422095","C5AB724101FA898457293D64059D21A9","2026-10-14T09:14:57" $ tasklist /FI "PID eq 22448" UnrealEditor.exe 22448 Console 1 7 305 680 Ko $ wc -l ; grep -n "Saving Package" ; grep -c "Dispatching toolset tool" (journal de l'éditeur, avant l'appel 1) 2260 CAM-B2p-R-editeur_20261014-100330.log (aucune ligne) 0 $ md5sum Content/BPs/Room.uasset ; date (avant l'appel 7, première écriture) c5ab724101fa898457293d64059d21a9 *Content/BPs/Room.uasset 10:05:57 $ wc -l ; grep -c "Dispatching toolset tool" ; grep -n "Compiling Blueprint" (après l'appel 29) 2336 CAM-B2p-R-editeur_20261014-100330.log 29 2335:[2026.10.14-08.07.26:399][494]LogBlueprint: Compiling Blueprint '/Game/BPs/Room.Room' $ wc -l ; grep -n "Saving Package" ; grep -c "Dispatching toolset tool" (après l'appel 30) 2370 Saved/Logs/portage/CAM-B2p-R-editeur_20261014-100330.log 2340:[2026.10.14-08.07.39:540][140]LogFileHelpers: Saving Package: /Game/BPs/Room 30 $ tail -n +2335 | grep -ciE "error|warning" 0 $ md5sum Content/BPs/Room.uasset Content/BPs/GI.uasset Content/BPs/PC.uasset Content/BPs/Person.uasset (après l'appel 30) 931387479e2d15f80bc4f36398907712 *Content/BPs/Room.uasset bd0a2256b875a3ac875630e4b85d92d7 *Content/BPs/GI.uasset f45be57a39d13d3eb19d0b543153ab0b *Content/BPs/PC.uasset 8668a47c627f7a5254910cf0ac33b12a *Content/BPs/Person.uasset $ stat -c "%s %y %n" Content/BPs/Room.uasset 6428769 2026-10-14 10:07:40.131707500 +0200 Content/BPs/Room.uasset $ git status --short -- Content/BPs/ M Content/BPs/GI.uasset M Content/BPs/PC.uasset M Content/BPs/Person.uasset M Content/BPs/Room.uasset ``` Tours : 43 / 60 ## Constats - `K2Node_CustomEvent` : OutputDelegate `{EGPD_Output,0}`, then `{EGPD_Output,1}`, et non then 0. Relevé sur 43 et 45. - ORBoolean créé par `Math|Booléen|ORBoolean` : la classe est `K2Node_CommutativeAssociativeBinaryOperator`. Broches : A `{In,0}`, B `{In,1}`, ReturnValue `{Out,0}`. `find_node_types` avec le filtre `ORBoolean` rend aussi XOR et NOR. - `connect_pins` sur une entrée d'exécution déjà reliée **ajoute** le lien (394 : 3 liens entrants, 441 : 2). Sur une entrée de données reliée, il **remplace** (14 et 17 Condition : 62 retiré, sans `break_pins`). Sur une sortie d'exécution reliée, il **remplace** (43.then, 45.then : 77 et 91 ont perdu leur entrée, puis l'ont reprise par S1.else et S2.else). - Une reconnexion du client MCP écrit des lignes `LogModelContextProtocol: Error:` (`Unknown session id`, `server/discover`) dans le journal de l'éditeur. Il faut les exclure du compte des diagnostics de compilation, ou compter seulement à partir de la ligne `Compiling Blueprint`. - À verser : lp-mcp § 3, quatre points : - indices de `K2Node_CustomEvent` (then = sortie 1) ; - `ORBoolean` (classe CommutativeAssociativeBinaryOperator, A 0, B 1, ReturnValue 0) ; - effet de `connect_pins` selon la broche (sortie d'exécution : remplace ; entrée d'exécution : ajoute ; entrée de données : remplace) ; - lignes d'erreur MCP de reconnexion à exclure du compte de diagnostics (CAM-B2p-R).