LifePlay-Revival/Docs/Migration/etat/REL/SAV/REL-SAV-DIAG.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

21 KiB
Raw Blame History

Fiche REL-SAV-T1 — Niveau N3− — Modèle prévu opus (lp-diag, effort medium) | utilisé claude-opus-5-5 (session REL, sans sous-agent) — Agent session REL — Skills lp-lot, lp-paths

REL-SAV-DIAG : renommer le dossier de sauvegarde LifePlay en LifePlay-Revival (2026-10-13)

Lecture seule : aucun jeton UE, rien écrit hors ce dossier etat\REL\SAV\. Moteur lu : D:\Game\Launcher\Engine\UE_5.8\Engine (abrégé E\), moteur installé (E\Build\InstalledBuild.txt présent). Niveaux de preuve : établi (lu dans la source ou mesuré), estimé (déduit, non rejoué), incertain.

Verdict

L'hypothèse est confirmée : sous Windows, le jeu Shipping écrit dans %LOCALAPPDATA%\<FApp::GetProjectName()>\Saved. Le nom de projet LifePlay est figé dans l'exe monolithique et sert aussi au chemin du contenu : on ne le change pas. Le moteur prévoit deux leviers :

  • un argument de lancement -UserDir=<chemin absolu>, déjà utilisé par les .bat d'essai du projet ;
  • une macro de compilation UE_SAVED_DIR_OVERRIDE, sans effet avec le moteur Launcher, car Core y est précompilé.

Recommandation : option B (lanceur officiel qui passe -UserDir="%LOCALAPPDATA%\LifePlay-Revival"), complétée par la garde B+ si l'on veut couvrir le double-clic sur LifePlay.exe. Les deux sont réversibles, sans changement du contrat des mods ni de l'éditeur. B seule ne touche ni Source\ ni Config\ ni Content\ ; B+ ajoute du C++ dans le module LifePlay.

1. Calcul du dossier utilisateur et de Saved (UE 5.8, Windows, jeu empaqueté)

Étape Source Niveau
ProjectSavedDir() = ProjectUserDir() + Saved (+ _<suffixe> si -saveddirsuffix=), mis en cache au premier appel E\Source\Runtime\Core\Private\Misc\Paths.cpp:86-115, 485-494 établi
ProjectUserDir() : 1) -UserDir= s'il est donné ; 2) sinon, si ShouldSaveToUserDir() : UserSettingsDir()\UE_SAVED_DIR_OVERRIDE si la macro est définie, sinon UserSettingsDir()\<FApp::GetProjectName()> ; 3) sinon ProjectDir() (dossier du jeu) Paths.cpp:451-471 établi
ShouldSaveToUserDir() = FApp::IsInstalled() ou -SaveToUserDir ou FPlatformProcess::ShouldSaveToUserDir() (faux par défaut) ou -UserDir non vide Paths.cpp:183-192 ; E\Source\Runtime\Core\Private\GenericPlatform\GenericPlatformProcess.cpp:98-102 établi
FApp::IsInstalled() est vrai par défaut en Shipping desktop ; il l'est aussi si Engine\Build\InstalledProjectBuild.txt existe, ou avec -Installed. -NotInstalled l'annule E\Source\Runtime\Core\Private\Misc\App.cpp:212-242 (l. 218-219, 225-227, 231-237) établi
UserSettingsDir() = dossier connu LocalAppData (LocalAppDataLow en intégrité basse) E\Source\Runtime\Core\Private\Windows\WindowsPlatformProcess.cpp:1459-1467 établi
-UserDir= est lu par FParse::Value(…, "UserDir="). Un chemin relatif est rattaché à ProjectDir() ; aucune variable d'environnement n'est développée par le moteur (0 occurrence de « environment » dans CommandLine.cpp) : il faut un chemin absolu déjà développé Paths.cpp:1940-1960 ; E\Source\Runtime\Core\Private\Misc\CommandLine.cpp établi
Journaux : ProjectLogDir() = ProjectSavedDir()\Logs sous Windows (SUPPORTS_LOGS_IN_USERDIR = 0) Paths.cpp:36-38, 574-595 établi
Nom du projet dans un exe monolithique : GInternalProjectName = UE_PROJECT_NAME, défini par UBT à partir du nom du .uproject. Le même nom sert au chemin ..\..\..\<Nom>\<Nom>.uproject E\Source\Runtime\Core\Public\Modules\ModuleManager.h:1102, 1116 ; E\Source\Programs\UnrealBuildTool\Configuration\UEBuildModuleCPP.cs:2792-2797 ; E\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:666-716 établi
Aucun réglage .ini ne change ce dossier : seuls la ligne de commande et la macro interviennent dans Paths.cpp Paths.cpp:451-471 (aucune lecture de GConfig) établi

Constat sur les builds du projet (établi) : les 20 builds LifePlay_Build_5.8_*_Development lancés ont un Windows\LifePlay\Saved à côté de l'exe (Development non « installé »). Le Shipping, lui, écrit dans %LOCALAPPDATA%\LifePlay\Saved. Ce dossier existe sur le poste et contient :

Sous-dossier Taille Fichiers
Config 53 K 29 (Windows\GameUserSettings.ini, LPColorGrade.ini, LPKeyboard.ini ; restes WindowsNoEditor\ et CrashReportClient\ des versions UE4)
SaveGames 11 M 22
LPDataCache 7,9 M 13
Logs 0 0
Crashes 4 K 0

Conséquence : seul le Shipping (build de release) est concerné. L'éditeur et les builds Development de test n'utilisent pas ce dossier aujourd'hui.

2. Options pour obtenir LifePlay-Revival sans renommer le projet ni le module

Option Moyen Effort Risque Réversibilité Niveau
A. Macro UE_SAVED_DIR_OVERRIDE GlobalDefinitions.Add("UE_SAVED_DIR_OVERRIDE=LifePlay-Revival") dans LifePlay.Target.cs (UE_STRINGIZE garde le tiret : PreprocessorHelpers.h:6-7) impossible avec le moteur Launcher. Une définition globale exige BuildEnvironment = Unique, refusé sur moteur installé (RulesAssembly.cs:708-712 ; UEBuildTarget.cs:1508-1516). Même forcée par bOverrideBuildEnvironment, elle ne recompile pas Core : les modules du moteur installé sont précompilés (RulesAssembly.cs:572-573, bUsePrecompiled = bReadOnly), et LifePlay-Win64-Shipping.exe.rsp relie 43 objets Module.Core.* pris dans l'Intermediate du moteur. Il faudrait un moteur 5.8 compilé depuis les sources : très lourd. élevé (changement de chaîne de build juste avant la release) oui (retirer la ligne), mais le moteur source reste à maintenir établi (refus, liaison) ; estimé (sans effet silencieux avec bOverrideBuildEnvironment)
B. Lanceur officiel avec -UserDir Un lanceur à la racine du paquet (.bat, raccourci ou petit exe) qui lance LifePlay.exe -UserDir="%LOCALAPPDATA%\LifePlay-Revival". Le moteur crée alors …\LifePlay-Revival\Saved\… (Paths.cpp:453-457 puis :86-115) faible : un fichier ajouté au paquet par l'étape d'empaquetage, plus README. Méthode déjà prouvée en Shipping par les .bat d'essai (LifePlay_Build_5.8_Shipping_U8r2_essai\Windows\Lancer_U8r2_essai.bat, lp-validate l. 96-100) moyen : un joueur qui lance LifePlay.exe directement (habitude, raccourci existant) retombe sur %LOCALAPPDATA%\LifePlay. Les deux dossiers coexistent alors sans erreur, mais avec des sauvegardes séparées totale : retirer le lanceur établi (mécanisme) ; estimé (comportement des joueurs)
B+. B + garde dans le jeu Au démarrage du module LifePlay, en Shipping : si FPaths::CustomUserDirArgument() est vide, relancer l'exe avec -UserDir=… puis sortir aussitôt (RequestExit(true), sans écrire la config) moyen : environ 30 lignes C++, une build, un essai en jeu moyen : à ce moment, le moteur a déjà ouvert un journal et lu la config dans l'ancien dossier (pré-initialisation avant les modules du jeu). Il faut prouver que rien n'y est réécrit. Une double fenêtre ou un écran de démarrage est possible totale (retirer le code) estimé (non rejoué)
C. Renommer le projet (.uproject, ProjectName) pour le seul paquet — élevé rédhibitoire : UE_PROJECT_NAME et le chemin <Nom>\Content changent (LaunchEngineLoop.cpp:708-713), ce qui casse la structure du paquet, les points de montage et le contrat des mods (figé). Les noms de projet UE n'acceptent pas le tiret (incertain, non vérifié) difficile établi (lien nom ↔ chemins)
D. Arguments intégrés à LifePlay.exe (bootstrap) UAT écrit dans la ressource 202 de l'exe de démarrage les seuls arguments ..\..\..\LifePlay\LifePlay.uproject (E\Source\Programs\AutomationTool\Win\WinPlatform.Automation.cs:167-176, 330-331) moyen à élevé : retoucher la ressource après empaquetage moyen. Surtout, sans développement des variables, il faudrait un chemin absolu propre à chaque poste : inapplicable oui établi
E. Jonction Windows LifePlay → LifePlay-Revival — faible le dossier LifePlay reste visible : ne répond pas à la demande oui estimé

3. Effets de bord (option B ou B+)

Domaine Effet Preuve
Code du jeu et de l'addon Aucun chemin en dur : tout passe par ProjectSavedDir() et suit le nouveau dossier (jeu : LPColorGradeSubsystem.cpp:27, LPKeyboardSubsystem.cpp:37, LPVideoQualitySubsystem.cpp:71, LPDebugSubsystem.cpp:78, 101, Plugins\LPAnimCore\…\LPAnimRedirect.cpp:10, Plugins\ModdingExtra\…\LPDataCache.cpp:105 ; addon LPSandbox* : 10 fichiers, absent du paquet de release) établi (grep)
Mods et contrat des mods Les mods vivent dans Content\Modules du dossier du jeu (ProjectContentDir() : LPModInfoSubsystem.cpp:129, LPDataCache.cpp:102-104). Aucun mod ne lit Saved. LPDataCache est un cache reconstruit à partir des dates et tailles des modules (LPDataCache.cpp:107-125) : il est simplement recréé au premier lancement (plus lent une fois). Le contrat des mods n'est pas touché. Le choix des mods (GI.ModEnableds, README l. 97) est enregistré dans une sauvegarde : il suit SaveGames si l'on reprend ce dossier établi (mods, cache) ; estimé (lieu du choix des mods : GameSettings.sav, doc 21 l. 225)
Sauvegardes dans Content\Saves Une partie de la sauvegarde (Player.lpcharacter, doc 21 l. 213) est dans Content\Saves, dans le dossier d'installation. Le renommage ne la touche pas ; le défaut existant (SAV1 / ERR-042) reste ouvert établi
Éditeur Non concerné : non « installé », il écrit dans <copie>\Saved. Le lanceur n'est livré qu'avec le paquet établi (App.cpp:218-221, Paths.cpp:467-470)
Builds Development de test Non concernés, sauf s'ils sont lancés par le lanceur : -UserDir force alors le dossier utilisateur (Paths.cpp:189) établi
Lanceurs d'essai (Lancer_*_essai.bat) Ils passent leur propre -UserDir : inchangés établi
Outils Tools\TracesRacines.ps1:90 liste %LOCALAPPDATA%\LifePlay comme racine de traces : ajouter LifePlay-Revival. CollectDebugArtifacts.ps1:18-20, debug\LifePlay_debug_*.bat et .ps1, LogStats.ps1:22 visent le Saved d'un build Development : inchangés. CheckPackage.ps1 : aucune mention de Saved ni d'AppData. Étape d'empaquetage (lp-builder / BuildDebug) : y ajouter le lanceur établi (grep)
Skills lp-build l. 71-72 et lp-validate l. 96-100 (copie 5.8 et addon 5.8) citent %LOCALAPPDATA%\LifePlay\Saved : à mettre à jour établi (grep)
README l. 82-83 (« saves and settings … %LOCALAPPDATA%\LifePlay\Saved ») et l. 140 : à réécrire (nouveau dossier, lanceur, reprise) établi
Moteur hors projet EngineUserDir (%LOCALAPPDATA%\UnrealEngine\5.8) ne dépend pas de -UserDir (Paths.cpp:204-210) : inchangé établi

4. Reprise des anciennes sauvegardes (option seulement, à décider par l'utilisateur)

Variante Quoi Coût Risque
R0. Rien Le joueur copie lui-même ; seul le README l'explique nul perte apparente des parties (signalements)
R1. Copie par le lanceur (B) Au lancement : si %LOCALAPPDATA%\LifePlay-Revival\Saved\SaveGames est absent et que %LOCALAPPDATA%\LifePlay\Saved\SaveGames existe, copier SaveGames (11 M, 22 fichiers sur ce poste). La copie se fait avant le démarrage du moteur, donc sans conflit de fichiers ouverts. Sans déplacement ni suppression : l'ancien dossier reste une sauvegarde faible : quelques lignes dans le lanceur ; essai avec dossier présent, absent, déjà migré faible ; à essayer avec un profil dont le chemin contient une espace ou des accents
R1c. + Config\Windows GameUserSettings.ini, LPKeyboard.ini, LPColorGrade.ini, LPVideoQuality.ini faible moyen : réglages d'une version antérieure réinjectés (incident U8 : .ini réécrits). À éviter, ou à limiter à LPKeyboard.ini (touches du joueur). WindowsNoEditor\, CrashReportClient\, LPDataCache, Logs, Crashes ne sont jamais à reprendre
R2. Copie dans le jeu (C++) Même règle, faite au démarrage du module LifePlay moyen (C++ + build) moyen : GameUserSettings est déjà lu quand le module démarre, donc une copie de Config arriverait trop tard ; SaveGames seul reste possible si la copie précède la première lecture des sauvegardes par le GI (à prouver)

5. Recommandation

  1. B + R1 (SaveGames seul). Un lanceur LifePlay-Revival est ajouté au paquet par l'étape d'empaquetage. Il copie SaveGames s'il manque, puis lance LifePlay.exe -UserDir="%LOCALAPPDATA%\LifePlay-Revival". Le README désigne ce lanceur comme point d'entrée. Rien n'est écrit dans Source\, Config\ ni Content\ : risque faible, faisable avant l'alpha.
  2. B+ seulement si l'utilisateur veut couvrir le lancement direct de LifePlay.exe. C'est du C++ avec un risque moyen, à n'engager qu'après une preuve en jeu que l'ancien dossier n'est pas réécrit. Sinon, l'écarter jusqu'après l'alpha.
  3. Rejeter A (moteur source), C (renommage du projet) et D.

Questions pour l'utilisateur (posées par Big Boss) : forme du lanceur (.bat avec fenêtre de console brève, raccourci .lnk, ou petit exe) ; reprise R0 / R1 / R1c ; B+ oui ou non. Chantiers suivants si GO : SPEC du lanceur, IMPL dans l'outil d'empaquetage, BUILD Shipping, essai en jeu (dossier absent, présent, déjà migré ; Continuer ; mods), puis DOC (README, TracesRacines.ps1, lp-build, lp-validate, doc 29 l. 37).

6. Proposition de l'utilisateur (2026-10-13) : dossier choisi dans les réglages du jeu, LifePlay-Revival par défaut

Demande : enregistrer le dossier de sauvegarde dans un fichier .ini des réglages du jeu, pour que le joueur puisse le choisir, avec %LOCALAPPDATA%\LifePlay-Revival par défaut.

Faisable, en prolongement de l'option B, sous deux contraintes établies au § 1 :

  1. Le chemin doit être connu avant le démarrage du moteur. ProjectSavedDir() est calculé une fois, puis mis en cache (Paths.cpp:485-494), à partir de la seule ligne de commande (Paths.cpp:451-471). Le jeu ne peut donc pas changer de dossier en cours de partie. C'est le lanceur qui lit le .ini et passe -UserDir. Un choix fait dans le menu prend effet au lancement suivant.
  2. Le .ini ne peut pas être dans Saved. GameUserSettings.ini est dans Saved\Config\Windows : le lanceur ne le trouverait qu'en connaissant déjà le dossier (référence circulaire). Précision de l'utilisateur (2026-10-13) : le fichier va dans le dossier LifePlay du jeu installé, avec d'autres réglages, par exemple <installation>\Windows\LifePlay\SaveLocation.ini, clé SaveDir= (nom et place exacts fixés par la SPEC). L'emplacement est fixe par rapport à l'exe : le lanceur et le jeu le trouvent tous deux sans connaître Saved (le jeu par FPaths::ProjectDir()). Si le fichier ou la clé manque, le lanceur prend %LOCALAPPDATA%\LifePlay-Revival. Le paquet V2.0 n'a aujourd'hui aucun fichier de réglages dans ce dossier (Binaries, Content\Modules, Movies, Paks seulement). Les fichiers de réglages existants (LPKeyboard.ini, LPVideoQuality.ini, LPColorGrade.ini, GameUserSettings.ini) ne peuvent pas recevoir cette clé. Ils sont écrits dans ProjectSavedDir()\Config\Windows, donc dans le dossier de sauvegarde lui-même (§ 3). En Development, ce dossier se trouve sous <build>\Windows\LifePlay\Saved\Config\Windows (relevé : LifePlay_Build_5.8_STE-J6_Development). En Shipping, il se trouve sous %LOCALAPPDATA%\LifePlay\Saved\Config\Windows (relevé sur ce poste), et il suivra le dossier choisi. On retient donc un fichier séparé au même format, LPSaveLocation.ini, placé hors de Saved. Conséquences de cet emplacement :
    • Une nouvelle installation, par exemple une nouvelle version décompressée ailleurs, repart sans ce fichier, donc au dossier par défaut. Les parties ne sont pas perdues : elles restent dans le dossier choisi, qu'il faudra choisir de nouveau, ou recopier le .ini (à écrire au README).
    • Droits d'écriture : hors périmètre (utilisateur, 2026-10-13). Le jeu n'a pas d'installateur : on le décompresse où l'on veut, et les permissions sont à la charge du joueur. Aucun repli spécial n'est prévu. Seule une écriture refusée est signalée au journal, sans plantage (garde minimale de la SPEC).
    • L'emplacement est cohérent avec Content\Saves, déjà dans le dossier d'installation (§ 3).

Détails :

  • Le moteur ajoute Saved\ au dossier choisi (Paths.cpp:86-115). Si le joueur choisit D:\MesParties, il obtient D:\MesParties\Saved\SaveGames. Cela convient, à condition de l'indiquer dans le menu.
  • Le lanceur vérifie que le dossier est accessible en écriture. Sinon, il revient au dossier par défaut.
  • Au changement de dossier, il faut décider : copier les sauvegardes existantes vers le nouveau dossier (même règle que R1), ou partir d'un dossier vide.
Volet Effort Risque Touche
Lanceur qui lit SaveLocation.ini (B + R1, plus une lecture de clé) faible faible outil d'empaquetage seulement
Option dans le menu des réglages (choix du dossier, écriture du .ini, message « effectif au prochain lancement ») moyen à élevé : widget Blueprint (Content, par MCP) et fonction C++ d'écriture et de sélecteur de dossier moyen Source\, Content\ (GO de Big Boss)

Proposition de phasage :

  • Avant l'alpha : le lanceur avec SaveLocation.ini. Le joueur peut déjà changer le dossier en modifiant le fichier (README).
  • Ensuite : l'option dans le menu des réglages, comme lot distinct (SPEC, IMPL, BUILD, essai en jeu).

7. Ligne « dossier de sauvegarde » dans les réglages du jeu (demande de l'utilisateur, 2026-10-13 : onglet Misc ou General)

Faisable en C++ seul, sans modifier de Blueprint ni rien dans Content\, sur le modèle d'un précédent du projet (établi, lecture du code) :

  • LPSettingsSubsystem.cpp:35-45 : les six onglets General, Audio, Video, Keyboard, Lewd, Misc. CategoryOf (l. 145-207) range chaque ligne d'après le nom de son widget, puis d'après son libellé.
  • LPModInfoSubsystem.cpp:42-46, 240-313 : le lot U7 ajoute déjà en C++ trois lignes à SettingsScrollBox, avec des libellés suffixés « (restart) » et l'infobulle « Takes effect at next launch ». Les widgets nommés LPModCheck* sont envoyés dans Misc (LPSettingsSubsystem.cpp:178-181).

Proposition (pour la SPEC) :

  • Un sous-système, ou une extension de LPSettingsSubsystem, ajoute une ligne nommée LPSaveDir…, rangée dans Misc : c'est l'onglet qui porte déjà les réglages « (restart) ». General reste possible en une ligne de CategoryOf, au choix de l'utilisateur.
  • Contenu de la ligne :
    • libellé « Save folder (restart) » et chemin actuel (FPaths::ProjectUserDir()) ;
    • bouton « Browse… » ;
    • bouton « Default » (%LOCALAPPDATA%\LifePlay-Revival) ;
    • infobulle : « Takes effect at next launch. Existing saves are copied if the new folder has none » (selon la décision R0 / R1).
  • Écriture de ProjectDir()\LPSaveLocation.ini, clé SaveDir=. En cas d'échec, une ligne au journal (décision U3).
  • Sélecteur de dossier :
    • le module DesktopPlatform sert à l'éditeur et n'est pas livré en Shipping (estimé) ;
    • il faudrait donc le dialogue natif Windows (IFileOpenDialog, FOS_PICKFOLDERS, sous #if PLATFORM_WINDOWS), estimé à une soixantaine de lignes ;
    • repli plus simple : un champ texte où l'on colle le chemin, plus le bouton « Default ».

Dans tous les cas, cette ligne ne fait qu'écrire le choix. Pour qu'il soit appliqué au lancement suivant, il faut encore :

  • soit le lanceur (B), qui lit LPSaveLocation.ini et passe -UserDir ;
  • soit la garde B+ : au démarrage, le jeu lit LPSaveLocation.ini et, si -UserDir est absent ou différent, se relance avec le bon -UserDir, puis se ferme. Avec un réglage dans le jeu, B+ dispense du lanceur et couvre le double-clic sur LifePlay.exe, mais il reste à prouver en jeu que l'ancien dossier n'est pas réécrit (§ 2).

Effort : moyen. Le C++ se trouve dans Source\LifePlay seulement ; il faut une compilation, un paquet Shipping et un essai en jeu (choisir, relancer, Continuer, revenir au dossier par défaut). Risque : moyen. GO de Big Boss requis.

Fichiers à commiter

Docs/Migration/etat/REL/SAV/REL-SAV-DIAG.md, Docs/Migration/etat/REL/SAV/REL-SAV-TACHES.md, Docs/Migration/etat/REL/SAV/fiches/REL-SAV-T1.md (ticket au gardien par Big Boss).

Tours : ≈ 30 — aucune écriture hors etat\REL\SAV\ — aucun jeton UE pris.