186 lines
13 KiB
Markdown
186 lines
13 KiB
Markdown
|
|
# 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`) |
|
|||
|
|
| `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`.
|