Fiche STF-T1 — Niveau N1 — Modèle prévu orchestrateur STF (Opus 5.5) | utilisé claude-opus-5-5 — Agent orchestrateur — Skills lp-mcp, lp-lot, sk-protocol # STF-T1 : relevés MCP sur MainMenu après STC, choix de méthode (2026-10-10) Copie `D:\Game\LifePlay-master 5.8` (branche `ue5.8`, HEAD `1a4e73c`, STC commité en `bc4d91f`). BUILD-GO STF-T1 de « Big Boss ». Éditeur 5.8 lancé sans rendu (`-RenderOffScreen -unattended`, chemin du projet entre guillemets ; le script `Start-HyperAIStudioEditor.ps1` passe toujours le chemin sans guillemets, défaut déjà relevé par STC), journal `Saved\Logs\portage\STF-T1_Editor_20261010-105655.log`. **Lecture seule** : `load_asset`, `find_nodes`, `get_node_infos`, `UMGToolSet.GetWidgets` / `GetWidgetDescription`, `ObjectTools.list_properties` / `get_properties` (via `ProgrammaticToolset`) ; aucune sauvegarde, aucune compilation. | Contrôle | Entrée | Sortie | |---|---|---| | MD5 `Content/UI/MainMenu.uasset` | 59d1ee7190afb88bf51b90eda26fcc32 | 59d1ee7190afb88bf51b90eda26fcc32 | | MD5 `Content/BPs/GI.uasset` | d93785fca90e3342575fc0b601cc2e93 | d93785fca90e3342575fc0b601cc2e93 | ## 1. Gestionnaires des 12 couples : T0 confirmé (établi, `get_node_infos`) `find_nodes` « SpinBox » sur l'EventGraph : 13 événements (`ComponentBoundEvent_13, 15, 17, 19, 20, 21, 22, 23, 26, 31, 42, 84, 178`) + `VariableGet_49` (STC) ; `6` (ChildGrowthMult) et `118` (ShadeDepth) relus directement. Les 12 chaînes sont **identiques à STF-T0 § 1** (mêmes nœuds, mêmes liens) : | # | Événement `OnValueChanged` | Chaîne relue | GI | |---|---|---|---| | 1 | 6 ChildGrowthMult | `MacroInstance_2` (IsValid) → `VariableSet_1` | `VariableGet_29` (partagé 6, 13, 17) | | 2 | 118 ShadeDepth | `MacroInstance_40` → `VariableSet_106` → `DynamicCast_7` (MID) → `CallFunction_820` SetScalarParameterValue('ShadeDepth', sortie du Set) ; échec → `CallFunction_265` PrintString | `VariableGet_461` (Set) ; `VariableGet_106` → PostProcessVolume → Settings → `BreakStruct_9/10` → `GetArrayItem_6`[1] → `BreakStruct_11` | | 3 | 20 SpinBoxBGA | `MacroInstance_10` → `VariableSet_16` | `VariableGet_1` (partagé 20-23) | | 4 | 13 SpinBoxMarkerSize | `MacroInstance_5` → `VariableSet_6` | `VariableGet_29` | | 4b | **15** `OnValueCommitted` MarkerSize | `CallFunction_44` RetriggerableDelay 2 s → `CallFunction_31` SpawnMapMarkers(false) | `VariableGet_17` | | 5 | 23 SpinBoxMoan | `MacroInstance_8` → `VariableSet_19` | `VariableGet_1` | | 6 | 17 SpinBoxPhysicsMult | `MacroInstance_7` → `VariableSet_11` | `VariableGet_29` | | 7 | 178 SpinBoxSceneFrequency | `MacroInstance_42` → `VariableSet_116` | `VariableGet_195` | | 8 | 84 SpinBoxSexDescription | `MacroInstance_90` → `VariableSet_48` | `VariableGet_7504` | | 9 | 22 SpinBoxSex | `MacroInstance_12` → `VariableSet_18` | `VariableGet_1` | | 10 | 26 SpinBoxSquirtMult | `VariableSet_25` **sans IsValid** | `VariableGet_40` | | 11 | 21 SpinBoxUI | `MacroInstance_11` → `VariableSet_17` | `VariableGet_1` | | 12 | 42 SpinBoxPregnancyTerm | `MacroInstance_57` → `VariableSet_70` | `VariableGet_324` | Aucune sortie « Is Not Valid » branchée. Hors périmètre relu : 19 (`SpinBox_0`), 31 (`OnValueCommitted` SpinBoxSexDuration, STC). ## 2. Chaîne `Construct` après STC (établi) `Event_1` (Construct) → `DynamicCast_0` (Cast To GI) → `VariableSet_2904` (Set GI) → `CallFunction_72` (`SliderCameraSpeed.SetValue(InValue)`) → `CallFunction_74` (`TextCameraSpeedValue.SetText`) → `CallFunction_73` (`SpinBoxSexDuration.SetValue(NewValue ← VariableGet_53)`, `self ← VariableGet_49`, pos 1650,1000) → **`CallFunction_1278` (UpdateDonors)** → `CallFunction_7` (Delay) → `IfThenElse_2` … - **Point d'insertion STF** : couper `CallFunction_73.then → CallFunction_1278.execute`, insérer les 12 `SetValue` chaînés, rebrancher le dernier sur `CallFunction_1278`. Modèle de nœud : `CallFunction_73` (`Comportement|SetValue` de SpinBox, broche valeur **`NewValue`** ; celle du slider s'appelle `InValue`). ## 3. Widgets (établi, `GetWidgets`, `GetWidgetDescription`, `get_properties`) Chaque SpinBox est l'enfant **d'indice 1** d'une `HorizontalBox` dont l'enfant 0 est son libellé ; `bIsVariable` vrai, aucun composant d'interface. | SpinBox | Parent | Slot | Propriétés non par défaut (`GetWidgetDescription`) | |---|---|---|---| | ChildGrowthMult | HorizontalBox_8 | HorizontalBoxSlot_1 | Value 1 ; Min 0.01 / Max 10000 ; glisser 0.01-10000 | | ShadeDepth | HorizontalBox_6 | HorizontalBoxSlot_1 | Value 0.5 ; Max 1 ; glisser max 1 | | SpinBoxBGA | HorizontalBox_36 | HorizontalBoxSlot_1 | (Value 0) ; Max 5 ; glisser max 5 | | SpinBoxMarkerSize | HorizontalBox_30 | HorizontalBoxSlot_1 | Value 28 ; Min 1 / Max 100 ; glisser 1-100 | | SpinBoxMoan | HorizontalBox_39 | HorizontalBoxSlot_1 | (Value 0) ; Max 5 ; glisser max 5 | | SpinBoxPhysicsMult | HorizontalBox_33 | HorizontalBoxSlot_1 | Value 1 ; Max 100 ; glisser max 100 | | SpinBoxSceneFrequency | HorizontalBox_3 | HorizontalBoxSlot_1 | (Value 0) ; Min 0.2 / Max 100 ; glisser 0.2-100 | | SpinBoxSexDescription | HorizontalBox_2 | HorizontalBoxSlot_1 | Value 15 ; Min 1 / Max 100 ; glisser 1-100 | | SpinBoxSex | HorizontalBox_38 | HorizontalBoxSlot_1 | (Value 0) ; Max 5 ; glisser max 5 | | SpinBoxSquirtMult | HorizontalBox_42 | HorizontalBoxSlot_1 | (Value 0) ; Max 100 ; glisser max 100 | | SpinBoxUI | HorizontalBox_37 | HorizontalBoxSlot_1 | (Value 0) ; Max 5 ; glisser max 5 | | SpinBoxPregnancyTerm | HorizontalBox_5 | HorizontalBoxSlot_1 | (Value 0) ; Min 0.01 / Max 3 ; glisser 0.01-3 | Communs aux 12 **et à `SpinBoxSexDuration` (STC)**, valeurs identiques : `Font.Size 20` ; les 4 `bOverride_Min/Max(Slider)Value` vrais ; `Delta 0`, `SliderExponent 1`, `Min/MaxFractionalDigits 1 / 6`, `MinDesiredWidth 0`, `Justification Left`, `KeyboardType Number`, `ClearKeyboardFocusOnCommit false`, `SelectAllTextOnCommit true`, `ForegroundColor` (0.4729, 0.4729, 0.4729, 1, Specified), `Visibility Visible`, `RenderOpacity 1` ; slot : `Size Automatic 1`, `Padding 0`, `HAlign_Fill`, `VAlign_Fill`. `WidgetStyle` absent des écarts (style par défaut), comme chez SpinBoxSexDuration. Conséquence : la recopie de la méthode A se limite à **Value (= défaut GI), Min/Max, MinSlider/MaxSlider, les 4 `bOverride_*`, Font.Size 20** ; le reste est par défaut ou commun (à recopier quand même par `get_properties` / `set_properties` du widget d'origine, puis relu contre ce tableau). Valeurs de conception (Value) différentes du défaut GI : BGA, Moan, Sex, UI (0 contre 0.5 / 1 / 1 / 1), SquirtMult (0 contre 2), SceneFrequency (0, bornée à 0.2, contre 10), PregnancyTerm (0, bornée à 0.01, contre 1) : sans effet après STF (`Construct` affiche GI), corrigées quand même (SPEC § 1.1 : Value = défaut GI). ## 4. Liaisons (`Bindings`) - `ObjectTools.list_properties` sur `/Game/UI/MainMenu.MainMenu` renvoie les propriétés de la classe générée (`underwearVisible`…), pas le tableau `Bindings` du `UWidgetBlueprint` (établi, T0 confirmé). - Relecture binaire du `.uasset` (lecture seule, chaînes terminées par NUL) : chacun des 12 noms paraît **7 fois**, les widgets STC sans liaison (`SpinBoxSexDuration`, `SliderCameraSpeed`) **5 fois** ; `SpinBox_0` (liaison Function) 6. Écart de 2 = une entrée `FDelegateEditorBinding` + une `FDelegateRuntimeBinding` par widget lié (**estimé** : décompte de chaînes, pas d'analyse de la structure). Attendu après STF : 12 nouveaux noms à 5, anciens noms à 0. ## 5. Choix de méthode : **A** (établi) - `UMGToolSet` (24 outils relevés) n'a aucun outil qui écrive le tableau `Bindings` ; `ObjectTools` ne l'atteint pas (§ 4) ; `MVVMToolset` traite les liaisons de modèle de vue, pas les liaisons de propriété (hors sujet). Méthode B non démontrée → **méthode A** (SPEC § 1.1), modèle STC : `RemoveWidget` puis `AddWidget` (SpinBox, même parent, indice 1), **jamais `ReplaceWidgetWithTemplate`** (conserve les liaisons, STC-T5 § 1). - Noms neufs : tableau de STF-SPEC § 1.1, inchangé. - Ordre par couple (T3) : lire les propriétés de l'ancien widget → supprimer ses nœuds d'événement (`OnValueChanged`, plus `ComponentBoundEvent_15` pour MarkerSize) et ceux qui ne servent qu'à lui → `RemoveWidget` → `AddWidget` → propriétés et slot → `ToggleWidgetAsVariable` si besoin → `BindToEventProperty` `OnValueCommitted` (ou création de nœud) → chaîne `IsValid` → `Set` (+ suite propre au couple) → relecture → compilation. - Nœuds GI partagés : `VariableGet_29` (1, 4, 6) et `VariableGet_1` (3, 5, 9, 11) restent tant qu'un couple non traité s'en sert ; supprimés avec le dernier couple qui les utilise (aucune autre sortie relevée). ## 6. Écarts à la SPEC, points pour T3 1. Aucun écart sur les 12 chaînes ni sur `Construct` (SPEC exécutable telle quelle). 2. `SetValue` de SpinBox : broche **`NewValue`** (pas `InValue`). 3. Constat STC-T5 § 3 (hors périmètre, rappelé pour J1) : un réglage changé à l'écran titre n'est conservé au lancement suivant que si une sauvegarde l'a écrit dans `GameSettings.sav` (seuls `SceneFrequency`, `SexLineDuration` y sont). 4. Démarrage de l'éditeur : `Start-HyperAIStudioEditor.ps1` reste à corriger (guillemets), hors lot. Fichiers écrits : ce livrable seulement. Aucun fichier de la copie UE modifié (MD5 ci-dessus).