Fiche SET1-PRE — Niveau N2 — Modèle prévu non précisé par la fiche | utilisé claude-sonnet-5-5 — Agent lp-cart — Skills sk-protocol, ue-cpp-build, lp-commandlets, lp-paths # SET1-PRE : étude préliminaire, remplacer « l'ancien panneau settings du menu du jeu » par celui du menu principal (2026-10-20) Hors gabarit : étude préliminaire (pas une CART complète), sur le modèle de `FIX1-F6-PRE.md`. Les six rubriques du gabarit CART sont gardées ; la rubrique 3 suit les cinq questions de la fiche. Lecture seule : ni copie UE, ni MCP, ni éditeur, ni commandlet. Seul ce fichier est écrit. Contenu adulte (doc 27) : noms techniques de widgets seulement, aucun libellé d'interface. ## Résumé (à lire en premier) 1. **Le dépôt ne contient pas deux panneaux de réglages.** Un seul asset porte la liste des réglages : `Content/UI/MainMenu.uasset` (`SettingsScrollBox`). Aucun autre widget n'en contient (rubrique 2, commandes 6 et 7). Le « nouveau panneau » (onglets General, Audio, Video, Keyboard, Lewd, Misc) n'est **pas un autre widget** : c'est la même liste, dont le C++ montre ou cache les lignes par onglet (`LPSettingsSubsystem.h:1-6`, établi). 2. **`MainMenu_C` sert à la fois d'écran titre et de menu en partie** (boutons de partie et de titre dans le même widget, liaisons `OnlyVisibleForTitleScreen` / `ColapsedForTitleScreen`, `LPTitleModManagerCommandlet.h:4-9`). Seul le **bouton** « Settings » de l'écran titre est ajouté par le C++ (`LPSettingsSubsystem.cpp:571-762`, visible seulement sur l'écran titre, l. 757-761). En partie, le bouton d'origine ouvre la même liste, et les onglets s'y posent tout seuls (`Tick`, l. 498-561 : estimé). 3. **La prémisse « ancien ≠ nouveau » n'est donc pas confirmée.** Désactiver « l'ancien panneau » reviendrait à désactiver **le seul panneau existant**, titre compris. Ce qui peut exister, et que ce dépôt ne prouve pas : un défaut d'affichage en partie (hypothèse H1, rubrique 3.3) que seul un essai en jeu tranche. 4. **Recommandation** : ne pas ouvrir d'IMPL. Build 1 : un essai en jeu à trois captures (0 code), puis, **seulement si H1 est confirmée**, un correctif C++ d'un fichier (0 Blueprint, 0 GI). La réécriture complète du module en C++ que vise le doc 37 § 2.4 est un lot de **build 2** (rubrique 3.5). 5. **Question bloquante pour l'utilisateur** : que voit-il, en partie, qui diffère du menu principal ? Une capture de chaque panneau lèverait le doute (rubrique 6, Q1). ## 1. Objet et périmètre Un domaine : les panneaux de réglages (écran titre et menu en partie). Demande de l'utilisateur, citée dans `BOSS-JOURNAL.md:1030` (2026-10-20 21:04) : « non je souhaite passer la désactivation de l ancien panneau settings du menu du jeu et le remplacer par celui du menu principal. » Référence : `Docs/37_Feuille_De_Route_Alpha2.md:125-128` (§ 2.4 Dépréciation). Hors périmètre : le contenu des réglages (valeurs, textes), la correction de quoi que ce soit, le Mod Manager (widget distinct `UI/ModManager`). Copie lue : `D:\Game\LifePlay-master 5.8`, branche `ue5.8`, HEAD `ad3c9c6`. `LPCameraModeSubsystem.cpp` et `LPDirectControlSubsystem.cpp` portent des modifications non commitées (statut git de départ) : leurs numéros de ligne peuvent bouger. `Content/UI/MainMenu.uasset` est propre (`git status --short` vide) ; dernier commit `d15ffaa` (DISC1, 2026-10-20). ## 2. Commandes et lectures (exactes) avec compte brut | # | Commande ou lecture | Résultat brut | |---|---|---| | 1 | Read `Docs/37_Feuille_De_Route_Alpha2.md:95-198` ; Grep `2\.4\|Dépréciation` | § 2.4 l. 125-128 ; le tableau des lots (l. 161-172) **n'a pas de ligne SET1** | | 2 | Read `LPSettingsSubsystem.h` (69 l.), `LPSettingsSubsystem.cpp:1-330, 470-896` (896 l.), `LPUserSettings.h` (60 l.) | cités en 3 | | 3 | `wc -l` sur 4 sources | `896 LPSettingsSubsystem.cpp`, `1537 LPKeyboardSubsystem.cpp`, `36 LPModSettingsLibrary.cpp`, `115 LPUserSettings.cpp` | | 4 | Glob `Content/**/*{ettings,ptions,Pause,Esc}*.uasset` | 4 fichiers : `Heavy/Daz/Clothes/DazDiffuseOptions`, `Heavy/New/settings` (texture), `BPs/GameSettings` (SaveGame), `FreeAnimationsPack/.../Mannequin_LODSettings` : **aucun widget** | | 5 | Glob `Content/UI/MainMenu/**/*.uasset` | `No files found` (pas de dossier ; `MainMenu` est un seul asset `Content/UI/MainMenu.uasset`, 2 245 771 o) | | 6 | `rg -a -l -e "SettingsScrollBox" -g "*.uasset" Content` | 1 fichier : `Content\UI\MainMenu.uasset` ; code de sortie 0 | | 7 | `rg -a -l -e "SettingCheckbox" -e "SettingSlider" -e "SettingsScrollBox" -e "GameSettings" -g "*.uasset" -g "*.umap" Content/UI Content/BPs Content/Maps` | 6 fichiers : `BPs/PC`, `BPs/GameSettings`, `BPs/GI`, `UI/MainMenu`, `UI/SettingSlider`, `UI/SettingCheckbox` (code 2 : `Content/Maps` n'existe pas ; la sortie est valide) | | 8 | `rg -a -c -e SettingsScrollBox -e MainMenuOptions -e SettingsButton -e MainMenuOn` sur `MainMenu`, `GI`, `PC`, `TopRight` | `MainMenu.uasset:15`, `PC.uasset:1`, `GI.uasset:1`, `TopRight` : aucune ligne | | 9 | `rg -a -o "[A-Za-z_]*(Button\|ScrollBox\|Settings\|Setting)[A-Za-z_0-9]*" MainMenu.uasset \| sort \| uniq -c` | boutons du même widget : `ResumeButton`, `SaveButton`, `LoadButton`, `ContinueButton`, `NewGameButton`, `NewGameTfButton`, `NewGameTutorialButton`, `InventoryButton`, `StatMenuButton`, `CharGenButton`, `CityMenuButton`, `BodyShapeButton`, `ModManagerButton`, `ModManagerTitleButton`, `SettingsButton`, `ExitButton`, `FAQButton`, `DonateButton`, `DiscordButton`, `BackButton`, `FullscreenButton` ; `SettingsScrollBox` ×5 ; `SettingCheckbox_C` et `SettingSlider_C` ×1 | | 10 | `rg -a -o "[A-Za-z_]*(TitleScreen\|OnlyVisibleFor\|ColapsedFor\|CollapsedFor)[A-Za-z_]*" MainMenu.uasset \| sort \| uniq -c` | `ColapsedForTitleScreen` 3 ; `OnlyVisibleForTitleScreen` 3 ; `TitleScreen` 1 | | 11 | `rg -a -o "[A-Za-z_]{0,30}Settings[A-Za-z_]{0,30}" PC.uasset` | `GameSettings`, `GameSettings_C`, `GameSettingsInstance`, `ConcurrencySettings`, `Settings` ×2 ; et (commande 12) `MainMenuOn`, `MainMenuInput`, `MainMenu`, `InpActEvt_MainMenu_K…`, `CloseMainMenu` | | 12 | `rg -a -o "(MainMenu\|Settings\|PauseMenu\|OptionsMenu)" PC.uasset` | cités ci-dessus ; aucun `PauseMenu` ni `OptionsMenu` | | 13 | Grep `SettingsScrollBox\|TitleScreen\|ModManagerTitleButton` dans `Source` | 5 sous-systèmes cherchent la liste par son nom : `LPSettingsSubsystem.cpp:506`, `LPColorGradeSubsystem.cpp:263`, `LPVideoQualitySubsystem.cpp:466`, `LPKeyboardSubsystem.cpp:854`, `LPModInfoSubsystem.cpp:246` ; plus `LPReadableTextSubsystem.cpp:125` (remonte les parents) | | 14 | Grep `MainMenu\|IsMenuOpen` dans `Source/LifePlay/*.cpp` | `MainMenu_C` est une classe de « menu ouvert » dans 4 listes : `LPDirectControlSubsystem.cpp:60`, `LPDebugSubsystem.cpp:436`, `LPOutdoorRoomSubsystem.cpp:52`, `LPCameraModeSubsystem.cpp:262` ; `LPCameraModeSubsystem.cpp:91, 1189-1192` (remise à faux de `GI.MainMenuOn`) ; `LPKeyboardSubsystem.cpp:819-822` | | 15 | Read `Docs/Migration/etat/ST/STB/dumps/MainMenu__EventGraph.txt:100-270` | `EventGraph` de MainMenu (398 nœuds) : Resume, CharGen, CityMenu, ModManager, Inventory, Exit, **Settings**, **Back**, StatMenu | | 16 | Read `…/CAM/CAM-B1-PRE_LPDumpFunction_20261013-083048.txt:5126-5185` | `EventGraph` de GI : événements `MainMenuInput`, `OpenMainMenu`, `CloseMainMenu`, `CreateMainMenuWidget` (CreateWidget, `AddToViewport`, variable `MainMenu`) | | 17 | Read `LPTitleModManagerCommandlet.h:1-30` | commentaire d'en-tête : l. 4-9 | | 18 | Journal du jeu `D:\Game\LifePlay_Build_5.8_Development_COM22\Windows\LifePlay\Saved\Logs\LifePlay.log` : `rg -n "Reglages : "` ; `rg -c "Reglages : (onglets\|entree)"` | 2 lignes (957 `entree Settings ajoutee sur l'ecran titre`, 958 `Settings place apres Mod Manager`) ; compte 1 ; **aucune ligne `Reglages : onglets`** : les réglages n'ont jamais été ouverts dans cette session | | 19 | Journal COMMUN-21 `…/BOSS/COMMUN-21/COMMUN-21_session_1927.log` : Grep `Reglages :` | 971 `entree`, 972 `place`, **1014 `onglets General, Audio, Video, Keyboard, Lewd, Misc`**, 2880 `entree`, 2881 `place` | | 20 | `rg -a -w -e <45 noms de lignes du dump 5.5 de MainMenu> Content/UI/MainMenu.uasset \| sort -u` | 32 noms retrouvés (liste en 3.2) ; 14 absents (3.2) | | 21 | `rg -a -c -e SaveSettings -e LoadSettings Content/BPs/GI.uasset` | `4` | | 22 | Grep `module de r[ée]glages\|panneau (général\|…)\|nouveau panneau\|menu général` dans `Docs/[0-9]*.md` | seul résultat utile : `37_…md:127-128` ; aucune définition de « l'ancien module de réglages » ailleurs | Écart de méthode : le dump des widgets de MainMenu (`portage55/L6e/L6e-CX-B09_LPDumpWidgetTree_20260930-083639.txt`) date du 2026-09-30 (5.5). Il sert à nommer les lignes ; le décompte exact des lignes actuelles demande un `LPDumpWidgetTree` (copie UE, éditeur fermé). ## 3. Constats `fichier:ligne` ### 3.1 Le « nouveau panneau » : celui du menu principal (question 1) | Constat | Source | Niveau | |---|---|---| | Il **n'est pas un widget créé en C++ ni un Blueprint à part**. Le sous-système dit : « Les lignes existent déjà dans MainMenu.SettingsScrollBox (cases et curseurs du Blueprint). Ce sous-système ne les recrée pas : il les montre ou les cache selon l'onglet. […] Aucun Blueprint n'est modifié. » | `LPSettingsSubsystem.h:1-6` | établi | | Les onglets sont une `UHorizontalBox` nommée `LPSettingsTabs` ajoutée au `CanvasPanel` parent de la liste, 40 px au-dessus d'elle ; six boutons dont les clics appellent `ShowGeneral / ShowAudio / ShowVideo / ShowKeyboard / ShowLewd / ShowMisc` | `LPSettingsSubsystem.cpp:764-836` (liaison l. 790-817) ; noms des onglets l. 35-37 | établi | | Le classement d'une ligne dans un onglet se fait par **nom** (`NewAnimationsOnly` → General ; `ShowFPS`, `ScreenPercentage`, `FullscreenButton`, `ToonShading`, `Censore`, `CPUSkinning`, `DisableFurEffect`, `LPColor*`, `LPVideo*` → Video ; `LPModCheck*` → Misc), puis par **mots-clés du libellé**, sinon Misc. `ShadowQuality`, `PostProcessQuality`, `PostProcessAAQuality` sont repliés (remplacés par les lignes `LPVideo*`). `BackButton` est toujours visible | `LPSettingsSubsystem.cpp:145-212` | établi | | L'onglet Keyboard est une page Slate native (`UNativeWidgetHost` nommé `LPSettingsKeyboard`) fournie par `ULPKeyboardSubsystem::TakeEmbeddedPage()`, placée sous la barre d'onglets | `LPSettingsSubsystem.cpp:821-832, 877-888` | établi | | Ouverture depuis l'écran titre : bouton `LPSettingsTitleButton` créé en C++ dans la boîte `MainMenuOptions`, placé après `ModManagerTitleButton` ; son clic appelle `OpenSettings`, qui **diffuse `OnClicked` du bouton d'origine `SettingsButton`** (Blueprint) | `LPSettingsSubsystem.cpp:563-569, 571-690` | établi | | Le Blueprint d'origine, sur clic de `SettingsButton` : cache `MainMenuOptions`, montre `SettingsScrollBox` ; `BackButton` fait l'inverse | `MainMenu__EventGraph.txt:222-259` (`SetVisibility` Hidden / Visible) | établi | | Le bouton C++ prend la visibilité de `ModManagerTitleButton` (`Ours->SetVisibility(TitleVisibility)`) ; ce dernier n'est visible que sur l'écran titre (liaison `OnlyVisibleForTitleScreen`) : **le bouton ajouté est donc propre à l'écran titre** | `LPSettingsSubsystem.cpp:757-761` ; `LPTitleModManagerCommandlet.h:6-9` | établi | | Les onglets et les réglages C++ sont posés par un `Tick` à chaque image, sur la **première** `SettingsScrollBox` trouvée par `TObjectIterator` dont le propriétaire partage le `GameInstance` (`break` l. 516). Rien dans la sélection ne distingue écran titre et partie | `LPSettingsSubsystem.cpp:498-561` | établi | | Les quatre autres sous-systèmes injectent leurs lignes dans la même liste, par le même nom | observations 13 | établi | **Peut-il s'ouvrir en cours de partie ?** Établi : le même widget `MainMenu_C` est celui du menu en partie (`LPTitleModManagerCommandlet.h:4-9` : « entrée "Mod Manager" du menu, masquée sur l'écran titre » ; boutons `ResumeButton`, `SaveButton`, `InventoryButton`… dans le même asset, observation 9 ; `GI.OpenMainMenu`, `MainMenuInput`, `CloseMainMenu`, `CreateMainMenuWidget`, observation 16). Les onglets s'y posent par construction (estimé, jamais observé en jeu : aucun journal ne montre `Reglages : onglets` après un lancement de partie ; observations 18-19). | Point demandé | Établi | Inconnu | |---|---|---| | Entrée | touche → `PC.InpActEvt_MainMenu_K…` → `GI.MainMenuInput` (chaînes de `PC.uasset`, observation 12 ; `GI` : `CAM-B1-PRE…txt:5128`) | le test `IfThenElse_6451` de `MainMenuInput` (ouvre ou ferme) | | Focus | `LPKeyboardSubsystem::IsMenuOpen` traite les réglages ouverts comme un menu (`MainMenu_C`) ; marche, caméra et relevage sont coupés | focus clavier ou manette dans la liste : non lu | | Retour | `BackButton` (panneau → options) ; `CloseSelf` → `GI.CloseMainMenu` (`MainMenuOn` = faux) (`MainMenu__EventGraph.txt:144-150`, `CAM-B1-PRE…txt:5134-5150`) ; `KEY2-DIAG-01` : réglages fermés pendant une capture de touche → capture annulée (`LPSettingsSubsystem.cpp:528-541`) | — | | Pause du jeu pendant le menu | — | **inconnu** : `GI.MainMenuInput` n'a pas été lu jusqu'au bout ; la ligne `AutoPause` est un réglage, pas la pause du menu | ### 3.2 L'« ancien panneau » : celui du menu en partie (question 2) **Constat central (établi, négatif)** : aucun autre widget de réglages. Observations 4 à 8 : un seul asset contient `SettingsScrollBox` (`MainMenu`) ; `SettingCheckbox` et `SettingSlider` ne sont référencés que par `MainMenu` (et eux-mêmes) ; `TopRight` ne contient rien ; `PC` et `GI` ne citent que `GameSettings` (le SaveGame) et les événements de menu. **Le menu de pause et le menu d'options en partie sont le même widget `MainMenu`**. Il n'existe pas de classe `PauseMenu` ni `OptionsMenu` (observation 12). *Limite* : ce relevé couvre `Content/UI`, `Content/BPs`, `Content` (Glob) ; un widget créé dynamiquement par C++ n'aurait pas de nom de ce type, mais aucun `CreateWidget` de réglages n'existe dans `Source` (Grep n° 13 : seuls les cinq sous-systèmes ci-dessus touchent la liste, par recherche d'objet, pas par création). **Ce que l'ancien panneau porte** (lignes nommées, relevé 2026-09-30 de `L6e-CX-B09_LPDumpWidgetTree`, recontrôlé dans le binaire 5.8 par `rg -a -w`) : 32 noms retrouvés dans `MainMenu.uasset` : `24Hour`, `AiOnlySuggests`, `AllowHomeDye`, `AutoPause`, `BodyChange`, `CPUSkinning`, `Censore`, `Difficulty`, `DisableFurEffect`, `DisableTrans`, `FullscreenButton`, `NPCsRespectPlayerSex`, `NameToRelation`, `NewAnimationsOnly`, `NoActionTimeout`, `NoAnimConditions`, `NoForcedCondom`, `NoTransPreg`, `OldFilter`, `PostProcessAAQuality`, `PostProcessQuality`, `PregnancyNotification`, `PreventClothChanges`, `ScreenPercentage`, `ShadeDepth`, `ShadowQuality`, `ShowFPS`, `ShowUnknownBuildings`, `SpinBoxDOF`, `ToonShading`, `TutorialCompleted`, `UnderwearVisible`. 14 noms du dump 5.5 **non retrouvés** par `rg -a -w` : `ChildGrowthMult`, `SpinBoxBGA`, `SpinBoxCameraSpeed`, `SpinBoxMarkerSize`, `SpinBoxMoan`, `SpinBoxPhysicsMult`, `SpinBoxPregnancyTerm`, `SpinBoxSceneFrequency`, `SpinBoxSex`, `SpinBoxSexDescription`, `SpinBoxSexDurationMultiplier`, `SpinBoxSquirtMult`, `SpinBoxUI`, `SpinBox_0`. `SpinBox_0` est expliqué : remplacé par `SpinBoxDOF` (commit `547dcdd`, STF-T5 a). Pour les 13 autres, la cause n'est **pas établie** (renommage, ou nom enfoui dans une chaîne plus longue que le motif `-w` rejette). Ces lignes existent : `LISIB-T1-CART.md:76` compte 15 `SpinBox` dans `SettingsScrollBox`, et `2883b80` en protège 12. La liste exacte des réglages de partie, un par un, demande donc un `LPDumpWidgetTree -BP=MainMenu` (éditeur fermé, copie UE) : **inconnu**. Lignes ajoutées par le C++ dans la même liste : `LPColor*` (`LPColorGradeSubsystem`), `LPVideo*` (`LPVideoQualitySubsystem`), `LPModCheck*` (3 cases de contrôle des mods, `LPModInfoSubsystem.h:16`), `LPKeyboardRow` (repliée, `LPSettingsSubsystem.cpp:862-868`), page Keyboard. **Qui écrit ces réglages** | Réglage | Écrit par | Support | Source | Niveau | |---|---|---|---|---| | Lignes Blueprint (cases, curseurs) | `GI.SaveSettings` / `GI.LoadSettings` (liaisons `Value ← GI` retirées, écriture sur `OnValueCommitted`, init dans `Construct`) | `GameSettings.sav` (SaveGame `Content/BPs/GameSettings`), dossier `…\Saved\SaveGames` | `rg -a -c` sur GI = 4 ; `STC-SPEC.md` ; commit `2883b80` (message) ; `Registre_Erreurs.md:49` (cité par `FIX1-F6-PRE.md:46`) | établi pour le principe ; **liste des champs de `GameSettings` : inconnue** (extraction vide, non relevée) | | Vitesse de caméra | `ULPUserSettingsLibrary::SetCameraSpeed` ; recopie dans `GI.CameraSpeed` | `GameUserSettings.ini`, section `/Script/LifePlay.LPUserSettings`, 1 à 7, 3 par défaut ; `GameSettings.sav` garde une recopie | `LPUserSettings.h:1-9, 19-27, 52-54` | établi | | Touches | `ULPKeyboardSubsystem` | `Saved/Config/Windows/LPKeyboard.ini` ; journal COM22 l. 879-880 : `Clavier : …LPKeyboard.ini absent, creation avec les touches actuelles` puis `51 actions et 17 axes enregistres` | `LifePlay.log` (COM22) | établi | | Couleur, qualité vidéo | `LPColorGradeSubsystem`, `LPVideoQualitySubsystem` | fichiers `LP*.ini` de `Saved/Config` | repris de `FIX1-F6-PRE.md:62` (`LPColorGradeSubsystem.cpp:27`, `LPVideoQualitySubsystem.cpp:71`), non relu ici | estimé | | Choix des mods | `ULPModSettingsLibrary::SaveModSelection` | `GameSettings.sav` (`ModEnableds`) | `UA-MODS.md:130` ; `LPModSettingsLibrary.cpp:34` | établi (par citation) | Bouton qui ouvre : le bouton `SettingsButton` du menu en partie (Blueprint, `MainMenu__EventGraph.txt:222`) ; sur l'écran titre, `LPSettingsTitleButton` (C++) qui diffuse le même événement. Aucun autre point d'entrée de réglages n'est apparu (PC, TopRight, GI : aucune création de widget de réglages). ### 3.3 Écart fonctionnel et hypothèses (question 3) **Écart par construction : nul.** Les deux « panneaux » sont une seule liste de lignes. Il n'existe pas de réglage « seulement dans l'ancien » au sens d'un second asset, ni de réglage de partie absent du nouveau : les lignes de partie (`Difficulty`, `NoActionTimeout`, `AutoPause`, `24Hour`, `TutorialCompleted`…) **sont** celles du « nouveau ». Seuls ajouts du C++ (« seulement dans le nouveau », mais dans la même liste, donc visibles en partie si les onglets s'y posent) : page Keyboard, lignes `LPColor*` / `LPVideo*` / `LPModCheck*`, vitesse de caméra adossée à l'ini. **Risque de perte si « l'ancien » est désactivé** (établi par construction) : désactiver `MainMenu.SettingsScrollBox` ou `SettingsButton` retire **tous** les réglages, titre compris, et casse cinq sous-systèmes qui cherchent la liste par son nom (observation 13) et `ULPKeyboardSubsystem::IsMenuOpen`. Désactiver seulement `SettingsButton` en partie retire l'accès aux réglages en partie, sans remplaçant. **Hypothèses sur ce que l'utilisateur voit** (aucune n'est établie ; un essai en jeu les départage) : | # | Hypothèse | Mécanisme (code lu) | Niveau | Essai qui tranche | |---|---|---|---|---| | H1 | En partie, la liste n'a **pas les onglets** (ou affiche seulement les lignes de General) | `GI.CreateMainMenuWidget` crée un `MainMenu` (CreateWidget + `AddToViewport`, `CAM-B1-PRE…txt:5171-5185`). Le `Tick` prend la **première** `SettingsScrollBox` du `GameInstance` (`LPSettingsSubsystem.cpp:516`) et `EnsureTabs` sort si `TabBar` est encore valide (l. 766-769). Si l'instance de l'écran titre n'est pas encore collectée quand la partie crée la sienne, la barre d'onglets reste celle de l'ancienne instance, et `ApplyRows` filtre la nouvelle liste sans barre pour changer d'onglet | estimé (la création à chaque ouverture et le délai de collecte ne sont pas lus) | écran titre → Settings → Back → nouvelle partie ou Continuer → Échap → Settings : la barre d'onglets est-elle là ? Journal : une ligne `Reglages : onglets` après le lancement de partie | | H2 | L'utilisateur parle d'un écart **visuel** (arrière-plan, taille) entre titre et partie, pas fonctionnel | même widget, mais le fond de la scène 3D change | incertain | deux captures côte à côte | | H3 | « L'ancien module de réglages » du doc 37 désigne la **logique Blueprint** (`GI.LoadSettings` / `SaveSettings`, `GameSettings.sav`) à remplacer par du C++ (modèle `ULPUserSettings`) | `37_…md:127` ne définit pas le terme ; aucun autre doc ne le définit (observation 22) | incertain | question à l'utilisateur (Q2) | ### 3.4 Voies possibles (question 4) Précision : comme les deux panneaux sont un seul widget, la voie (a) de la fiche (« rediriger le bouton ») n'a **rien à rediriger** : le bouton d'origine ouvre déjà la liste que le C++ met en onglets. Les voies ci-dessous reprennent l'esprit de la demande. | Voie | Contenu | Fichiers et assets touchés | GI | Agent, niveau | Durée (estimée) | Risques | Preuve en jeu | |---|---|---|---|---|---|---|---| | **V0. Vérifier, sans code** | essai en jeu à trois captures, avec la build COM22 ou la suivante | aucun | non | Big Boss, utilisateur | 15 à 20 min | aucun | titre → Settings (onglets) ; partie → Échap → Settings (onglets ou non) ; journal : lignes `Reglages :` | | **V1. Corriger H1** (si V0 la confirme) | choisir la liste de l'instance **à l'écran** (`IsInViewport()`), reconstruire `TabBar` et `KeyboardHost` quand leur `Canvas` n'est plus celui de la liste | `Source/LifePlay/LPSettingsSubsystem.cpp` (≈ 15 à 40 lignes, estimé) ; 0 Blueprint | **non** | SPEC N2 ; IMPL `lp-impl` (Sonnet) ; BUILD `lp-builder` ; VAL `lp-validator` distinct | SPEC 8 à 12 tours, IMPL 10 à 15, VAL 10 à 15 ; essai sous jeton 30 min | `TObjectIterator` + durée de vie des widgets ; régression sur l'écran titre ; les quatre autres sous-systèmes ont le même motif de recherche (`ColorGrade:263`, `VideoQuality:466`, `Keyboard:854`, `ModInfo:246`) et pourraient avoir la même faille | idem V0 + redémarrage en partie, 2 allers-retours titre ↔ partie | | **V2. Réécriture C++ du module (doc 37 § 2.4 pris au pied de la lettre)** | nouveau panneau en C++ qui lit et écrit les réglages de partie (≈ 40 lignes) par réflexion sur `GI`, appelle `GI.SaveSettings` par `ProcessEvent`, remplace la liste ; `MainMenu.SettingsScrollBox` repliée et gardée « forkée » dans l'asset | nouveau `LPSettingsPanel.*`, retouche de `LPSettingsSubsystem.cpp` et des quatre autres sous-systèmes (leurs lignes migrent), `LPCameraModeSubsystem` / `LPDirectControlSubsystem` / `LPOutdoorRoomSubsystem` / `LPDebugSubsystem` si la classe `MainMenu_C` change | **non** si l'écriture passe par la réflexion (modèle `ApplyCameraSpeedAtStartup`, `LPUserSettings.h:44-54`) ; **oui** si le Blueprint doit appeler le C++ | SPEC N3 (opus) ; IMPL `lp-impl-max` ; BUILD ; VAL ; essai long | 2 à 3 jours, répartis sur au moins 2 créneaux de la copie UE | perte de réglages joueurs (champs de `GameSettings` non listés), `Construct` de `MainMenu` qui initialise les widgets de la liste, 14 lignes non identifiées, listes `MainMenu_C` des quatre sous-systèmes | partie complète : tous les réglages, Continuer, redémarrage, comparaison de `GameSettings.sav` avant et après | | **V3. Modifier `MainMenu` par MCP** | recâbler `SettingsButton` ou masquer la liste | `Content/UI/MainMenu.uasset` (`lp-mcp-bp`, instantané, jeton) | non | `lp-mcp-bp` N2 | 1 créneau | **non recommandée** : aucun gain (l'ouverture est déjà commune), asset partagé avec l'écran titre et avec DISC1, et la liste est cherchée par nom par cinq sous-systèmes | — | **GI.uasset** (révisé une seule fois, en build 2, règle citée par la fiche et par `FIX1-F6-PRE.md:107-108`) : V0, V1 et V3 ne le touchent pas ; V2 ne le touche pas si l'écriture passe par la réflexion (estimé). ### 3.5 Recommandation (question 5) - **Build 1 : V0 seulement, puis V1 si H1 est confirmée.** Justification : (i) la prémisse « deux panneaux » n'est pas établie ; ouvrir une IMPL sur une prémisse non vérifiée est le pire coût possible avec un gel au 24 ; (ii) V0 ne coûte aucun jeton de copie UE (build COM22, estimé) ; (iii) la file de la copie UE est pleine (`37_…md:179-185` : STM1, CG2, CAM2, FIX1 le J3, KEY2 le J4, REL2 le J5) ; V1 serait un créneau de plus, à placer au J3 (voisin de FIX1) ou à écarter ; (iv) le doc 37 range la dépréciation en § 2 (« après l'alpha »), pas dans le tableau des lots de la build 1 (`37_…md:161-172` : pas de ligne SET1). - **Build 2 : V2** si l'utilisateur confirme qu'il veut une réécriture C++ du module (H3), avec SPEC N3 et liste exacte des champs de `GameSettings`. À grouper avec la révision unique de GI si un appel Blueprint devient nécessaire. - **Porte proposée pour V1** : si V0 montre les onglets absents en partie, SPEC le 2026-10-21, IMPL hors copie UE, essai au J3 ou J4 ; sinon V1 passe en build 2. Aucune décision n'est prise ici : elle revient à l'utilisateur. ## 4. Établi / estimé / incertain (synthèse) **Établi** : `MainMenu.uasset` est le seul asset portant `SettingsScrollBox` (observation 6) ; le « nouveau panneau » est cette liste montée en onglets par le C++ (`LPSettingsSubsystem.h:1-6`, `.cpp:764-889`) ; seul le bouton de l'écran titre est ajouté par le C++ et propre au titre (`.cpp:757-761`) ; le bouton `SettingsButton`, `Back` et le widget `MainMenu` servent titre et partie (observations 9, 10, 15, 17) ; cinq sous-systèmes injectent ou cherchent la liste par son nom (observation 13) ; `MainMenu_C` est compté « menu ouvert » dans quatre listes de classes (observation 14) ; `GI` porte `MainMenuInput`, `OpenMainMenu`, `CloseMainMenu`, `CreateMainMenuWidget` ; la vitesse de caméra vit dans `GameUserSettings.ini` ; `GI.SaveSettings` / `LoadSettings` existent dans l'asset (compte 4) ; le journal COM22 ne montre aucune ouverture des réglages (aucune ligne `onglets`). **Estimé** : les onglets s'appliquent aussi en partie (le `Tick` ne distingue pas) ; H1 (instance périmée) comme cause possible d'un écart ; V1 : 15 à 40 lignes ; V2 : 2 à 3 jours ; V0 réalisable sans jeton de copie UE ; V2 sans GI si réflexion. **Incertain, essai qui trancherait** : - Ce que l'utilisateur appelle « ancien panneau » : captures du titre et de la partie (V0). - Si `CreateMainMenuWidget` crée un widget neuf à chaque ouverture et quand l'ancien est collecté : lecture de `GI.OpenMainMenu` / `MainMenuInput` (`IfThenElse_6451`) et `LPDumpFunction -BP=GI`, ou le journal de V0. - Liste exacte des lignes actuelles de la liste (14 noms du dump 5.5 non retrouvés) : `LPDumpWidgetTree -BP=MainMenu`, éditeur fermé. - Champs de `GameSettings` (SaveGame) : `LPDumpSave` ou `LPDumpCDO` sur `GameSettings`, éditeur fermé. - Pause du jeu pendant le menu : lecture de `GI.MainMenuInput` en entier. - Sens de « forké » et de « release suivante » (doc 37 § 2.4). ## 5. Points à confirmer (repris par la fiche suivante) 1. Exécuter V0 (essai en jeu, trois captures + journal). 2. Si H1 : lire `GI.OpenMainMenu` / `MainMenuInput` / `CreateMainMenuWidget` et la fin de vie du widget (`RemoveFromParent`, `CloseSelf`). 3. Relever la liste des lignes de `MainMenu` (`LPDumpWidgetTree`, copie UE) et celle des champs de `GameSettings` (`LPDumpSave`) avant toute V2. 4. Relire `LPColorGradeSubsystem.cpp:27` et `LPVideoQualitySubsystem.cpp:71` (fichiers `.ini`), repris ici de `FIX1-F6-PRE.md:62`. 5. Vérifier si les quatre autres sous-systèmes partagent la faille H1 (même motif `TObjectIterator` + `break`). 6. Si V2 : relever les appels de `ULPKeyboardSubsystem::TakeEmbeddedPage` et le test `MenuOnScreen` (`LPKeyboardSubsystem.cpp:819-860`) pour ne pas casser KEY2. 7. Ajouter une ligne SET1 au tableau du doc 37 § 3.1 si l'utilisateur ouvre le lot (aujourd'hui absente). ## 6. Questions pour la SPEC ou l'utilisateur 1. **Q1 (bloquante)** : en partie, quel écran voyez-vous quand vous appuyez sur Échap puis sur Settings : les onglets General, Audio, Video, Keyboard, Lewd, Misc sont-ils présents ? Si non, une capture de chaque écran (titre, partie). 2. **Q2** : le doc 37 § 2.4 (« l'ancien module de réglages est forké et désactivé ; le menu redirige vers le nouveau panneau du menu général ») vise-t-il (i) un défaut d'affichage en partie, (ii) la réécriture du module de réglages en C++ (V2), ou (iii) autre chose ? Que signifie « forké » ? 3. **Q3** : « la release suivante » : laquelle (alpha 2.2a, ou après l'alpha) ? 4. **Q4** : accord pour l'essai V0 avec la build COM22, ou faut-il attendre la prochaine build ? 5. **Q5** : si H1 est confirmée, V1 en build 1 sous une porte au J4, ou directement en build 2 ? 6. **Q6** : V2 : périmètre (tous les réglages de partie, ou seulement l'affichage) et risque accepté sur `GameSettings.sav` ? ## Fichiers à commiter A `Docs/Migration/etat/REL/SET1/SET1-PRE.md` (dépôt du jeu, `.md` suivi sous `etat/`). Aucun autre fichier écrit. Tours : 24 / 25 (déclaré par l'agent ; `Tools/FicheStats.py` fait foi)