LifePlay-Revival/Docs/Migration/etat/ST/STE/STE-H3g-IMPL.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

19 KiB
Raw Blame History

Fiche STE-H3g-I — Niveau N3 — Modèle prévu opus (xhigh) | utilisé claude-opus-5-5 — Agent lp-mcp-bp — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot

STE-H3g-IMPL : garde G16 (GI:EventGraph, UpdateDefaultHair) écrite par MCP (2026-10-13)

Copie D:\Game\LifePlay-master 5.8, branche ue5.8, HEAD 0745917. SPEC : STE-H3g-SPEC.md § 2.0, 2.1, 2.3, 3, 4, 7 (G16 seule ; G15 non écrite, décision Q-H3g-1 = c). UE-GO de Big Boss reçu (fiche, rubrique 3). Éditeur headless lancé et fermé par l'agent (lp-mcp § 2). Un appel MCP par message, outils Epic seulement (aucun hyper_*, aucun execute_tool_script).

1. Fichiers modifiés

Un seul : Content\BPs\GI.uasset, graphe /Game/BPs/GI.GI:EventGraph, enregistré par save_assets {asset_paths:["/Game/BPs/GI"]} → true.

Empreintes (Git Bash, copie 5.8, md5sum Content/BPs/GI.uasset Content/BPs/Person.uasset Content/BPs/Room.uasset "/d/Game/LifePlay_Backup_5.5/STE-H3g/Content/BPs/GI.uasset") :

Fichier Avant (17:53) Après (18:07, éditeur fermé)
Content/BPs/GI.uasset c4817b847ecf246c859647577647d6e9 0e6aedcccd1a6522282f9a423843ce45
instantané D:\Game\LifePlay_Backup_5.5\STE-H3g\Content\BPs\GI.uasset c4817b847ecf246c859647577647d6e9 c4817b847ecf246c859647577647d6e9 (inchangé)
Content/BPs/Person.uasset (autre lot, non ouvert) 8668a47c627f7a5254910cf0ac33b12a 8668a47c627f7a5254910cf0ac33b12a
Content/BPs/Room.uasset (autre lot, non ouvert) ca2a9a0baaca4130fd5c318797f008ae ca2a9a0baaca4130fd5c318797f008ae

git status --short -- Content : avant M Person, M Room ; après M Content/BPs/GI.uasset, M Content/BPs/Person.uasset, M Content/BPs/Room.uasset.

Comptes de GI:EventGraph (find_nodes {graph:{refPath:"/Game/BPs/GI.GI:EventGraph"}, title:""}, sortie enregistrée par le client puis comptée par grep -o 'GI\.GI:EventGraph\.K2Node_[A-Za-z]*_[0-9]*') : 6 247 → 6 251 nœuds K2Node (+4, exactement les 4 nouveaux) ; avec les 2 commentaires (EdGraphNode_Comment_0, _1) que find_nodes ne liste pas : 6 249 → 6 253, compte du dump. Voir § 2 E1.

1.1 P4 : nœuds existants relus avant écriture (get_node_infos, deux appels de 8 nœuds)

Préfixe des refPath : /Game/BPs/GI.GI:EventGraph.K2Node_. Les 16 nœuds de la SPEC § 2.0 P4 retrouvés, tous conformes à la colonne « Avant » (§ 2.3.1).

Nœud type_id relu, position Liens et indices relevés
CustomEvent_5 `AddEvent Custom
IfThenElse_104 `Utilitaires ContrôleDeFlux
IfThenElse_65 / _66 Branche, (-9648, 9504) / (-9712, 9744) Condition ← CallFunction_235 ; then 0 → CallFunction_662 / _661 ; else 1 → CallFunction_259 / _287
CallFunction_259 / _287 ` LoadHairMeshIfNeeded`
CallFunction_662 / _661 `Composants Maillagesurfacé
MacroInstance_5 / _4 `Utilities Array
CallFunction_5654 ` TurnMaterialDynamic`, (-8176, 9552)
CallFunction_237 ` FitMorphableHair`, (-7856, 9648)
BreakStruct_12 / _13 `Utilitaires Structure
VariableGet_1147 / _64 ` GetMaterials`, (-9312, 9440) / (-8976, 9904)

1.2 Nœuds créés (correspondance SPEC → nom réel → type_id)

Chaque type_id vérifié par find_node_types {graph, type_id_filter, context_pins:[]} juste avant son create_node (4 appels), nœuds relus par get_node_infos avant tout câblage.

SPEC Nœud réel (refPath /Game/BPs/GI.GI:EventGraph.K2Node_…) Filtre → réponse type_id de création = relu Broches (index) Position
G16a-V IsValid CallFunction_715 `Utilitaires IsValid→ 5 :…IsValidSoftObjectReference, …IsValidSoftClassReference, …IsValidInterface, …IsValidClass, Utilitaires IsValid` `Utilitaires
G16a-B Branche IfThenElse_219 `ContrôleDeFlux Branche→ 1 :Utilitaires ContrôleDeFlux Branche`
G16b-V IsValid CallFunction_720 idem G16a-V (5) `Utilitaires IsValid` idem
G16b-B Branche IfThenElse_220 idem G16a-B (1) `Utilitaires ContrôleDeFlux Branche`

Aucun set_pin_value, aucun delete_node.

1.3 Coupures et liens (un appel MCP par message, réponse null pour chacun)

# Geste Sortie (index) Entrée (index)
C1 break_pins CallFunction_662.then (0) MacroInstance_5.Exec (0)
1 connect_pins BreakStruct_12.SkeletalMesh_2_93573D9945CD4136090CCBA1F1188DAC (0) CallFunction_715.Object (0)
2 connect_pins CallFunction_662.then (0) IfThenElse_219.execute (0)
3 connect_pins CallFunction_715.ReturnValue (0) IfThenElse_219.Condition (1)
4 connect_pins IfThenElse_219.then (0) MacroInstance_5.Exec (0)
5 connect_pins IfThenElse_219.else (1) CallFunction_5654.execute (0)
C2 break_pins CallFunction_661.then (0) MacroInstance_4.Exec (0)
6 connect_pins BreakStruct_13.SkeletalMesh_2_93573D9945CD4136090CCBA1F1188DAC (0) CallFunction_720.Object (0)
7 connect_pins CallFunction_661.then (0) IfThenElse_220.execute (0)
8 connect_pins CallFunction_720.ReturnValue (0) IfThenElse_220.Condition (1)
9 connect_pins IfThenElse_220.then (0) MacroInstance_4.Exec (0)
10 connect_pins IfThenElse_220.else (1) CallFunction_5654.execute (0)

Relecture (get_node_infos de 20 nœuds en deux appels : les 4 nouveaux + les 16 de P4 + CallFunction_2917 / _2918), conforme au § 2.3.2 :

  • CallFunction_662.then → IfThenElse_219.execute seul ; MacroInstance_5.Exec ← IfThenElse_219.then seul ; idem CallFunction_661.then → IfThenElse_220 seul, MacroInstance_4.Exec ← IfThenElse_220.then seul.
  • IfThenElse_219 : Condition ← CallFunction_715.ReturnValue ; else → CallFunction_5654.execute. IfThenElse_220 : Condition ← CallFunction_720.ReturnValue ; else → CallFunction_5654.execute.
  • CallFunction_715.Object ← BreakStruct_12 (0) ; CallFunction_720.Object ← BreakStruct_13 (0).
  • BreakStruct_12.SkeletalMesh_2_… → VariableGet_1147 (0), CallFunction_662.NewMesh (2), CallFunction_715.Object (0) ; BreakStruct_13.SkeletalMesh_2_… → VariableGet_64, CallFunction_661.NewMesh, CallFunction_720.Object.
  • CallFunction_5654.execute : 4 sources : MacroInstance_4 (3), MacroInstance_5 (3), IfThenElse_219 (1), IfThenElse_220 (1).
  • Inchangés : SetSkinnedAssetAndUpdate ×2 (execute, self, NewMesh, bReinitPose = true), MacroInstance_4/_5 (Array, LoopBody, Array Element, Array Index, Completed), VariableGet_1147/_64, CallFunction_5654.then → CallFunction_237, CustomEvent_5, IfThenElse_104/_65/_66, CallFunction_259/_287, CallFunction_2917/_2918.

1.4 Compilation et enregistrement

Journal : D:\Game\LifePlay-master 5.8\Saved\Logs\STE-H3g-headless-20261013-175345.log (heures UTC = locale − 2 h).

  • compile_blueprint {blueprint:{refPath:"/Game/BPs/GI.GI"}, warnings_as_errors:true} → null. Journal l. 2332, 16.06.47:036 : LogBlueprint: Compiling Blueprint '/Game/BPs/GI.GI' ; l. 2333 16.06.51:737 : LogUObjectHash: Compacting …. tail -n +2330 <journal> | grep -c -E 'Error|Warning' → 0. hyper_blueprint_debug_inspect non utilisé (absent du serveur, H3dI:156 ; fiche).
  • save_assets {asset_paths:["/Game/BPs/GI"]} (editor_toolset.toolsets.asset.AssetTools) → true. Journal l. 2340, 16.07.00:306 : Cmd: OBJ SAVEPACKAGE PACKAGE="/Game/BPs/GI" FILE="…/Content/BPs/GI.uasset" SILENT=true ; 16.07.04:595 : déplacement du .tmp vers Content/BPs/GI.uasset ; AssetCheck: /Game/BPs/GI (1 ressource validée), sans échec listé. grep -n SAVEPACKAGE <journal> → 2 lignes : 2274 (autosave, § 2 E4) et 2340 (seul enregistrement dans Content).
  • Éditeur : lancé 17:54:02 (PID 36020), Stop-Process -Id 36020 à 18:07:12 ; Tools\UeState.ps1 à 18:07:24 → processus=0 editeur=0 compilation=0 shaders=0 jeu=0 (code 0).

1.5 Garde Accessed None (lp-mcp § 1 règle 4) et comportement

  • IsValid justifié : « maillage vide » est un état normal ici : l'entrée de HairstyleTable lue par GetArrayItem_4/_6 peut rendre SkeletalMesh_2 = None (observé 2 fois dans HJ:16058, 16086), et l'utilisateur a décidé de garder « pas de coiffure, comme aujourd'hui » (décision Q1, SPEC § 1).
  • Cascade de Branche seule, aucun AND / OR / Select. SetSkinnedAssetAndUpdate(HairSM, None) reste appelé avant la garde (la coiffure est toujours vidée).
  • Maillage valide : then → boucle, chemin d'origine (établi par construction). Maillage None : else → CallFunction_5654 → CallFunction_237, sans lecture Materials (estimé identique à l'exécution actuelle, voir R-H3g-4 ci-dessous).

1.6 Réponse au point amont R-H3g-4 (successeurs des boucles)

Établi (relecture get_node_infos du jour) : MacroInstance_5 et _4 n'ont, en exécution, que deux sorties reliées : LoopBody (0) → CallFunction_2918 / _2917 (Rendu|Matériau|SetMaterial, dont la sortie then (0) n'a aucun lien) et Completed (3) → CallFunction_5654.execute seul. Aucun autre successeur que CallFunction_5654 après la boucle ; le corps de boucle s'arrête à SetMaterial. Donc l'else des gardes (→ CallFunction_5654) reproduit la suite d'exécution actuelle dès que la boucle fait 0 itération. Le « 0 itération sur tableau effacé » reste estimé (macro ForEachLoop non lue, SPEC § 6) ; s'il était faux, la seule différence serait des SetMaterial sur HairSM sans maillage.

2. Écarts à la SPEC

  • E1 (compte) : find_nodes title:"" rend 6 247 nœuds avant écriture, pas 6 249. Les 2 manquants sont les commentaires du graphe, que find_nodes ne liste pas : le dump compte EdGraphNode_Comment_0 et _1 (GEV, premier listing : 6 249 noms dont 6 247 K2Node_*) ; diff des noms K2Node_* du dump et de la liste MCP → aucune différence (code 0) ; get_node_infos sur les deux commentaires → 'EdGraphNode_Comment' object has no attribute 'get_node_title' (objets résolus, non K2). Le graphe est donc celui du dump (MD5 identique en plus). J'ai poursuivi : l'écart est dans la méthode de comptage, pas dans l'état. Après : 6 251 par find_nodes = 6 253 au sens du dump (à confirmer par le dump de VAL, § 5).
  • E2 (attente MCP) : Wait-HyperAIStudioMCP.ps1 -Port 8000 -UrlPath /mcp -TimeoutSeconds 540 → code 1, sans sortie, après 540 s (17:54 → 18:03), alors que le serveur écoutait depuis 15.54.14:094 UTC (journal l. 1903-1906 : Starting MCP server on port 8000, Created new HttpListener on 127.0.0.1:8000 ; Get-NetTCPConnection -LocalPort 8000 → propriétaire 36020) ; get_current_level a répondu /Game/Scenes/CentralLondon. Cause du code 1 non instruite.
  • E3 (lecture hors liste) : un get_node_infos sur les deux commentaires (E1) a laissé LogScript: Warning: 'EdGraphNode_Comment' object has no attribute 'get_node_title' au journal (16.04.18, avant la compilation) ; lecture seule.
  • E4 (autosave) : l'éditeur a écrit Saved\Autosaves\Game\BPs\GI_Auto1.uasset à 16.05.07 UTC (l. 2274, pendant le câblage). Déplacé (pas supprimé) vers D:\Game\LifePlay_Backup_5.5\STE-H3g\autosave\GI_Auto1.uasset (52 611 967 octets, MD5 4740351cdf4d3733f990922f87367723) ; plus aucun GI_Auto* sous Saved\Autosaves. Les autres autosaves (Person_Auto1, Room_Auto1-4, TestStatic_Auto1, UI\MainMenu_Auto1) préexistaient et n'ont pas été touchés.
  • E5 (P5) : get_node_infos des nouveaux nœuds fait par paire (après les deux créations de chaque garde), avant tout câblage, au lieu d'un appel après chaque création.
  • E6 (budget) : 53 tours pour un budget ≈ 50 (plafond 60).
  • Aucun autre : 4 nœuds, 2 coupures, 10 liens exactement selon § 2.3.2 ; G15 non écrite ; aucun autre graphe ni asset ouvert en écriture ; Person et Room ni chargés ni enregistrés.

3. Instantané

Pris par l'orchestrateur avant la fiche (pas de Snapshot.ps1 relancé) : D:\Game\LifePlay_Backup_5.5\STE-H3g\Content\BPs\GI.uasset, MD5 c4817b847ecf246c859647577647d6e9 = GI de départ, relu identique après l'enregistrement. Manifeste D:\Game\LifePlay_Backup_5.5\STE-H3g\manifest.csv non relu par l'agent. Retour arrière (proposé, non lancé ; décision de l'orchestrateur, éditeur fermé) : .\Tools\Restore.ps1 -Lot STE-H3g -Only Content\BPs\GI.uasset -WhatIf, puis sans -WhatIf ; MD5 attendu c4817b847ecf246c859647577647d6e9. Après commit : git revert du commit du ticket STE-H3g. Entrée de journal (sk-change-safety) : 2026-10-13 | G16 (2 IsValid + 2 Branche) dans GI:EventGraph | Content/BPs/GI.uasset | retour arrière : Restore.ps1 -Lot STE-H3g -Only Content\BPs\GI.uasset | instantané : D:\Game\LifePlay_Backup_5.5\STE-H3g\ | vérification : 6 247 → 6 251 K2Node (+4), relecture conforme, compilation 0 / 0, MD5 0e6aedcc…

4. Ce qui n'a pas été fait

  • G15 (isSameAs) : non écrite (décision Q-H3g-1 = c) ; isSameAs non chargé en lecture ni en écriture.
  • Dumps LPDumpFunction après IMPL, CompileAllBlueprints, LPTestStringCompat, build et journal de jeu : à la VAL / au BUILD (SPEC § 7).
  • Cause du maillage None (piste Daz) : hors périmètre (SPEC § 2.3.3, R-H3g-7).
  • Gel annoncé aux autres sessions et BUILD-FIN : à l'orchestrateur.

5. Points à confirmer en VAL

  • Dump -BP=GI -Fn=EventGraph -Pins -Exec → (6253 noeuds) ; liens du § 7.1 de la SPEC avec les noms réels : G16a-V = CallFunction_715, G16a-B = IfThenElse_219, G16b-V = CallFunction_720, G16b-B = IfThenElse_220.
  • DiffRemplacementNoeuds.py sur EventGraph (avant = dumps\GI__EventGraph_P2.txt) : seuls ces 4 nœuds, 2 coupures, 10 liens.
  • isSameAs reste à 11 nœuds (G15 abandonnée : le « 15 » de la SPEC § 7.1 ne s'applique plus) ; GetVariable 53, Action:EventGraph 363, CallFunctionReturnBool 594 inchangés.
  • CompileAllBlueprints éditeur fermé : BP /Game/ 0 erreur ; LPTestStringCompat 3120 / 0 / 60.
  • MD5 de GI = 0e6aedcccd1a6522282f9a423843ce45 au départ de la VAL ; Person 8668a47c… et Room ca2a9a0b… inchangés.
  • Journal de jeu (build, même ligne de commande que HJ) : SkeletalMesh_2_93573D 2 → 0, UpdateDefaultHair 4 → 0 ; Person_24_.*of length 0 (2) et isSameAs (3) attendus inchangés (G15 non écrite) ; preuve de parcours rejoué de la SPEC § 7.4 (G16).
  • R-H3g-4 : 0 itération sur tableau effacé reste estimé (§ 1.6) ; aucune autre suite d'exécution que CallFunction_5654 (établi).
  • Code 1 de Wait-HyperAIStudioMCP.ps1 alors que le serveur répondait (E2) : à instruire hors lot.

6. Fichiers à commiter

Dépôt jeu, branche ue5.8, ticket au gardien :

  • M Content/BPs/GI.uasset
  • A Docs/Migration/etat/ST/STE/STE-H3g-IMPL.md Ne pas inclure Content/BPs/Person.uasset ni Content/BPs/Room.uasset (autres lots, M préexistants).

Tours : 53 / 50 (plafond 60)

Constats

Commandes et sorties brutes (extraits) :

  • Entrée : md5sum Content/BPs/GI.uasset Content/BPs/Person.uasset Content/BPs/Room.uasset <instantané GI> → c4817b847ecf246c859647577647d6e9, 8668a47c627f7a5254910cf0ac33b12a, ca2a9a0baaca4130fd5c318797f008ae, c4817b847ecf246c859647577647d6e9 ; git rev-parse --short HEAD → 0745917 ; Tools/UeState.ps1 → processus=0 editeur=0 compilation=0 shaders=0 jeu=0.
  • Lancement : Start-Process UnrealEditor.exe "<copie>\LifePlay.uproject" -RenderOffScreen -unattended -nosplash -NoSound -ModelContextProtocolStartServer -ModelContextProtocolPort=8000 "-abslog=<copie>\Saved\Logs\STE-H3g-headless-20261013-175345.log" → PID=36020, 17:54:02. Aucune demande de recompilation de modules : grep -i -E "modules are missing|rebuild|out of date|built with a different" → aucune ligne utile (le seul « Took … seconds » relevé concerne la configuration).
  • Comptes (grep -o 'GI\.GI:EventGraph\.K2Node_[A-Za-z]*_[0-9]*' <sortie find_nodes>, sorties enregistrées par le client sous %USERPROFILE%\.claude\projects\D--Game-LifePlay-master-5-8\36e41eab-6dbf-4c01-adea-9fe53389b8ce\tool-results\mcp-unreal-mcp-call_tool-1791907424673.txt (avant) et …-1791907595179.txt (après)) :
avant: total 6247, uniques 6247
apres: total 6251, uniques 6251, refPath 6251
-- presents dans une seule liste :
> GI.GI:EventGraph.K2Node_CallFunction_715
> GI.GI:EventGraph.K2Node_CallFunction_720
> GI.GI:EventGraph.K2Node_IfThenElse_219
> GI.GI:EventGraph.K2Node_IfThenElse_220
  • Dump : head -n 30176 GI__EventGraph_P2.txt | grep -E '^ [A-Za-z]' | awk '{print $1}' | sort -u | wc -l → 6249 ; non K2Node_ → EdGraphNode_Comment_0, EdGraphNode_Comment_1 ; K2Node_ → 6247 ; diff avec la liste MCP avant → code 0.
  • Lignes Error / Warning du journal avant la compilation (l. 1990-2329) : sessions MCP (Unknown session id … client should reinitialize, Call to unknown method "server/discover", 16.03.25-16.03.26, reconnexion du client), E3 (16.04.18), LogHttp: Warning: HTTP request timed out … generate_204 (16.05.09) ; 20 LogAutomationTest: Error: Condition failed au démarrage (l. 1730-1747…, 15.54.13, tests du moteur au chargement). Aucune liée à GI.
  • Lecture seule de Person et Room respectée : ni load_asset, ni save_assets ; MD5 identiques.