LifePlay-Revival/Docs/Migration/07_Architecture_5.5.md
edujiro5972 d8a0f859ce DC1 : plugin LPAnimCore (LPAnimRedirect, LPCoupleSim) ; LifePlay ne depend plus de LPAnimMeasure (CHG-234)
Plugins/LPAnimCore (Runtime, PreDefault, toutes configurations) recoit la partie runtime
de l'ancien LPAnimMeasure de l'addon. LifePlay.Build.cs : LPAnimMeasure -> LPAnimCore.
LifePlayEditorTools depend encore de LPAnimMeasure jusqu'a DC2. Pin addon 3e9c32f.
Validation : DC1-BUILD code 0, DC1-VAL PASS (tournees Mesure identiques a SB2-REF,
controle visuel utilisateur marche et ShowCouple).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 18:31:01 +02:00

186 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 07 — Architecture de LifePlay en UE 5.5 (état final de la migration)
> Complète `01_Architecture_Initiale.md`, qui décrit le fonctionnement hérité de 4.27 (données texte,
> `ModdingExtra`, interpréteur du DSL dans `GI`). Ce document décrit ce que la migration a ajouté ou
> appris : la couche de compatibilité C++, les sous-systèmes, les différences de comportement du
> moteur et le fonctionnement de la scène (studio, pièces, écran d'appel), mesurés en jeu.
> État au 2026-10-02 : V1.1 publiée, lots L7a à L7l validés.
---
## 1. Vue d'ensemble
```
Content/Modules/** (texte, hors paquet) inchangé depuis 4.27 (2 051 fichiers, MD5 identiques)
│
Plugins/ModdingExtra LoadTxt / SaveTxt / GetAllFilesFromFolder (porté UE5, trace en Verbose)
│
Content/BPs/GI ── interpréteur du DSL, événements, personnages, sauvegarde (Blueprints 4.27,
│ Person, Room, AI, UI/* resauvegardés UE5)
│
│ appels Blueprint redirigés vers la couche de compatibilité (nœuds rebranchés par commandlet)
▼
Source/LifePlay ── bibliothèques de compatibilité (comportement 4.27 garanti)
│ LPStringCompat · LPMeshCompat · LPNavigationHelpers
│ LPAssetRegistryHelpers · LPVictoryCompat
│
└── sous-systèmes d'instance de jeu (aucun Blueprint modifié)
LPSessionLog (journal, diagnostic) · LPSecondScreen (caméra d'appel)
LPOutdoorRoom (plafond des lieux extérieurs)
Source/LifePlayEditorTools ── commandlets d'analyse et de correction (éditeur uniquement)
Plugins/StreetMap (280 villes, porté LWC) Plugins/McpAutomationBridge (éditeur uniquement)
```
Principe directeur : **les Blueprints de gameplay restent ceux de 4.27**. Chaque écart de comportement
du moteur est corrigé soit en rebranchant des nœuds vers une fonction C++ qui reproduit le comportement
4.27 (corrections « CX-B »), soit par un sous-système C++ qui agit à l'exécution sans toucher aux
assets.
## 2. Modules C++
### 2.1 `Source/LifePlay` (runtime, livré avec le jeu)
| Classe | Type | Rôle | Introduit par |
|---|---|---|---|
| `ULPAssetRegistryHelpers` | bibliothèque Blueprint | `GetAssetByObjectPath` en nœud **pur** (le moteur l'a rendu impur) ; `GetAssetsByClassName`, `GetAssetObjectPath` (paramètre `FName` → `FTopLevelAssetPath`) | portage 4.27 ; CX-B01 |
| `ULPVictoryCompat` | bibliothèque Blueprint | les 2 nœuds du Victory Plugin réellement utilisés (`LoadTexture2D_FromFile`, `SaveStringToOSClipboard`) ; `[CoreRedirects]` dans `DefaultEngine.ini` | CX-C06 |
| `ULPStringCompat` | bibliothèque Blueprint | `ParseIntoArray`, `Contains`, `Split`, `FindSubstring`, `FindUE4` avec la sémantique **UE 4.27** (§4) | CX-B08, CX-B12 |
| `ULPMeshCompat` | bibliothèque Blueprint | `GetSkeletalMesh(Component)` = `Cast<USkeletalMesh>(GetSkinnedAsset())`, valable pour tout `USkinnedMeshComponent` (les proxys de `Person` n'en sont pas des `USkeletalMeshComponent`) | CX-B10 |
| `ULPNavigationHelpers` | bibliothèque Blueprint | `GetRandomLocationInNavigableRadius` en nœud **pur** (le remplaçant moteur est impur) | CX-B11 |
| `ULPSessionLogSubsystem` | `UGameInstanceSubsystem` | résumé de démarrage, bilan de session dédoublonné, outils de diagnostic sur option de ligne de commande (§5) | L3, L5, L7i, L7l |
| `ULPSecondScreenSubsystem` | `UGameInstanceSubsystem` | à chaque image, cadre la caméra `SecondScreen` sur le visage du contact affiché (`GI.SecondScreenPerson`) | L7j (ERR-031) |
| `ULPOutdoorRoomSubsystem` | `UGameInstanceSubsystem` | masque le plafond `WallT` de la pièce quand l'échelle Z de sa racine est < 0,05 (lieux extérieurs) | L7l (ERR-036) |
| `ALifePlayGameModeBase` | — | vide ; le vrai mode de jeu est `/Game/BPs/GM` | 4.27 |
Dépendances (`LifePlay.Build.cs`) : publiques `Core`, `CoreUObject`, `Engine`, `InputCore`,
`AssetRegistry`, `NavigationSystem` ; privées `ImageWrapper`, `ApplicationCore`, `EngineSettings`.
Structure plate (pas de sous-dossier `Public/`) : `PublicIncludePaths.Add(ModuleDirectory)`.
### 2.2 `Source/LifePlayEditorTools` (éditeur uniquement)
24 commandlets, en trois familles (catalogue et usages : `08_Guide_Developpeur.md` §5) :
- **analyse en lecture seule** : `LPDumpFunction`, `LPDumpAssets`, `LPDumpComponents`,
`LPDumpWidgetTree`, `LPDumpCDO`, `LPDumpSave`, `LPCheckMeshAssignment`, `LPCheckStreetMap`,
`LPCheckMeshes`, `LPTestStringCompat` ;
- **correction de graphes** (rebranchement de nœuds, contrôle broche par broche intégré, `-DryRun`) :
`LPFixAssetRegistryNodes`, `LPFixAssetRegistryPins`, `LPFixEditableTextBoxFont`,
`LPFixOrphanBoundEvents`, `LPFixParseIntoArray`, `LPFixButtonPadding`, `LPFixSkeletalMeshGet`,
`LPFixNavRandomPoint`, `LPFixStringSearch` ;
- **correction de cartes ou de paquets** : `LPFixZeroScaleActors`, `LPConvertAtmosphericFog`,
`LPFixSceneCapture`, `LPResavePackages`.
`LPFixDeprecatedNodes` (R-03/R-04 d'origine) est conservé pour l'historique mais **ne doit plus
être utilisé** : sa variante R-03 aggrave ERR-002 (CX-B05 rejeté), sa variante R-04 est remplacée par
`LPFixNavRandomPoint`.
### 2.3 Plugins
| Plugin | Cible | Remarque |
|---|---|---|
| `ModdingExtra` | runtime | entrée/sortie des données ; trace d'appel en catégorie `LogModdingExtra` (`Verbose`) |
| `LPAnimCore` | runtime | lot DC1 : `LPAnimRedirect` (redirection des clips) et `LPCoupleSim` (géométrie du couple), rapatriés de l'addon ; module `LPAnimCore` dans `Plugins/LPAnimCore` |
| `StreetMap` | runtime | porté LWC ; 280 villes vérifiées identiques à 4.27 (L7h) |
| `EnhancedInput` | runtime | système d'entrée actif ; exécute les 34 actions héritées de `DefaultInput.ini` |
| `McpAutomationBridge` | **éditeur uniquement** (`TargetAllowList: Editor`) | pilotage de l'éditeur par serveur MCP ; jamais publié (contient un jeton) |
| `AndroidFileServer` | désactivé | réécrivait un `SecurityToken` dans `DefaultEngine.ini` (ERR-023) |
## 3. Configuration (écarts à 4.27)
| Fichier | Clé | Valeur | Raison |
|---|---|---|---|
| `DefaultGame.ini` | `+DirectoriesToAlwaysCook=(Path="/Game")` | — | assets chargés par chemin texte : sans cela, 3 257 paquets cuits au lieu de 8 561 (ERR-026) |
| `DefaultGame.ini` | `DirectoriesToAlwaysStageAsNonUFS=Modules`, `UsePakFile=False` | inchangés | `Modules` en fichiers nus, comme la version de l'auteur |
| `DefaultGame.ini` | clés de nativisation | retirées | inexistantes en UE5 (L7c) |
| `DefaultEngine.ini` | `r.DynamicGlobalIlluminationMethod=0`, `r.ReflectionMethod=2`, `r.Shadow.Virtual.Enable=0` | explicites | rendu identique à celui validé, indépendant des valeurs par défaut du moteur (L7c) |
| `DefaultEngine.ini` | `DefaultGraphicsRHI_DX12` | explicite | idem |
| `DefaultEngine.ini` | `r.AntiAliasingMethod=2` (TAA) | explicite (`r.DefaultFeature.AntiAliasing` est ignorée par UE5) | supprime le scintillement à l'approche des personnages (ERR-032, L6a) |
| `DefaultEngine.ini` | `[CoreRedirects]` Victory → `LPVictoryCompat` | — | chargement de `GI`, `MainMenu`, `Inventory`… |
| `DefaultEngine.ini` | 4 clés PhysX | retirées | PhysX n'existe plus (Chaos) |
| `LifePlay.uproject` | `TargetPlatforms: ["Windows"]`, plugins explicites | — | L2 |
## 4. Différences de comportement du moteur découvertes (UE 4.27 → 5.5)
Aucune n'est signalée par le compilateur : un graphe identique donne un résultat différent. Elles
expliquent l'essentiel des défauts de la migration.
| # | API | UE 4.27 | UE 5.5 | Effet dans LifePlay | Correction |
|---|---|---|---|---|---|
| 1 | `IAssetRegistry::GetAssetsByClass` | paramètre `FName ClassName` | `FTopLevelAssetPath` ; la valeur est **perdue** à la montée de version | aucun corps, vêtement, coiffure énumérable : personnages identiques (ERR-002) | CX-B01 |
| 2 | `FString::ParseIntoArray("")` | `[]` | `[""]` ; séparateur insensible à la casse | `generatePerson()` charge les 141 presets : personnages invisibles (ERR-027) | CX-B08 |
| 3 | `FString::Find("", IgnoreCase, FromStart)` | `INDEX_NONE` | `0` | `Contains(x, "")` vrai : filtres de morphs sans effet (ERR-005), erreurs en cascade (ERR-006/007) | CX-B12 |
| 4 | style par défaut de `UButton` | marge 2,2,2,2 (`FCoreStyle`) | 12,1.5,12,1.5 (`FUMGCoreStyle`) | les assets 4.27 ne stockent pas la valeur par défaut : barre de temps décalée (ERR-034) | CX-B09 |
| 5 | `USkinnedMeshComponent::SkeletalMesh` | propriété | dépréciée ; `GetSkeletalMeshAsset()` n'existe que sur `USkeletalMeshComponent` | un remplacement naïf renvoie `None` sur les proxys (CX-B05 rejeté) | CX-B10 |
| 6 | `GetAssetByObjectPath`, `K2_GetRandomLocationInNavigableRadius` | purs | impurs | un rebranchement naïf ajoute des broches d'exécution non reliées : nœud élagué | helpers purs |
| 7 | `FEditableTextBoxStyle::Font` | champ | `TextStyle.Font` | broche orpheline : cuisson en échec (ERR-021) | CX-B02 |
| 8 | `AAtmosphericFog` | classe active | dépréciée, convertie en `SkyAtmosphere` au chargement | aucun changement visible | L7d (remplacement explicite) |
| 9 | Shipping (`NO_LOGGING`) | — | les catégories de journal deviennent `FNoLoggingCategory` sans `GetCategoryName` | compilation Shipping en échec | `FName` constant (L7g) |
Leçon générale : **une propriété sérialisée en delta prend silencieusement la nouvelle valeur par
défaut du moteur** (#4), et **une fonction de chaîne peut changer de sémantique sur les cas limites**
(#2, #3). Comparer les sources du moteur 4.27 et 5.5 sur ces cas avant de conclure.
## 5. Journalisation et diagnostic (`ULPSessionLogSubsystem`)
Le sous-système n'altère aucun message existant (les comparaisons A/B avec 4.27 en dépendent). Il
ajoute :
- au démarrage : `===== LifePlay : demarrage =====` (versions, modules, fichiers par type, échecs
`LoadTxt`) ;
- à la fermeture ou par la commande console `LifePlay.LogSummary` : `===== LifePlay : bilan de
session` (volume par catégorie, signatures d'erreurs dédoublonnées) ;
- des outils activés par la ligne de commande, tous inactifs par défaut (liste dans
`09_Commandes_Utiles.md` §4) : variables de `GI` au démarrage et à la fin (`-LPDumpVars`),
trace des exceptions de script avec variables locales et cadres appelants (`-LPTraceScriptEx`…),
relevé de chemins d'objets sur un motif du journal (`-LPDumpOnLog`) ou périodique
(`-LPDumpEvery`).
Un chemin de relevé part de l'instance de jeu et suit les propriétés objet ou structure :
`Room.WallT.RelativeLocation`, `PlayerCharacter.CapsuleComponent.CapsuleHalfHeight`… C'est ce qui a
permis de mesurer la cause réelle d'ERR-036 (le plafond), là où l'analyse statique des données
désignait à tort une dalle de neige.
## 6. Scène, pièces et écran d'appel (mesurés en jeu)
### 6.1 Studio unique
Tous les lieux (bâtiments, extérieurs) sont construits par **un seul acteur `Room_C_0`** placé dans un
studio, en (−3 131 543 ; −14 967 213 ; −115) de `CentralLondon`. Pendant une visite, la ville
(`StreetMapStatic`) est masquée.
### 6.2 Pièce et échelle `.lpworld`
- La racine de `Room` (cube, matériau `FntWall`) prend l'**échelle de la première ligne du `.lpworld`**.
- Les meubles sont positionnés et dimensionnés relativement à cette racine : leurs hauteurs sont donc
multipliées par l'échelle Z.
- Échelles Z déclarées : 81 lieux à 0,2, 5 à 0,3, 1 à 0,4, et **0,01 pour les 7 lieux extérieurs**
(`beach`, `forest`, `mountain`, `park`, `pool`, `river`, `street`).
- Le plafond `WallT` (Z relatif 2 040, sans collision) suit l'échelle : 4,08 m en intérieur, mais
18 à 20 cm au-dessus du sol en extérieur, où il masquait pieds et pieds de meubles (ERR-036,
défaut d'origine 4.27). `ULPOutdoorRoomSubsystem` le masque en extérieur et le rend en intérieur.
### 6.3 Écran d'appel (second écran)
- `GI::Show` place le contact sur son emplacement de scène décalé de −10 000 000 en Y, sur la copie
de scène `SecondScreenFloor`.
- La caméra `SceneCapture2D` `SecondScreen` rend vers `Render/SecondScreen`, affiché par
`UI/Scene::FaceRender`.
- Dans la carte 4.27 d'origine, cette caméra n'avait pas de racine et filmait le ciel (ERR-031,
défaut d'origine). L7j lui a donné une racine (`LPFixSceneCapture`), et
`ULPSecondScreenSubsystem` la cadre à chaque image : 80 cm devant l'os `head` du contact, champ de
30°.
### 6.4 Ciel
`BP_Sky_Sphere` (matériau `M_Sky_Panning_Clouds2`), lumière directionnelle `Sun`, `SkyLight` à
cubemap, `SkyAtmosphere` (ex-`AtmosphericFog`, Z −100 000, `PlanetTopAtComponentTransform`). Le soleil
ne suit pas l'heure : la nuit reste claire en extérieur, **comme en 4.27**. Un grand disque blanc à
l'horizon existe déjà avant L7d (origine non étudiée).
### 6.5 Variables du DSL
`GI::GetVariable` traite à part les noms spéciaux (`Player`, `Ptr`, `Interacting`, `CurrentCompanion`,
`A1` à `A5`) par un `SwitchString`. La variable `AI` est un `AIDummy`. Les variables `Person` vides
signalées en jeu (ERR-003) existent au même taux en 4.27.
## 7. Ce qui reste hérité tel quel
Effets Cascade (4 systèmes, pris en charge par UE 5.5), entrées héritées exécutées par Enhanced Input,
éclairage dynamique sans précalcul. Défauts d'origine 4.27 conservés : ERR-030 (habillage), ERR-037
(Quick dress), nuit claire, disque blanc. Voir `Registre_Erreurs.md`.