LifePlay-Revival/Docs/Migration/etat/REL/SET1/SET1-V1b-IMPL.md

398 lines
32 KiB
Markdown
Raw Normal View History

Fiche SET1-V1b — Niveau N2 — Modèle prévu Sonnet (fiche) | utilisé claude-sonnet-5-5 — Agent lp-impl — Skills sk-protocol, ue-cpp-build (préchargés en plus : lp-build, lp-ue-compat)
# SET1-V1b-IMPL : les lignes Couleur, Video et Mods se posent sur l'instance de MainMenu qui est à l'écran (2026-10-20)
Hors gabarit : la fiche demande, après les rubriques IMPL 1 à 6, la compilation, le diff, les MD5, les journaux et la preuve attendue en jeu (sections 7 à 12). Suite directe de `SET1-V1-IMPL.md` (§ 0 et § 8). Contenu adulte (doc 27) : noms techniques de widgets seulement.
Résultat : **réussi à la compilation** (éditeur et jeu : code 0, 0 erreur, 0 avertissement) ; **non éprouvé en jeu** (la preuve en jeu revient à la VAL, § 10). Les trois sous-systèmes choisissent maintenant la même liste que les onglets ; aucun état par instance à remettre à zéro n'a été trouvé chez eux (§ 2, constat C1).
## 1. Fichiers modifiés
| Fichier | Lignes (après modification) | Contenu |
|---|---|---|
| `Source/LifePlay/LPSettingsSubsystem.h` | 17 | `class UGameInstance;` (déclaration avancée) |
| idem | 50-55 | `static UScrollBox* FindOnScreenSettingsList(const UGameInstance* GI, const UScrollBox* Current = nullptr);` publique, avec son commentaire |
| `Source/LifePlay/LPSettingsSubsystem.cpp` | 592-596 | `ULPSettingsSubsystem::FindOnScreenSettingsList` : une ligne, renvoie `LPSettingsUi::FindOnScreenSettingsList(GI, Current)` (la fonction du `namespace LPSettingsUi`, `:122-146`, n'est pas touchée ; le `Tick` des onglets l'appelle comme avant) |
| `Source/LifePlay/LPColorGradeSubsystem.cpp` | 18 | `#include "LPSettingsSubsystem.h"` |
| idem | 260-264 | `EnsureControls` (commence l. 258) : la boucle « première `SettingsScrollBox` + `break` » (ancien 259-274) est remplacée par `ULPSettingsSubsystem::FindOnScreenSettingsList(GetGameInstance())` |
| idem | 313-314 | nouvelle ligne de journal `Couleur : reglages de couleur ajoutes sur <MainMenu_C_n>` (fin d'`EnsureControls`) |
| `Source/LifePlay/LPVideoQualitySubsystem.cpp` | 20 | `#include "LPSettingsSubsystem.h"` |
| idem | 463-467 | `EnsureControls` (commence l. 461) : même remplacement (ancien 462-477) |
| idem | 594-595 | journal `Video : controles ajoutes avant les reglages de couleur (sur <MainMenu_C_n>)` |
| `Source/LifePlay/LPModInfoSubsystem.cpp` | 21 | `#include "LPSettingsSubsystem.h"` |
| idem | 243-246 | `EnsureSettingsRows` (commence l. 241) : même remplacement (ancien 242-257) |
| idem | 302-305 | journal `Modules : cases de controle des mods ajoutees a Settings > Misc (moteur …, version min …, version max …) sur <MainMenu_C_n>` |
Les numéros de ligne « après » ont été relevés par `grep -n` sur les fichiers actuels (après les builds).
Total (`diff -u --strip-trailing-cr` contre l'instantané, lignes `+` / `-` hors en-têtes ; § 11) : 5 fichiers, +38 / −51. Par fichier : `LPSettingsSubsystem.h` +8 / −0, `LPSettingsSubsystem.cpp` +6 / −0, `LPColorGradeSubsystem.cpp` +8 / −16, `LPVideoQualitySubsystem.cpp` +8 / −17, `LPModInfoSubsystem.cpp` +8 / −18. Fins de ligne conservées (§ 9) : CRLF pour quatre fichiers, LF pour `LPModInfoSubsystem.cpp` (le fichier est LF dans l'index, `git ls-files --eol`).
`LPKeyboardSubsystem.cpp` : non touché (consigne), MD5 `611c21489d80374a4817f70e408cf4db` avant et après.
API moteur utilisée, lue dans `D:\Game\Launcher\Engine\UE_5.8\Engine\Source` (5.8.3). Le lot n'ajoute aucune API moteur nouvelle par rapport à SET1-V1 (§ 1 de `SET1-V1-IMPL.md`) ; les seules lignes neuves s'appuient sur :
| API | Source |
|---|---|
| `UGameInstanceSubsystem::GetGameInstance() const` renvoie `UGameInstance*` (paramètre `const UGameInstance*` de la nouvelle fonction : conversion vers `const`) | `Runtime/Engine/Public/Subsystems/GameInstanceSubsystem.h:25` |
| `class UGameInstance;` déjà déclarée par `GameInstanceSubsystem.h` (la redéclaration dans notre `.h` est sans effet) | `GameInstanceSubsystem.h:9` |
| `UObject::GetTypedOuter<T>() const` (pour le nom du `MainMenu` dans les journaux) | `Runtime/CoreUObject/Public/UObject/UObjectBaseUtility.h:551-553` |
## 2. Écarts à la SPEC / à la fiche
| # | Écart | Motif |
|---|---|---|
| E1 | Le journal de Video et celui de Mods changent de texte (suffixe `(sur <nom>)` / `sur <nom>`), et le Color reçoit une ligne neuve. La fiche demande que « les lignes de journal de chaque sous-système visent l'instance à l'écran ». | Sans nom d'instance, aucune ligne ne prouve sur quelle liste les lignes ont été posées. Le début du texte est conservé, donc une recherche par préfixe trouve toujours les lignes : `VQ2-VAL.md:62` et `VQ2-SPEC.md:302` citent `Video : controles ajoutes avant les reglages de couleur` ; `U7-T7-IMPL.md:221` cite la ligne Mods **entière**, qui se terminait par `)` : une comparaison exacte avec cette trace ancienne échouerait. |
| E2 | `Tick` des onglets inchangé : il appelle toujours la fonction du `namespace LPSettingsUi`, pas la fonction statique. | « Sans changer son comportement » : la statique est un renvoi d'une ligne vers la même fonction, aucun risque de divergence. |
| E3 | Les trois appelants passent `Current` = nul (valeur par défaut) ; `Tick` des onglets passe `SettingsList`. | Ils ne suivent aucune liste. Conséquence : à égalité de score (deux instances à l'écran, aucune liste ouverte) ils prennent la première trouvée, les onglets la liste déjà suivie. Cas non rencontré (une seule instance à l'écran à la fois d'après `SET1-V1-IMPL.md` § 0), sans effet visible : dès qu'une liste est ouverte (score 2), les quatre sous-systèmes la choisissent. |
| E4 | `LPSettingsSubsystem.h` est modifié (V1 : « `.h` non modifié »). | Exigé par la fiche (fonction statique publique déclarée dans le `.h`). |
| E5 | Aucune remise à zéro d'état par instance n'a été ajoutée dans Color, Video et Mods (la fiche : « corrige au minimum »). | Constat C1 ci-dessous : leur « état » est lu sur les enfants de la liste choisie, donc par instance de fait. |
| E6 | `CopieEtat.ps1 -Lot SET1` rend `ALERTE GIT` (code 1), 7 fichiers. | Deux sont **antérieurs** à ce travail (`LPCameraModeSubsystem.cpp`, `LPDirectControlSubsystem.cpp`, statut git de départ de la session) ; `LPSettingsSubsystem.cpp` porte aussi les changements de SET1-V1, non commités ; les quatre autres sont les fichiers de ce lot, non déclarés par `-Assets` (aucun asset). |
**Constat C1 — état par instance (lecture, non observé en jeu).** Pour chacun des trois sous-systèmes, ce qui décide « les lignes sont-elles déjà là ? » est lu sur la liste choisie, jamais mémorisé dans un indicateur :
- Color : présence d'un enfant `LPColorBrightness` (`LPColorGradeSubsystem.cpp:273`, boucle sur `Scroll->GetChildrenCount()`). Les cinq afficheurs de valeur `BrightnessValue`…`TintValue` sont des `TWeakObjectPtr<UTextBlock>` (`LPColorGradeSubsystem.h:53-57`) réaffectés par `AddRow` (`LPColorGradeSubsystem.cpp:235-254`, test sur le nom de la ligne) puis remplis (`:293-312`). Aucun indicateur booléen.
- Video : présence d'un enfant `LPVideoOverall` (`LPVideoQualitySubsystem.cpp:477`). `Rows[]` (`.h:104`) et `RecommendedButton` (`.h:105`) sont réaffectés par `AddRow` (`:426-427`) et `MakeRecommendedRow` (`:457`) ; `RefreshWidgets()` (`:591`) et `ApplyToScalability()` (`:593`) rejouent les valeurs sur les curseurs neufs. `Levels` et `bConfigured` sont globaux par conception (choix du joueur), pas par instance.
- Mods : présence d'un enfant `LPModCheckEngine` (`LPModInfoSubsystem.cpp:254`, `RowNames[0]`) ; aucune variable membre liée à la liste des réglages (`ManagerList` et `bManagerListLogged`, `.h:75-76`, concernent le gestionnaire de mods, autre widget, déjà filtré par `IsInViewport` à `TickModManager`).
Avec la bonne liste, une nouvelle instance n'a pas ces enfants : les lignes sont recréées à la première image où l'instance est à l'écran ; l'ancienne instance n'est plus regardée. Les noms `LPColor*` / `LPVideo*` / `LPModCheck*` sont classés par `LPSettingsUi::CategoryOf` (`LPSettingsSubsystem.cpp:267-275` : Video, Video, Misc) et `ApplyRows` est rejoué à chaque image où la liste est ouverte, donc une ligne ajoutée plus tard entre dans son onglet à l'image suivante.
**Constat C2 — délai.** Les lignes sont posées par des tickers à 0,5 s (`LPColorGradeSubsystem.cpp:77`, `LPVideoQualitySubsystem.cpp:160`, `LPModInfoSubsystem.cpp:150`), alors que `LPSettingsSubsystem` tourne à chaque image (`:583`, période 0). Entre l'apparition d'une instance à l'écran et ses lignes, il peut s'écouler jusqu'à ≈ 0,5 s ; un clic sur Settings dans cet intervalle montrerait les onglets Video et Misc incomplets quelques images (puis complétés). Estimé, non mesuré ; périodes non modifiées (hors fiche).
**Constat C3 — le défaut de V1 §8 est bien celui-ci.** Les trois boucles supprimées étaient les mêmes (`TObjectIterator<UScrollBox>`, nom `SettingsScrollBox`, même `GameInstance`, `break` à la première) : `git diff`/`diff -u` du § 11, lignes `-`.
## 3. Instantané
`D:\Game\LifePlay_Backup_5.5\SET1-V1b\` (fait par l'orchestrateur), `manifest.csv` relu : 5 fichiers, MD5 de départ **tous égaux** au manifeste avant écriture (relevé de session, § 9).
| Fichier (dans `Source\LifePlay\`) | Octets | MD5 du manifeste |
|---|---|---|
| `LPSettingsSubsystem.cpp` | 33904 | `3591F579D88C4CA3A44468C750C9A24E` |
| `LPSettingsSubsystem.h` | 1792 | `0F98C05568AE789C5C0B78F6EC580503` |
| `LPColorGradeSubsystem.cpp` | 12464 | `F818C7F56DA018ED97683F01717A9AFB` |
| `LPVideoQualitySubsystem.cpp` | 19408 | `DFF29F3F1B976979E556501CEBBF2613` |
| `LPModInfoSubsystem.cpp` | 16572 | `1D0FFF7D4327C493903F180868D00BDE` |
Retour arrière (proposé, non lancé) : `Tools\Restore.ps1 -Lot SET1-V1b`. Attention : `LPSettingsSubsystem.cpp` y revient à l'état **de fin de SET1-V1** (qui contient le travail de V1, non commité), pas à HEAD.
## 4. Ce qui n'a pas été fait
- Aucun essai en jeu (la fiche n'en confie pas) ; aucun éditeur ni jeu lancé.
- `LPKeyboardSubsystem.cpp` non touché (consigne). `LPReadableTextSubsystem.cpp`, `LPCameraModeSubsystem.cpp`, `LPDirectControlSubsystem.cpp` non ouverts.
- Pas de changement des périodes des tickers (C2), du `Tick` des onglets, de `PlaceSettingsButton`, d'un Blueprint ni du GI.
- Pas de test automatique (aucun existant pour ces sous-systèmes). Pas de build empaqueté.
- Aucune autre boucle `SettingsScrollBox` à reprendre : `Grep "SettingsScrollBox"` sur `Source` ne trouve plus que `LPSettingsSubsystem.cpp:129` (la fonction partagée), `LPKeyboardSubsystem.cpp:854` (hors consigne, indicateur de journal sans `break`), `LPReadableTextSubsystem.cpp:125` (remontée de parents) et des commentaires.
## 5. Points à confirmer en VAL (un par ligne)
1. W1 : en partie (Échap, Settings), première ouverture : l'onglet Video montre Overall Quality, Shadows, Textures, Effects, Anti-Aliasing, Recommended (`LPVideo*`) puis Brightness, Saturation, Contrast, White Balance, Tint (`LPColor*`) ; l'onglet Misc montre les trois cases de contrôle des mods (`LPModCheck*`) ; le tout dès l'ouverture, sans attendre la collecte d'une ancienne instance (≈ 30 s).
2. W2 : deuxième et troisième ouverture en partie (nouvelle instance à chaque fois) : mêmes contenus Video et Misc dès l'ouverture ; pour chaque instance trois lignes de journal portant le **même** `MainMenu_C_<n>` que `Reglages : onglets poses sur MainMenu_C_<n> (partie)` : `Couleur : reglages de couleur ajoutes sur …`, `Video : controles ajoutes avant les reglages de couleur (sur …)`, `Modules : cases de controle des mods ajoutees a Settings > Misc (…) sur …`.
3. W3 : écran titre, premier lancement, ouvrir Settings : mêmes contenus et mêmes trois lignes, `<n>` identique à celui de `onglets poses sur … (ecran titre)`. Symptôme du risque V6 de SET1-V1 (`IsInViewport()` faux pour l'instance du titre) : aucune des trois lignes et aucun `onglets poses` au titre ; ce lot l'aggraverait pour Video/Mods/Couleur, qui l'avaient avant (première liste trouvée, sans filtre d'écran).
4. W4 : retour au titre puis réouverture : mêmes contenus et trois lignes avec un `<n>` différent de celui du premier titre.
5. W5 : valeurs sur l'instance neuve : le curseur Overall et les quatre curseurs de Video affichent le niveau en cours (`RefreshWidgets`, pas la valeur par défaut) ; les cinq afficheurs de Couleur affichent les valeurs en cours (réaffectation des `TWeakObjectPtr`) ; un curseur déplacé sur l'instance neuve met bien à jour son afficheur (pas l'ancien).
6. W6 : pas de doublon : une seule ligne de journal par sous-système et par instance ; les noms `LPColorBrightness`, `LPVideoOverall`, `LPModCheckEngine` présents une fois dans la liste de l'instance à l'écran.
7. W7 : délai (C2) : mesurer, dans `LifePlay.log`, l'écart entre `Reglages : onglets poses sur …` et les trois lignes de la même instance ; attendu ≤ ≈ 0,5 s ; une ouverture de Settings dans cet intervalle ne doit rien casser.
8. W8 : ouverture répétée sur la même instance (ouvrir, Back, rouvrir) : aucune nouvelle ligne `Couleur`/`Video`/`Modules` (présence déjà vue), onglet Video inchangé.
9. W9 : reprise de V8 de `SET1-V1-IMPL.md` § 5 (onglets Video et Misc de l'instance de partie complets) : à juger sur W1 à W3 ; V1 à V10 de SET1-V1 restent à rejouer comme prévu.
## 6. Fichiers à commiter
Dépôt du jeu, branche `ue5.8` :
M `Source/LifePlay/LPSettingsSubsystem.h`
M `Source/LifePlay/LPSettingsSubsystem.cpp` (contient aussi le travail de SET1-V1, non commité à la date de cette fiche)
M `Source/LifePlay/LPColorGradeSubsystem.cpp`
M `Source/LifePlay/LPVideoQualitySubsystem.cpp`
M `Source/LifePlay/LPModInfoSubsystem.cpp`
A `Docs/Migration/etat/REL/SET1/SET1-V1b-IMPL.md`
A `Docs/Migration/etat/REL/SET1/SET1_Build_20261020-213520.txt` (résumé `Build.ps1` éditeur)
A `Docs/Migration/etat/REL/SET1/SET1_Build_20261020-213620.txt` (résumé `Build.ps1` jeu)
A `Docs/Migration/etat/REL/SET1/SET1-V1b_CopieEtat_avant_build.json`, `SET1-V1b_CopieEtat_apres_build.json` (traces `CopieEtat.ps1`)
Hors lot, déjà modifiés avant ce travail, **à ne pas embarquer** : `Source/LifePlay/LPCameraModeSubsystem.cpp`, `Source/LifePlay/LPDirectControlSubsystem.cpp`.
## 7. Compilation
Éditeur fermé et rien ne tournait avant (`UeState` : `processus=0 editeur=0 compilation=0 shaders=0 jeu=0`, code 0). Les deux builds ont été lancés à la suite, l'éditeur d'abord, le jeu seulement après un code 0.
| | LifePlayEditor Win64 Development | LifePlay Win64 Development `-NoUBA` |
|---|---|---|
| Commande | `pwsh -NoProfile -Command "& 'D:/Game/LifePlay-master 5.8/Tools/Build.ps1' -Lot SET1 -EtatDir 'D:/Game/LifePlay-master 5.8/Docs/Migration/etat/REL/SET1'"` | idem + `-Target LifePlay -Config Development -ExtraArgs '-NoUBA'` |
| Code de sortie | 0 | 0 |
| Durée | 59 s | 59 s |
| Erreurs / avertissements du compilateur | 0 / 0 | 0 / 0 |
| Autres lignes (UBT, UHT, liens) | 20 (les 20 lignes `Plugin 'HyperAIStudio' does not list plugin …` connues, `lp-build` § 7 : attendu 20 pour l'éditeur) | 0 (attendu 0 pour la cible jeu) |
| Unités compilées | 5 : `LPColorGradeSubsystem.cpp`, `LPModInfoSubsystem.cpp`, `LPSettingsSubsystem.cpp`, `LPVideoQualitySubsystem.cpp`, `Module.LifePlay.cpp` | les mêmes 5, marquées `[NoUba]` |
| Liaison | `[6/8] Link [x64] UnrealEditor-LifePlay.dll` (DLL liées : 1) | `[6/7] Link [x64] LifePlay.exe [NoUba]`, `Output binary: D:\Game\LifePlay-master 5.8\Binaries\Win64\LifePlay.exe`, `Result: Succeeded` (journal `:26, :31, :33`) ; le résumé compte « DLL liées : 0 » car le jeu lie un `.exe` |
| Toolchain | `Using Visual Studio 14.50.35739 toolchain (C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717)` = MSVC épinglé de la 5.8 | idem |
| Résumé | `Docs\Migration\etat\REL\SET1\SET1_Build_20261020-213520.txt` | `Docs\Migration\etat\REL\SET1\SET1_Build_20261020-213620.txt` |
| Journal | `Saved\Logs\portage\SET1_Build_20261020-213520.log` | `Saved\Logs\portage\SET1_Build_20261020-213620.log` |
Sorties brutes de `Build.ps1` (dernières lignes de chaque build) :
```
code=0 duree=59s erreurs=0 avertissements=0 autres=20 unites=5
code=0 duree=59s erreurs=0 avertissements=0 autres=0 unites=5
```
Dates des binaires (`ls -l --time-style=full-iso`) : `UnrealEditor-LifePlay.dll` 2026-10-20 21:36:18, `LifePlay.exe` 2026-10-20 21:37:17 (postérieurs aux écritures du § 11). Limites : la ligne `Makefile` des deux résumés est vide (comme en V1) ; le module modifié figure bien dans les unités compilées. Aucune ligne de journal propre au nouveau code n'existe avant un lancement du jeu (§ 10).
## 8. Les quatre autres sous-systèmes (point 3 de la fiche)
`LPKeyboardSubsystem.cpp` : non modifié, MD5 `611c21489d80374a4817f70e408cf4db` identique avant et après (`md5sum`, § 9). Aucun défaut de choix d'instance d'après `SET1-V1-IMPL.md` § 8 (boucle sans `break`, ne sert qu'à un indicateur pour un journal). Trois sous-systèmes corrigés : Color, Video, Mods (§ 1). `LPReadableTextSubsystem` : sans objet (aucun choix d'instance).
## 9. MD5 et fins de ligne
Commande : `md5sum Source/LifePlay/LPSettingsSubsystem.cpp Source/LifePlay/LPSettingsSubsystem.h Source/LifePlay/LPColorGradeSubsystem.cpp Source/LifePlay/LPVideoQualitySubsystem.cpp Source/LifePlay/LPModInfoSubsystem.cpp Source/LifePlay/LPKeyboardSubsystem.cpp` (après modification et après les builds, identique aux deux relevés) :
```
6277a8fc139c05dc10e302f88de0f8d9 *Source/LifePlay/LPSettingsSubsystem.cpp
138350efe8473c430db984db63c8feac *Source/LifePlay/LPSettingsSubsystem.h
5be400543166b6de7a4a88f6097a9d93 *Source/LifePlay/LPColorGradeSubsystem.cpp
c3055197030bdbbce813df4cc6d7cd63 *Source/LifePlay/LPVideoQualitySubsystem.cpp
98206e688308e908b04ae15cf408e1bb *Source/LifePlay/LPModInfoSubsystem.cpp
611c21489d80374a4817f70e408cf4db *Source/LifePlay/LPKeyboardSubsystem.cpp
```
| Fichier | MD5 avant (relu avant d'écrire, = manifeste) | MD5 après |
|---|---|---|
| `LPSettingsSubsystem.cpp` | `3591f579d88c4ca3a44468c750c9a24e` | `6277a8fc139c05dc10e302f88de0f8d9` |
| `LPSettingsSubsystem.h` | `0f98c05568ae789c5c0b78f6ec580503` | `138350efe8473c430db984db63c8feac` |
| `LPColorGradeSubsystem.cpp` | `f818c7f56da018ed97683f01717a9afb` | `5be400543166b6de7a4a88f6097a9d93` |
| `LPVideoQualitySubsystem.cpp` | `dff29f3f1b976979e556501cebbf2613` | `c3055197030bdbbce813df4cc6d7cd63` |
| `LPModInfoSubsystem.cpp` | `1d0fff7d4327c493903f180868d00bde` | `98206e688308e908b04ae15cf408e1bb` |
| `LPKeyboardSubsystem.cpp` (non touché) | `611c21489d80374a4817f70e408cf4db` | idem |
`git ls-files --eol` sur les cinq fichiers modifiés, puis comptes `tr -cd '\r' | wc -c` et `tr -cd '\n' | wc -c` :
```
i/crlf w/crlf attr/-text Source/LifePlay/LPColorGradeSubsystem.cpp (CR=370 LF=370)
i/lf w/lf attr/-text Source/LifePlay/LPModInfoSubsystem.cpp (CR=0 LF=432)
i/crlf w/crlf attr/-text Source/LifePlay/LPSettingsSubsystem.cpp (CR=1002 LF=1002)
i/crlf w/crlf attr/-text Source/LifePlay/LPSettingsSubsystem.h (CR=76 LF=76)
i/crlf w/crlf attr/-text Source/LifePlay/LPVideoQualitySubsystem.cpp (CR=596 LF=596)
```
`pwsh -NoProfile -File Tools/FileCheck.ps1 -Lot SET1-V1b` (le lot de l'instantané donne le manifeste des 5 fichiers) :
```
Fichiers CRLF LF CR BOM : fichiers=5 CRLF=4 LF=1 alertes=0 introuvables=0
contenu : modifie=5
```
(détail par fichier : CRLF 370 / LF 432 / CRLF 1002 / CRLF 76 / CRLF 596, `Sauv` = fins de ligne de l'instantané identiques, aucune alerte.)
`pwsh -NoProfile -File Tools/PubCheck.ps1 -Fichiers <chemin relatif> -Depot "D:/Game/LifePlay-master 5.8"` (stdin sur `/dev/null`, un fichier par appel) : `PubCheck : 0 constat(s)`, code 0, pour chacun des cinq fichiers source. Pour ce livrable : voir la fin de la section 12.
`pwsh -NoProfile -File Tools/CopieEtat.ps1 -Lot SET1 -Sortie …` avant et après les builds : `COPIE ALERTE lot=SET1 … proc=0 assets=0 absents=0 modifies=0 git=7/0/0 hors_declares=7 parasites=0 … alertes=GIT`, code 1 dans les deux cas (voir E6). Traces : `SET1-V1b_CopieEtat_avant_build.json`, `SET1-V1b_CopieEtat_apres_build.json`.
Fin de lot : `pwsh -NoProfile -File Tools/UeState.ps1 < /dev/null` → `processus=0 editeur=0 compilation=0 shaders=0 jeu=0`, code 0. **Jeton UE rendu.**
## 10. Journaux et preuve attendue en jeu
Lignes de journal (préfixe `LogLifePlay: ` dans `LifePlay.log`) :
| Ligne | Origine | Quand |
|---|---|---|
| `Reglages : onglets poses sur <MainMenu_C_n> (ecran titre|partie)` | SET1-V1 (`LPSettingsSubsystem.cpp`, fin d'`EnsureTabs`) | création d'une barre sur une instance |
| `Couleur : reglages de couleur ajoutes sur <MainMenu_C_n>` | **nouvelle** (`LPColorGradeSubsystem.cpp:313-314`, texte à la ligne 314) | les 5 lignes `LPColor*` viennent d'être ajoutées à la liste de cette instance |
| `Video : controles ajoutes avant les reglages de couleur (sur <MainMenu_C_n>)` | existante, suffixe **nouveau** (`LPVideoQualitySubsystem.cpp:594-595`) | les lignes `LPVideo*` et Recommended viennent d'être ajoutées |
| `Modules : cases de controle des mods ajoutees a Settings > Misc (moteur a, version min b, version max c) sur <MainMenu_C_n>` | existante, suffixe **nouveau** (`LPModInfoSubsystem.cpp:302-305`) | les 3 cases `LPModCheck*` viennent d'être ajoutées |
Recette de lecture pour la VAL : `pwsh -NoProfile -File Tools/LogStats.ps1 -Log <LifePlay.log> -Pattern 'onglets (poses|retires)|reglages de couleur ajoutes sur|controles ajoutes avant|cases de controle des mods' -Max 60` (un seul motif à alternatives : `pwsh -File` refuse une liste ; journal de la session, pas de compte refait de mémoire). Rapprocher ensuite les noms `MainMenu_C_<n>` des quatre familles de lignes.
Preuve attendue, à rejouer par la VAL sur un build Development :
| Scénario | Attendu à l'écran | Attendu au journal |
|---|---|---|
| Partie : Échap, Settings, première ouverture | onglets Video et Misc complets dès l'ouverture (W1) | `onglets poses sur MainMenu_C_n (partie)` puis, avec le même `n`, les trois lignes Couleur, Video, Modules (ordre libre) |
| Partie : deuxième, troisième ouverture | idem, sans attendre ≈ 30 s (W2) | `onglets retires de <ancienne>` si une barre existait ; un `n` nouveau à chaque ouverture, repris par les quatre lignes |
| Écran titre, puis retour au titre | idem (W3, W4) | `(ecran titre)` ; un `n` différent au second titre, repris par les trois lignes |
| Même instance rouverte | aucun changement (W8) | aucune nouvelle ligne Couleur, Video, Modules |
Limite : la présence d'une ligne `sur <n>` ne prouve que la liste choisie ; ce que le joueur voit (contenu des onglets) se juge à l'écran. Ni `IsInViewport()` sur l'instance du titre, ni l'ordre réel d'itération de `TObjectIterator`, ni le délai du ticker à 0,5 s ne sont observés ; établis par lecture seulement.
## 11. Diff (`diff -u --strip-trailing-cr` entre l'instantané `D:/Game/LifePlay_Backup_5.5/SET1-V1b/Source/LifePlay/` et `Source/LifePlay/`)
```diff
=== LPSettingsSubsystem.h
@@ -14,6 +14,7 @@
class UButton;
class UCanvasPanel;
+class UGameInstance;
class UHorizontalBox;
class UNativeWidgetHost;
class UScrollBox;
@@ -46,6 +47,13 @@
UFUNCTION()
void OpenSettings();
+ // Lot SET1-V1b. Liste des reglages (MainMenu.SettingsScrollBox) de l'instance de MainMenu qui est a l'ecran, nulle s'il
+ // n'y en a aucune. Partagee avec les sous-systemes qui ajoutent des lignes a cette liste (couleur, video, controle des
+ // mods) : une ancienne instance, retiree du viewport et pas encore collectee, garde sa liste en memoire et ne doit pas
+ // recevoir leurs lignes a la place de l'instance affichee. Current : liste deja suivie par l'appelant, elle departage
+ // deux listes a l'ecran ; peut etre nulle.
+ static UScrollBox* FindOnScreenSettingsList(const UGameInstance* GI, const UScrollBox* Current = nullptr);
+
private:
bool Tick(float DeltaTime);
void PlaceSettingsButton();
=== LPSettingsSubsystem.cpp
@@ -589,6 +589,12 @@
Super::Deinitialize();
}
+UScrollBox* ULPSettingsSubsystem::FindOnScreenSettingsList(const UGameInstance* GI, const UScrollBox* Current)
+{
+ // SET1-V1b : meme choix que le Tick des onglets (LPSettingsUi::FindOnScreenSettingsList), expose aux autres sous-systemes.
+ return LPSettingsUi::FindOnScreenSettingsList(GI, Current);
+}
+
bool ULPSettingsSubsystem::Tick(float DeltaTime)
{
(void)DeltaTime;
=== LPColorGradeSubsystem.cpp
@@ -15,6 +15,7 @@
#include "Engine/PostProcessVolume.h"
#include "Engine/World.h"
#include "LifePlay.h"
+#include "LPSettingsSubsystem.h"
#include "Misc/ConfigCacheIni.h"
#include "Misc/Paths.h"
#include "Styling/CoreStyle.h"
@@ -256,22 +257,11 @@
void ULPColorGradeSubsystem::EnsureControls()
{
- UScrollBox* Scroll = nullptr;
- for (TObjectIterator<UScrollBox> It; It; ++It)
- {
- UScrollBox* Candidate = *It;
- if (!Candidate || Candidate->GetFName() != TEXT("SettingsScrollBox") || Candidate->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
- {
- continue;
- }
- const UUserWidget* Owner = Candidate->GetTypedOuter<UUserWidget>();
- if (!Owner || Owner->HasAnyFlags(RF_ClassDefaultObject) || Owner->GetGameInstance() != GetGameInstance())
- {
- continue;
- }
- Scroll = Candidate;
- break;
- }
+ // SET1-V1b : la liste de l'instance de MainMenu qui est a l'ecran, pas la premiere trouvee (une ancienne instance,
+ // retiree du viewport et pas encore collectee, vient souvent avant). Aucune a l'ecran : rien a faire. Pas d'etat par
+ // instance a remettre a zero : la presence de LPColorBrightness se lit sur les enfants de la liste choisie, et AddRow
+ // rebranche les afficheurs de valeur (BrightnessValue...) sur les lignes de cette liste.
+ UScrollBox* Scroll = ULPSettingsSubsystem::FindOnScreenSettingsList(GetGameInstance());
if (!Scroll)
{
return;
@@ -320,6 +310,8 @@
{
Readout->SetText(FText::FromString(LPColorGrade::FormatValue(Tint, 2)));
}
+ const UUserWidget* Menu = Scroll->GetTypedOuter<UUserWidget>();
+ UE_LOG(LogLifePlay, Display, TEXT("Couleur : reglages de couleur ajoutes sur %s"), Menu ? *Menu->GetName() : TEXT("?"));
}
void ULPColorGradeSubsystem::OnBrightnessChanged(float Value)
=== LPVideoQualitySubsystem.cpp
@@ -17,6 +17,7 @@
#include "Engine/World.h"
#include "HAL/IConsoleManager.h"
#include "LifePlay.h"
+#include "LPSettingsSubsystem.h"
#include "Misc/ConfigCacheIni.h"
#include "Misc/Paths.h"
#include "DynamicRHI.h"
@@ -459,22 +460,11 @@
void ULPVideoQualitySubsystem::EnsureControls()
{
- UScrollBox* Scroll = nullptr;
- for (TObjectIterator<UScrollBox> It; It; ++It)
- {
- UScrollBox* Candidate = *It;
- if (!Candidate || Candidate->GetFName() != TEXT("SettingsScrollBox") || Candidate->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
- {
- continue;
- }
- const UUserWidget* Owner = Candidate->GetTypedOuter<UUserWidget>();
- if (!Owner || Owner->HasAnyFlags(RF_ClassDefaultObject) || Owner->GetGameInstance() != GetGameInstance())
- {
- continue;
- }
- Scroll = Candidate;
- break;
- }
+ // SET1-V1b : la liste de l'instance de MainMenu qui est a l'ecran, pas la premiere trouvee (une ancienne instance,
+ // retiree du viewport et pas encore collectee, vient souvent avant). Aucune a l'ecran : rien a faire. Pas d'etat par
+ // instance a remettre a zero : la presence de LPVideoOverall se lit sur les enfants de la liste choisie, et AddRow /
+ // MakeRecommendedRow rebranchent Rows et RecommendedButton sur les lignes de cette liste.
+ UScrollBox* Scroll = ULPSettingsSubsystem::FindOnScreenSettingsList(GetGameInstance());
if (!Scroll)
{
return;
@@ -601,5 +591,6 @@
RefreshWidgets();
// Nouvelle instance du menu : le Blueprint a pu reappliquer ses propres valeurs.
ApplyToScalability();
- UE_LOG(LogLifePlay, Display, TEXT("Video : controles ajoutes avant les reglages de couleur"));
+ const UUserWidget* Menu = Scroll->GetTypedOuter<UUserWidget>();
+ UE_LOG(LogLifePlay, Display, TEXT("Video : controles ajoutes avant les reglages de couleur (sur %s)"), Menu ? *Menu->GetName() : TEXT("?"));
}
=== LPModInfoSubsystem.cpp
@@ -18,6 +18,7 @@
#include "LifePlay.h"
#include "LPDataCompat.h"
#include "LPModGuard.h"
+#include "LPSettingsSubsystem.h"
#include "Misc/EngineVersion.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
@@ -239,22 +240,10 @@
void ULPModInfoSubsystem::EnsureSettingsRows()
{
- UScrollBox* Scroll = nullptr;
- for (TObjectIterator<UScrollBox> It; It; ++It)
- {
- UScrollBox* Candidate = *It;
- if (!Candidate || Candidate->GetFName() != TEXT("SettingsScrollBox") || Candidate->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
- {
- continue;
- }
- const UUserWidget* Owner = Candidate->GetTypedOuter<UUserWidget>();
- if (!Owner || Owner->HasAnyFlags(RF_ClassDefaultObject) || Owner->GetGameInstance() != GetGameInstance())
- {
- continue;
- }
- Scroll = Candidate;
- break;
- }
+ // SET1-V1b : la liste de l'instance de MainMenu qui est a l'ecran, pas la premiere trouvee (une ancienne instance,
+ // retiree du viewport et pas encore collectee, vient souvent avant). Aucune a l'ecran : rien a faire. Pas d'etat par
+ // instance a remettre a zero : la presence de LPModCheckEngine se lit sur les enfants de la liste choisie.
+ UScrollBox* Scroll = ULPSettingsSubsystem::FindOnScreenSettingsList(GetGameInstance());
if (!Scroll)
{
return;
@@ -310,9 +299,10 @@
Slot->SetPadding(FMargin(0.f, 0.f, 0.f, 10.f));
}
}
- UE_LOG(LogLifePlay, Display, TEXT("Modules : cases de controle des mods ajoutees a Settings > Misc (moteur %d, version min %d, version max %d)"),
+ const UUserWidget* Menu = Scroll->GetTypedOuter<UUserWidget>();
+ UE_LOG(LogLifePlay, Display, TEXT("Modules : cases de controle des mods ajoutees a Settings > Misc (moteur %d, version min %d, version max %d) sur %s"),
FLPModGuard::GetSavedCheck(ELPModCheck::Engine) ? 1 : 0, FLPModGuard::GetSavedCheck(ELPModCheck::MinVersion) ? 1 : 0,
- FLPModGuard::GetSavedCheck(ELPModCheck::MaxVersion) ? 1 : 0);
+ FLPModGuard::GetSavedCheck(ELPModCheck::MaxVersion) ? 1 : 0, Menu ? *Menu->GetName() : TEXT("?"));
}
```
## 12. Établi / estimé / incertain
- **Établi** : les trois boucles remplacées étaient identiques (`SettingsScrollBox`, même `GameInstance`, `break` à la première, § 11 lignes `-`) ; aucun autre site ne les reprend (`Grep "SettingsScrollBox"` sur `Source`, § 4) ; l'état de Color, Video et Mods se lit sur les enfants de la liste choisie (C1, avec lignes) ; la fonction statique renvoie la même valeur que celle des onglets (renvoi d'une ligne, `LPSettingsSubsystem.cpp:592-596`) ; MD5 de départ égaux au manifeste, MD5 d'arrivée et fins de ligne relevés (§ 9) ; `LPKeyboardSubsystem.cpp` inchangé ; compilation éditeur et jeu : code 0, 0 erreur, 0 avertissement, 5 unités compilées dans chaque (§ 7).
- **Estimé** : une ancienne instance précède la nouvelle dans `TObjectIterator` (déjà estimé en V1) ; les lignes arrivent au plus ≈ 0,5 s après l'apparition de l'instance (tickers à 0,5 s, C2) ; `ApplyRows` classe sans autre changement les lignes ajoutées plus tard (rejoué à chaque image, `Tick` des onglets).
- **Incertain** (essai qui trancherait : W1 à W9, § 5) : contenu réel des onglets Video et Misc aux trois scénarios ; `IsInViewport()` vrai pour l'instance du titre (V6 de V1) ; absence de régression de Video/Mods/Couleur au titre si ce filtre était faux ; mesure du délai de 0,5 s.
- **Livrable** : 0 CR (fins de ligne LF, `tr -cd '\r' | wc -c` = 0) ; `PubCheck` sur ce fichier : `PubCheck : 0 constat(s)`, code 0 ; `UeState` final : `processus=0 editeur=0 compilation=0 shaders=0 jeu=0`, code 0 ; **jeton UE rendu**.
Tours : 36 / 40 (déclaré par l'agent ; `Tools/FicheStats.py` fait foi)
## Constats
- `Tools\FileCheck.ps1 -Lot SET1-V1b` (lot de l'instantané, sans `-Path`) compare bien les cinq fichiers au manifeste (`Sauv` = fins de ligne d'origine, `Contenu` = modifié). C'est le contournement du piège relevé en V1 (`Contenu = pas sauvegarde` avec un chemin relatif à barres obliques).
- Les builds ont été enchaînés dans une commande d'arrière-plan (`CopieEtat` avant, `Build` éditeur, `Build` jeu seulement si l'éditeur rend 0, `CopieEtat` après, `UeState`), l'attente se faisant par `UeState.ps1 -Kind Compilation -WaitExit` (`lp-build` § 2) ; le jeu est lancé par `pwsh -Command "& '…/Build.ps1' … -ExtraArgs '-NoUBA'"` : la forme `-File … -ExtraArgs '-NoUBA'` risquerait de lire `-NoUBA` comme un nom de paramètre.
- La ligne exacte `U7-T7-IMPL.md:221` (trace ancienne de la ligne Mods) ne correspond plus à la ligne produite par le code actuel (suffixe ` sur <nom>`) : voir E1.