LifePlay-Revival/Docs/Migration/01_Architecture_Initiale.md

184 lines
13 KiB
Markdown
Raw Normal View History

# 01 — Architecture initiale de LifePlay (référence 4.27, écarts 5.5)
> Document de référence de la reprise de migration (2026-09-29).
> Source : étude en lecture seule de `D:\Game\LifePlay-master 4.27` (tables de noms, d'imports et
> d'exports des `.uasset`, graphes Blueprint, code C++, journal d'exécution 4.27 Development).
> Complément : `Docs/Architecture/VictoryPlugin_Architecture.md` (C++ et plugins) et
> `Docs/Architecture/Rapport_Session_2026-09-28.md` (bug ouvert).
---
## 1. Vue d'ensemble
LifePlay est un **moteur de script piloté par des données texte**, écrit presque entièrement en
Blueprint. Il n'y a **ni DataTable, ni JSON, ni XML, ni clé de gameplay dans les `.ini`**.
```
Content/Modules/** (fichiers texte : .lpmod .lpstat .lpaction .lpscene .lpai .lpquest
│ .lptalk .lpdesc .lpcharacter .lpworld, tables *.txt)
│ lus à l'exécution, sur disque, hors paquet
▼
Plugins/ModdingExtra (C++) LoadTxt · SaveTxt · GetAllFilesFromFolder
│ FFileHelper / IFileManager sur FPaths::ProjectContentDir()
▼
Content/BPs/GI.uasset (GameInstance, 606 fonctions, 618 variables, 50 Mo)
│ analyse, tableaux Raws_*, structures, interpréteur du DSL
├──► ÉVÉNEMENTS CheckForScenes → PlayScene → ReadSceneLine → CallFunction (219 commandes)
├──► PERSONNAGES GeneratePerson → LoadPreset / Person.RandomizeAll
└──► SAUVEGARDE Save_C, GameSettings_C, CityExpansion_C (USaveGame) + .lpcharacter
▼
Content/BPs/Person.uasset (386 fonctions : morphs, peau, cheveux, stats) UI/* (≈100 widgets)
Plugins/StreetMap (280 villes) Source/LifePlay (helpers AssetRegistry, compat Victory)
```
Contrainte de packaging **vitale** : `Config/DefaultGame.ini`
`+DirectoriesToAlwaysStageAsNonUFS=(Path="Modules")`. `Modules` doit rester en fichiers nus à côté
de l'exécutable : il est lu par `FFileHelper`, pas par le système de paquets. Les mods de la
communauté reposent sur ce point.
## 2. Configuration de démarrage
| Fichier | Clé | Valeur |
|---|---|---|
| `DefaultEngine.ini` | `GameInstanceClass` | `/Game/BPs/GI.GI_C` |
| `DefaultEngine.ini` | `GlobalDefaultGameMode` | `/Game/BPs/GM.GM_C` |
| `DefaultEngine.ini` | `GameDefaultMap` | `/Game/Scenes/CentralLondon.CentralLondon` |
| `DefaultGame.ini` | `DirectoriesToAlwaysStageAsNonUFS` | `Modules` |
| `DefaultGame.ini` | `UsePakFile` | `False` |
| `DefaultInput.ini` | 55 `ActionMappings` (34 actions), 13 `AxisMappings` (6 axes) | consommés par `BPs/PC` uniquement |
Aucun `GConfig` dans le C++. Les réglages joueur sont dans `Saved/SaveGames/GameSettings.sav`.
## 3. Couches logicielles
### 3.1 C++ du projet
| Module | Type | Contenu utile |
|---|---|---|
| `Source/LifePlay` | Runtime | `ULPAssetRegistryHelpers::GetAssetByObjectPath` (nœud pur, utilisé par `GI`, `Person`, `Room`, `UI/VisualMorph`) ; en 5.5 aussi `LPVictoryCompat`, `LPNavigationHelpers` |
| `Source/LifePlayEditorTools` | Editor | commandlets d'analyse et de correction de graphes (`LPDumpFunction`, `LPCheckMeshAssignment`, `LPFix*`, `LPCheckStreetMap`) |
`ALifePlayGameModeBase` est vide : le vrai mode de jeu est `/Game/BPs/GM`.
### 3.2 Plugins
| Plugin | Rôle | Fonctions consommées par le contenu |
|---|---|---|
| `ModdingExtra` (Vinfamy, Runtime, `PreLoadingScreen`) | **toute l'entrée/sortie de données** | `LoadTxt` (9 assets), `GetAllFilesFromFolder` (6), `SaveTxt` (4) |
| `StreetMap` (fork Vinfamy) | villes OSM : routes, bâtiments, `SearchByBuildingName` | 292 assets |
| `VictoryBPLibrary` (4.27 seulement) | 2 nœuds : `Victory_LoadTexture2D_FromFile`, `Victory_SaveStringToOSClipboard` | remplacé en 5.5 par `LPVictoryCompat` + `[CoreRedirects]` |
## 4. Formats de données
| Motif | Format | Champs | Consommateur (`GI`) |
|---|---|---|---|
| `Modules/<id>/<id>.lpmod` | `CLÉ: valeur` | `MODULE_UNIQUEID/NAME/AUTHOR/LINK/DESCRIPTION/REQUIREMENTS` | `removeDeletedMods`, `UI/ModManager` |
| `Modules/ModLauncher.config` | ligne 1 `UseConfigIgnoreAppData:true/false`, puis `UniqueID:IsEnabled` (déduit) | — | `ReadModLauncher` → `ParseConfig` → `ModEnableds`. **Absent du disque dans les deux versions** |
| `*.lpstat` | `CLÉ: valeur` | `STAT_ID, STAT_NAME, PLAYER_ONLY, NPC_ONLY, HIGHER_BETTER, STAT_MIN, STAT_MAX, DAILY_CHANGE, DEFAULT_VALUE` | `PopulateStats` → `StatValue[]` |
| `*.lpaction` | `CLÉ: valeur` | `ACTION_UNIQUEID/NAME, WHERE, WHEN, MINUTES, TIMEOUT_MINUTES, ALSO_TIMEOUT, EFFECTS, CONDITIONS, MOVE_FIRST, SCENE_ALWAYS, ANIMATION` | `PopulateActions` → `ActionDetail[]`, `AmenityAction[]` |
| `*.lpscene` | en-tête `WHAT/WHERE/WHEN/WHO/OTHER`, puis corps DSL | — | `PopulateScenes` → `Scene[]` ; corps relu par `PlayScene` |
| `*.lpai` | corps DSL (5 premières lignes ignorées) | — | `LPAI`, `AI_High/Med`, `UpdateAI` |
| `*.lpquest` | `CLÉ: valeur` | `ID, NAME, DESC, ONCE, CONDITIONS, START` | `PopulateQuests` → `Quest[]` |
| `*.lptalk`, `*.lpdesc` | condition + textes, séparateur `##`, préfixes `*START*`/`*END*` | — | `PopulateTalksAndDescs` |
| `*.lpcharacter` | `CATÉGORIE Param: p% v1, p% v2…` ; plage `lo=>hi` | catégories `INFO, HAIR, SKIN, MORPH, STAT, SCALE, PENIS` | `LoadPreset` → `ReadLine` → `ChanceMinMax` → `GenerateAndApply{Floats,Strings,Bools}` |
| `*.lpworld` | taille de pièce, blocs `*****` (maillage `///` matériaux `///` transformation) | — | `PopulateWorldPresets`, `Room` |
| `Modules/names_{F,M}.txt` | un prénom par ligne | — | `FillNamePool` |
| `Modules/outfits_{M,F}[_work/_sports/_swim].txt` | `;` entre tenues, `,` entre pièces | — | `ReadOutfits` |
| `Modules/uniforms.txt` | lieux, puis listes F et M | — | `readUniforms` |
| `Modules/Clothes4.txt`, `SimplifyMorphs.txt`, `donors.txt` | `Nom: Daz?: Slots: Tag,Nombre` | — | `populateClothes4`, `SimplifyMorphs` |
| `Modules/MorphTags/*.txt` | un morph par ligne, `: tag` optionnel | — | `PopulateAllMorphTags` |
| `Modules/beauty_standards_default.txt` | `tag: poidsA: poidsB` | — | `PopulateBeautyStandardsDefault`, `getRandomEthnicity`, `getRandomAge` |
| `Modules/Pregnancy_Morphs.txt` | `Morph:valeur` | — | `FillPregnancyMorphs` |
| `Saved/SaveGames/GameSettings.sav` | `GameSettings_C` (63 variables) | `PercentMale/Female/IntSame/IntOpp/IntTrans`, `Fantasy*`, `BodyShapeDistribution`, `BeautyStandards_Custom`, `ModEnableds`, volumes… | `LoadSettings` / `SaveSettings` |
| `Saved/SaveGames/<slot>.sav` | `Save_C` (137 variables) | jour, heure, `GeneratedIndex`, relations, `ActorVars`, `GlobalVariables`, grossesses, IA… | `SaveGame` / `LoadGame` / `NewGame` |
| `Content/Saves/<slot>/Characters/N.lpcharacter` | format `.lpcharacter` | personnages générés | `SavePreset`, `DuplicateCharacters` |
Volumétrie 5.5 (identique à 4.27, 2 051 fichiers) : `vin_Base` 1 394 fichiers dont 752 `.lpscene`,
286 `.lpaction`, 128 `.lpcharacter`, 110 `.lpworld`, 69 `.lpstat` ; 15 autres modules `vin_*`.
36 fichiers de données sont **vides en amont** (34 `.lpscene` de `vin_base/scenes/corruption`,
`strt_white_m.lpcharacter`, `boss_asks_impregnate)cms.lpscene`) : ce n'est pas un défaut du portage.
Structures Blueprint utilisées par les pipelines (`Content/Structs`, 57 au total) : `Variable`,
`ActorVars`, `ChanceMinMax`, `SMBool`, `ActionDetail`, `Scene`, `Quest`, `StatValue`, `ModEnabled`,
`StringArray`, `FloatArray`, `IntArray`, `PersonData`, `MorphSlider`, `NameFloat`, `Cloth`, `Inventory`.
## 5. Pipelines
### 5.1 Démarrage et injection des données
```
GI.ReceiveInit → UpdateFullScreenMode, AssetReg, minuterie 2 s → DelayedStart
DelayedStart → PC.BeginPlay, StreetMap_Static.BeginPlay, LoadSettings, Make10k
LoadSettings : GameSettings.sav → ~60 variables de GI
→ ReadModLauncher (LoadTxt ModLauncher.config) → ParseConfig → ModEnableds
→ removeDeletedMods (GetAllFilesFromFolder "Modules" *.lpmod)
→ DefaultDistributionIfNeeded (presets male/female → BodyShapeDistribution)
→ PopulateRaws
PopulateRaws (pour chaque module activé)
FillNamePool, readUniforms, PopulateAllMorphTags, PopulateBeautyStandardsDefault, FillPregnancyMorphs
GetAllFilesFromFolder("Modules/<id>", *.lpstat|lpaction|lpscene|lptalk|lpdesc|lpquest|lpai)
→ LoadTxt → Raws_* (tableaux de chaînes)
→ PopulateStats → PopulateActions → PopulateScenes → PopulateQuests → PopulateTalksAndDescs
→ PopulateWorldPresets → RemoveNPCOnly → CleanRaws
```
Également au démarrage, appelant non identifié (voir §7) : `donors`, `Clothes4`, `SimplifyMorphs`,
`outfits_*`.
### 5.2 Événements (scènes)
```
Action du joueur : TakeActionWithBuilding / TakeModActionWithBuilding → CheckForScenes
→ LoopCheckForScenes → UpdateCheckForScenes (pour chaque Scene) :
CheckSceneForTimeout → CheckConditionsWhen → CheckConditionsWho → CheckConditionsOther → PlayScene
Autres déclencheurs : UpdateAI (.lpai), actions SCENE_ALWAYS, quêtes (StartQuest → TestScene)
PlayScene : LoadTxt(fichier) → GetValidLines → boucle ReadSceneLine
If/Elseif/Else/Endif/While/Random/Sex( traités en ligne ; variables : GI.Variables (Array<Variable>)
ReadSceneLine → CallFunction (219 commandes) / CallFunctionReturnBool (84 conditions)
fin : DefaultDistribution, destroyAllDummies, clearScenePersons, SceneEnd, Timeout
```
### 5.3 Personnages
```
DSL generatePerson(p1..pn) → GI.GeneratePerson(Presets, Temporary, Relative, MatchRace, VariableToClear) → Person_C
SpawnDummy (réserve de Person_C pré-instanciés, MakeDummyPersons) → BackupCbe → PopulateEachPerson → RandomizeStats
A) presets fournis : pour chaque .lpcharacter dont le nom se termine par le preset → LoadPreset
B) aucun preset : determinePersonVars (Percent*, Fantasy*, MajorityRace, getRandomEthnicity/Age)
→ IsMale, Race, Genital, UpdatePlayerMesh, randomizeName, Person.RandomizeAll
→ ChooseNPCBodyShape(BodyShapeDistribution) → LoadPreset(corps) → MorphRace
→ SavePreset → SaveTxt("Saves/_session/Characters/<GeneratedIndex>.lpcharacter") → AddVariable
LoadPreset : LoadTxt → ReadLine → tirage → GenerateAndApplyFloats (morphs, matériaux)
/ GenerateAndApplyStrings (maillages, cheveux, textures via GetAssetByObjectPath + GetAsset)
/ GenerateAndApplyBools → ResolveConflictingMorphs, Unfat, ShowAppropriateGenital, UpdateProxyMorphs
```
Tout le hasard passe par `KismetMathLibrary` (`RandomFloat`, `RandomBool`, `RandomInteger`…,
`Array_Shuffle`) : pas de graine, pas de `RandomStream`.
### 5.4 Sauvegarde
`SaveGame(Name, Index)` : `SaveSettings` + `CreateSaveGameObject(Save_C)` + ~100 variables +
`SaveGameToSlot`. Personnages : `DuplicateCharacters` copie `Saves/_session/Characters` ↔
`Saves/<slot>/Characters` (`LoadTxt`/`SaveTxt`).
## 6. Dépendances moteur des pipelines (points sensibles au portage)
| Dépendance | Où | Risque 5.5 |
|---|---|---|
| Structures utilisateur avec tableaux (`Variable`) | conteneur de variables du DSL | `Variable.uasset` porte un `DoubleProperty` en 5.5 (conversion LWC) — piste principale du bug ouvert |
| `TMap` dans les `USaveGame` | `Save_C`, `GameSettings_C` | compatibilité des `.sav` existants |
| `GetAssetByObjectPath` + `GetAsset` | chargement de maillages et textures par chemin | API passée à `FSoftObjectPath` ; broches orphelines au portage |
| `SetSkeletalMesh`, `SetMasterPoseComponent`, propriété `SkeletalMesh` | `Person`, `GI`, UI | renommés/dépréciés en 5.1 |
| Composants proxy ajoutés à l'exécution (`AddComponent`) | `Person::NewProxy`, `MorphProxy` | type réel `USkinnedMeshComponent` ≠ `USkeletalMeshComponent` (cause de l'échec de R-03) |
| `FFileHelper`, `IFileManager` sur `ProjectContentDir` | `ModdingExtra` | stable ; exige `Modules` hors paquet |
| `GameplayStatics` SaveGame | `GI` | stable |
## 7. Inconnues à lever (lot L5)
1. Appelants de `ReadOutfits`, `populateClothes4`, `PopulateCharGenPage`, `MakeDummyPersons` (probablement `PC`, `MainMenu` ou une minuterie).
2. Format exact de `ModLauncher.config` (déduit, jamais observé sur disque).
3. Types de valeur de `PerksUnlocked`, `VoiceTypes`, `ActionCount` (`Map<string,?>`).
4. Fin de `GeneratePerson` après `fertility_npc` (conditions de branche vers `ChooseNPCBodyShape`).
5. Fichiers sans chargeur confirmé : `step4_morphs.txt`, `test_output.txt`, `FAQ.txt`, `AllMorphTags.txt`.
6. Contenu binaire de `Default.sav` (un `BodyShapeDistribution` périmé est possible).
## 8. Écarts 5.5 déjà en place (hérités de la campagne du 2026-09-08)
VictoryPlugin retiré et remplacé par `LPVictoryCompat` (+ `[CoreRedirects]`) ; `StreetMap` porté
(LWC, R-01, R-02) ; `ModdingExtra` porté ; `Target.cs` en `BuildSettingsVersion.V5` /
`Unreal5_5` ; 8 562 packages resauvegardés en UE5 ; commandlets de correction R-03 à R-06.
État détaillé et défauts : `02_Audit_Logiciel.md`.