LifePlay-Revival/Docs/Migration/etat/ST/STF/STF-SPEC.md

106 lines
9 KiB
Markdown
Raw Normal View History

Fiche STF-T2 — Niveau N2 — Modèle prévu orchestrateur STF (Opus 5.5) | utilisé claude-opus-5-5 — Agent orchestrateur — Skills lp-lot, lp-mcp, sk-change-safety, sk-protocol
# STF-SPEC : protéger les 12 autres SpinBox de MainMenu (liaison retirée, init dans Construct, écriture sur commit) (2026-10-10)
Copie `D:\Game\LifePlay-master 5.8` (branche `ue5.8`). Entrées : décision utilisateur du 2026-10-10 (« 3 dans un lot
séparé », `STC-TACHES.md`), conception approuvée « 4 approuvé » (`STC-reponse-fable.md` § 4.3-4.4), `STC-SPEC.md` § 3.2
(modèle : durée des scènes), `STF-T0-CART.md`. **Exécutable seulement après la clôture de STC** (gel levé, MainMenu
modifié et commité par STC) : les numéros de nœuds et la chaîne `Construct` sont alors relus (STF-T1).
## 0. Cadre
| # | Règle | Source |
|---|---|---|
| C1 | Même correction mécanique que la durée des scènes, pour les 12 couples de `STF-T0-CART.md` § 1 | tâche, conception § 4.4 |
| C2 | Bornes Min / Max inchangées (aucun `Max < Min` sur les 12) | STC-T0 |
| C3 | `SpinBox_0` (flou de champ CharGen), caméra, durée : hors périmètre | tâche |
| C4 | Comportement inchangé à la validation d'une valeur ; seul l'instant d'écriture change (fin de geste au lieu de chaque pas) | conception § 4.3 |
## 1. Pour chacune des 12 SpinBox (ordre du tableau T0 § 1)
1. **Retirer la liaison** `Value ← GI.<variable>` :
- méthode A (modèle STC, par défaut) : remplacer le widget par une SpinBox neuve, au même créneau du même parent, toutes
propriétés recopiées depuis `UMGToolSet.GetWidgets` / `ObjectTools.get_properties` (style, police, couleur,
`Delta`, `MinFractionalDigits` / `MaxFractionalDigits`, `MinValue` / `MaxValue`, `MinSliderValue` / `MaxSliderValue`,
`bOverride_*`, `Value` = défaut GI, slot : taille, alignement, remplissage, marge), cochée « variable » ; noms :
| Ancien | Neuf |
|---|---|
| ChildGrowthMult | SpinBoxChildGrowth |
| ShadeDepth | SpinBoxShadeDepth |
| SpinBoxBGA | SpinBoxVolBGA |
| SpinBoxMarkerSize | SpinBoxMapMarkerSize |
| SpinBoxMoan | SpinBoxVolMoan |
| SpinBoxPhysicsMult | SpinBoxPhysics |
| SpinBoxSceneFrequency | SpinBoxSceneFreq |
| SpinBoxSexDescription | SpinBoxSexLineDuration |
| SpinBoxSex | SpinBoxVolSex |
| SpinBoxSquirtMult | SpinBoxSquirt |
| SpinBoxUI | SpinBoxVolUI |
| SpinBoxPregnancyTerm | SpinBoxPregnancyMult |
- méthode B (seulement si STF-T1 démontre une écriture du tableau `Bindings` du `UWidgetBlueprint` par un outil Epic) :
retirer les 12 entrées des deux tableaux (éditeur et exécution), noms et événements gardés. Sinon, méthode A.
2. **Écriture GI sur commit** :
- A : supprimer l'événement `OnValueChanged` de l'ancien widget ; créer `OnValueCommitted(<neuf>)` → `IsValid(GI)` →
`Set GI.<variable> = Value`, plus la suite propre au couple (§ 2). Aucun gestionnaire `OnValueChanged`.
- B : créer `OnValueCommitted(<widget>)`, y déplacer la chaîne existante (exécution et `InValue`), supprimer l'événement
`OnValueChanged`.
- Nœuds `GI` partagés (VariableGet_29, VariableGet_1) : ne couper que les liens du couple traité.
3. **Initialisation** : dans `Construct`, après la chaîne STC (`SetValue` caméra / durée), avant `UpdateDonors` :
`<widget>.SetValue(GI.<variable>)`, 12 appels chaînés (même ordre que le tableau). `SetValue` UMG émet `OnValueChanged`
seulement, sans gestionnaire après l'étape 2 (`SSpinBox.cpp:722-727, 1053-1058`).
## 2. Cas particuliers
- **SpinBoxMarkerSize** : `OnValueCommitted` existe déjà (événement 15, `RetriggerableDelay 2 s` → `SpawnMapMarkers`).
B : y insérer `IsValid(GI)` → `Set GI.MarkerSize = Value` en tête, puis la chaîne existante. A : le nouvel
`OnValueCommitted` porte `IsValid` → `Set` → `RetriggerableDelay 2 s` → `GI.SpawnMapMarkers(false)` (chaîne recopiée),
l'ancien événement 15 supprimé avec l'ancien widget.
- **ShadeDepth** : la chaîne `Cast MID` du `PostProcessVolume` → `SetScalarParameterValue('ShadeDepth')` suit le `Set`
sur `OnValueCommitted` (aperçu pendant le glisser perdu, application en fin de geste ; C4).
- **SquirtMult** : ajout de `IsValid(GI)` devant le `Set` (absent aujourd'hui) ; état vide impossible après `Construct`,
garde d'uniformité, écrite au CHG (règle 4 `lp-mcp`).
## 3. Contrôles de l'asset (après chaque SpinBox, puis à la fin)
- `get_node_infos` sur chaque nœud créé ; `compile_blueprint` + `hyper_blueprint_debug_inspect` : 0 diagnostic.
- Fin : `find_nodes` « OnValueChanged » sur MainMenu : seuls restent ceux hors périmètre (aucun pour les 12 ni pour
caméra / durée) ; 13 `OnValueCommitted` attendus (12 + `SpinBox_0`) en plus de ceux de STC.
- Relecture binaire des tableaux `Bindings` (méthode du diagnostic § 1.1) : 0 entrée vers `GI.<variable>` pour les 12 ;
seule liaison SpinBox restante : `SpinBox_0` (Function).
- `save_assets ["/Game/UI/MainMenu"]`, puis `CompileAllBlueprints` éditeur fermé (référence 418 / 418, 0 / 0).
## 4. Ordre, sécurité, traces
1. Entrée : STC clos (CHG et commit STC faits, gel levé annoncé) ; `git status --short -- Content/UI/MainMenu.uasset` vide.
2. Gel de la copie 5.8 annoncé à toutes les sessions actives (`ListAgents`) ; ticket `TAG` `STF-avant` au gardien.
3. `.\Tools\Snapshot.ps1 -Lot STF -Path Content\UI\MainMenu.uasset, Saved\SaveGames\GameSettings.sav, Saved\SaveGames\Default.sav`.
4. STF-T1 (relevés § 4 de T0, choix A / B) ; écart au T0 → arrêt et mise à jour de cette SPEC.
5. IMPL par MCP, un couple à la fois (§ 1-2), relecture et compilation à chaque couple ; puis `Construct` (§ 1.3).
6. VAL (lp-validator, agent distinct) § 5 ; preuve en jeu par l'utilisateur (archive Development).
7. DOC : une entrée CHG par SpinBox (12) + une pour `Construct` si le gardien la sépare ; ticket `COMMIT` (un commit de
lot, sans push) ; fin de gel annoncée.
## 5. Critères de VAL et de preuve
| # | Contrôle | Attendu |
|---|---|---|
| V1 | Compilation MainMenu, `CompileAllBlueprints` | 0 erreur, 0 avertissement ; 418 / 418 |
| V2 | Liaisons (`Bindings`, relecture binaire) | 0 liaison Property vers GI sur les 12 |
| V3 | Gestionnaires | aucune écriture GI depuis un `OnValueChanged` des 12 ; chacune part d'un `OnValueCommitted` |
| V4 | PIE M0-M6 (`STC-reponse-fable.md` § 3.2) | 0 écart sur les 14 variables de GI |
| V5 | PIE : une valeur tapée (+ Entrée) dans chacun des 12 champs, dans les bornes et ≠ défaut | `GI.<variable>` = valeur tapée ; menu fermé puis rouvert : champ = valeur, GI inchangé |
| V6 | PIE : glisser sur un champ (ex. SceneFreq) | GI mis à jour en fin de geste, affichage fluide pendant le glisser |
| V7 | MarkerSize | `GI.MarkerSize` = valeur, `SpawnMapMarkers` toujours appelé 2 s après |
| V8 | Fichiers | `GameSettings.sav` / `Default.sav` à MD5 de l'instantané sauf sauvegarde de partie volontaire |
| J1 | Preuve en jeu (utilisateur, archive Development) | les 12 réglages se règlent et survivent à fermeture / réouverture du menu ; `SceneFrequency` et `SexLineDuration` (seuls des 12 présents dans `GameSettings.sav`, `STB-SET-INV.md` § 2-3) survivent aussi à une sauvegarde puis un relancement ; les 10 autres reviennent au défaut de GI à chaque lancement (non persistés, estimé STB-SET § 3 : comportement d'origine, hors périmètre) |
## 6. Risques
- Méthode A : 12 widgets à recopier fidèlement (risque d'oubli de style ou de créneau) → relecture propriété par
propriété contre le relevé STF-T1, capture du panneau avant / après.
- Liaisons orphelines après remplacement : traitées comme en STC (STC-SPEC § 7).
- Valeur de GI hors bornes (sauvegarde ancienne, mod) : `SetValue` l'affiche bornée sans écrire GI ; elle n'est réécrite
que si le joueur valide le champ (comportement voulu, à noter au CHG).
## 7. Écarts constatés à l'exécution (ajout du 2026-10-10, après acceptation)
| # | Écart | Décision / source | Effet sur les critères |
|---|---|---|---|
| E1 | § 1.2 (A) : chaînes `IsValid → Set` existantes gardées et rebranchées sur le nouvel `OnValueCommitted` au lieu d'être recréées | orchestrateur, STF-T3-IMPL § 1 | aucun (graphe d'exécution identique ; VAL statique) |
| E2 | § 2 SquirtMult : garde `IsValid` (fonction) + `Branche` au lieu de la macro `IsValid` (type ambigu dans `find_node_types`) | orchestrateur, STF-T3-IMPL § 2 | aucun |
| E3 | **Arrondi entier** (T3b) : `SpinBoxSceneFreq`, `SpinBoxMapMarkerSize`, `SpinBoxSexLineDuration` : `Delta` 1, `bAlwaysUsesDeltaSnap`, 0 décimale ; SceneFreq **Min / MinSlider 0.2 → 1** (dérogation à C2 et C4 pour ces 3 champs) | **utilisateur** pendant le PIE (« il faudrait arrondir à l'entier » ; « Dans STF, après le PIE » ; « Minimum 1 ») ; accord Big Boss | V5 : valeurs tapées non entières arrondies (33.6 → 34), 0 → 1 sur SceneFreq ; STF-T4-PIE § 4 |
| E4 | § 5 J1 : `LoadSettings` recharge 9 des 12 réglages depuis `GameSettings.sav`, pas 2 | constat STF-T4-PIE § 2 (comportement d'origine) | J1 : 9 réglages persistés seulement après `SaveSettings`, 3 jamais persistés |