670 lines
No EOL
44 KiB
Markdown
670 lines
No EOL
44 KiB
Markdown
# 11 — Audit d'optimisation UE 5.5 (lot O0)
|
||
|
||
> Chantier ouvert le 2026-10-02, après la migration (V1.1). Objectifs fixés par l'utilisateur :
|
||
> ressources obsolètes ou gourmandes, goulots d'étranglement, organisation des dossiers, optimisations
|
||
> propres à UE5, suppression du superflu, outils et exemples Fab.
|
||
> Ce document est le **lot O0** : mesures en lecture seule, aucune modification du projet. Les lots O1
|
||
> et suivants (§6) suivent `10_Protocole_Operations.md`.
|
||
|
||
---
|
||
|
||
## 1. Méthode et outils
|
||
|
||
| Mesure | Outil | Résultat |
|
||
|---|---|---|
|
||
| Inventaire des 8 563 assets (classe, taille, tags, références) sans chargement | `Tools/AuditAssets.py` (registre d'assets, exécuté par `-run=pythonscript`) | `Saved/Audit/assets.jsonl` |
|
||
| Noms d'assets cités par les données et les Blueprints | croisement avec le texte de `Content/Modules` et les tables de noms de `BPs`, `UI`, `Scenes` | `Saved/Audit/candidats_jamais_nommes.json` |
|
||
| Composition du build livré | build Shipping V1.1 (`LifePlay_Build_5.5_Shipping`) | §3 |
|
||
| Performances en jeu | profileur CSV + suivi mémoire LLM : `LifePlay_profil_O0.bat` (build L7cdj) | **à faire par l'utilisateur** (§5) |
|
||
|
||
Contrainte découverte, déterminante pour toute suppression ou réorganisation : **le jeu désigne la
|
||
plupart des assets par leur nom court** (`Clothes4.txt`, `.lpworld`, `.lpcharacter`), et les retrouve
|
||
en parcourant le registre par classe (`GetAssetsByClass`). Un asset sans référence dans le registre
|
||
peut donc être utilisé en jeu. Seules 5 lignes de données citent un chemin `/Game/` complet (lunettes
|
||
de `New3/Clothes`).
|
||
|
||
## 2. Contenu du projet (6,44 Go, 24 912 fichiers)
|
||
|
||
| Classe | Nombre | Taille source | Constat |
|
||
|---|---:|---:|---|
|
||
| `SkeletalMesh` | 1 057 | **4,08 Go** | 100 % à **un seul LOD** ; **54 536 morph targets** au total |
|
||
| `AnimSequence` | 1 705 | 819 Mo | `New2/Anims2` 481, `New3/Anims` 418, `New2/Daily` 344, `Daz/Anims` 313 |
|
||
| `Texture2D` | 2 969 | 810 Mo | majoritairement ≤ 1024 ; 68 en 2K/4K (visages, corps) |
|
||
| `SoundWave` | 419 | 208 Mo | presque tous dans `New2` |
|
||
| `MaterialInstanceConstant` | 1 180 | 132 Mo | — |
|
||
| `StaticMesh` | 650 | 128 Mo | 637 à un seul LOD ; `fnt_decor14` 180 000 triangles |
|
||
| Blueprints, widgets | 100 | 116 Mo | `GI` 50 Mo, `Person` 20 Mo |
|
||
|
||
Répartition des maillages squelettiques :
|
||
|
||
| Dossier | Maillages | Taille | Morph targets |
|
||
|---|---:|---:|---:|
|
||
| `Heavy/Clothes4` (vêtements) | 940 | 2,43 Go | **45 936** (≈ 49 par vêtement) |
|
||
| `Heavy/Daz` (corps, cheveux) | 22 | 633 Mo | 5 257 (`bridget_gp` : 1 070, 132 Mo) |
|
||
| `Heavy/New2` | 44 | 543 Mo | 1 570 |
|
||
| `Heavy/New3` | 36 | 360 Mo | 1 675 |
|
||
| `Heavy/New4` | 15 | 113 Mo | 98 |
|
||
|
||
Les vêtements portent chacun une copie des morphs du corps pour suivre la morphologie : c'est le
|
||
premier poste de taille, et un coût par personnage à l'exécution (§4).
|
||
|
||
Textures :
|
||
- **835 textures non streamées** (`NeverStream`) et **794 sans mipmaps**, dont 541 icônes de
|
||
`New3/UI` (normal pour de l'interface).
|
||
- Le reste concerne des textures 3D (`Clothes4/Materials` 43, `New2/Furniture` 41, `Daz/Michael` 34,
|
||
`New4/Hairs` 17, `New2/Beasts` 13) : sans mipmaps, elles scintillent à distance et occupent toujours
|
||
leur pleine résolution en mémoire vidéo.
|
||
- Toutes les textures sont dans le groupe `World`, y compris l'interface ; seules 37 sont en
|
||
compression normal map.
|
||
|
||
## 3. Build livré (Shipping V1.1 : 3,17 Go)
|
||
|
||
| Poste | Taille | Constat |
|
||
|---|---:|---|
|
||
| `LifePlay/Content/Heavy` (cuit) | 2,50 Go | paquets **non compressés** (`bCompressed=False`, pas de pak) |
|
||
| `LifePlay-Win64-Shipping.pdb` | **207 Mo** | symboles de débogage livrés par erreur (inutiles au joueur) |
|
||
| `LifePlay-Win64-Shipping.exe` | 140 Mo | inclut tous les plugins moteur activés |
|
||
| `Engine/Plugins/NNE` (débruiteur IA, ONNX Runtime) | **119 Mo** | inutilisé par LifePlay ; activé par défaut par le moteur |
|
||
| `DirectML.dll`, `d3d12SDKLayers.dll` | 19 Mo | DirectML : dépendance de NNE ; SDK Layers : couche de débogage D3D12 |
|
||
| `Engine/Plugins/Interchange` | 12 Mo | import d'assets, inutile en jeu |
|
||
| `LifePlay/Content/Movies` | 79 Mo | vidéo d'intro |
|
||
| `LifePlay/Content/Modules` | 14 Mo | données texte (doivent rester en fichiers nus) |
|
||
|
||
Plugins moteur présents dans le build sans usage connu en jeu : `NNE`, `Interchange`, `Fab`, `Bridge`,
|
||
`SpeedTreeImporter`, `MovieRenderPipeline`, `Paper2D`, `USDCore`, `HairStrands`… Plusieurs viennent des
|
||
dépendances de `McpAutomationBridge` (outil d'éditeur, ERR-024) ou de l'activation par défaut du moteur.
|
||
|
||
## 4. Goulots probables (à confirmer par la mesure du §5)
|
||
|
||
| # | Hypothèse | Indice | Mesure qui tranchera |
|
||
|---|---|---|---|
|
||
| G1 | **Coût CPU des personnages** : jusqu'à des centaines de PNJ générés, chacun avec corps, cheveux et vêtements à morphs, animés à chaque image même hors champ | 339 personnages générés en 2 h (V1) ; aucun LOD, aucune optimisation de fréquence d'animation | temps du thread de jeu et d'animation (CSV) selon le nombre de PNJ visibles |
|
||
| G2 | **Morph targets** : 45 936 sur les vêtements, recalculés pour chaque personnage | `bridget_gp` 1 070 morphs | temps GPU/CPU de déformation, mémoire `Meshes` (LLM) |
|
||
| G3 | **Tick des Blueprints** `GI` et `Person` (interpréteur du DSL, IA) | 606 fonctions dans `GI` | temps du thread de jeu hors animation |
|
||
| G4 | **Mémoire vidéo** : textures non streamées et maillages sans LOD | §2 | LLM `Textures`, `Meshes` |
|
||
| G5 | **Temps de chargement** : 2,5 Go de paquets non compressés, chargés par chemin | build Shipping | durée du démarrage et des changements de lieu (journal) |
|
||
|
||
## 5. Mesure en jeu à réaliser
|
||
|
||
Dans `D:\Game\LifePlay_Build_5.5_L7cdj\Windows`, lancer **`LifePlay_profil_O0.bat`** (et non
|
||
`LifePlay.exe`) puis jouer environ **15 minutes** :
|
||
1. charger une partie avancée (nombreux contacts), rester 2 minutes sur la carte de la ville ;
|
||
2. un lieu intérieur peuplé, 2 minutes ;
|
||
3. un lieu extérieur peuplé (parc, plage), 2 minutes ;
|
||
4. une scène avec plusieurs personnages ;
|
||
5. quitter normalement.
|
||
|
||
Résultats : `Windows\LifePlay\Saved\Profiling\CSV\*.csv` (temps par image, thread de jeu, rendu, GPU,
|
||
par tranche de 9 000 images) et `Saved\Profiling\LLM\*.csv` (mémoire par catégorie). Ils serviront de
|
||
**référence** : chaque lot O1+ sera mesuré à l'identique, avant et après.
|
||
|
||
## 6. Leviers classés et lots proposés
|
||
|
||
| Lot | Levier | Gain attendu | Risque | Changement de comportement |
|
||
|---|---|---|---|---|
|
||
| **O1** | Build : désactiver les plugins moteur inutiles au jeu (`NNE`, `Interchange`, `Fab`, `Bridge`…), ne plus livrer le `.pdb` ni les couches de débogage D3D12 | **≈ 350 Mo** sur 3,17 Go, exécutable plus petit, démarrage plus court | faible (vérifier que `ControlRig`, `IKRig`, `HairStrands` ne sont pas utilisés par les assets) | aucun |
|
||
| **O2** | Paquets compressés (IoStore + Oodle) pour `Content`, `Modules` restant en fichiers nus | taille du jeu et temps de chargement (à mesurer : souvent −30 à −50 %) | moyen : la version de l'auteur était en fichiers nus ; vérifier que les mods n'ajoutent que du texte | aucun pour le joueur |
|
||
| **O3** | Fréquence d'animation des PNJ : `VisibilityBasedAnimTickOption` (pas d'animation hors champ), optimisation de fréquence (URO), voire Animation Budget Allocator. Appliqué par un sous-système C++, sans modifier `Person` | thread de jeu (G1), proportionnel au nombre de PNJ | faible | PNJ hors champ figés (invisible au joueur) |
|
||
| **O4** | Textures 3D sans mipmaps (≈ 130) : génération des mipmaps et streaming ; textures d'interface dans le groupe `UI` | mémoire vidéo, scintillement à distance | faible | rendu plus net à distance |
|
||
| **O5** | LOD des maillages squelettiques (corps, cheveux, vêtements) par la réduction intégrée d'UE5 | GPU et mémoire avec beaucoup de PNJ | moyen : les morphs doivent suivre sur les LOD ; contrôle visuel | légère simplification à distance |
|
||
| **O6** | Morph targets inutilisés des vêtements : retirer ceux qu'aucune donnée ni aucun Blueprint ne pilote | taille (2,4 Go de vêtements) et coût de déformation | élevé : il faut la liste exacte des morphs pilotés (`.lpcharacter`, `MorphTags`, `Person`) | aucun si la liste est exacte |
|
||
| **O7** | Organisation : déplacer les sauvegardes de développement de `Content/Saves` (14 125 fichiers, 239 parties, non versionnées) hors du projet ; plan de nommage des dossiers `Heavy/New`, `New2`… | lisibilité, éditeur plus rapide à indexer | les déplacements d'assets demandent des redirecteurs et un contrôle des 5 chemins `/Game/` des données | aucun |
|
||
| **O8** | Supprimer les 258 assets jamais nommés ni référencés (animations `Daz/Anims`, icônes `New3/UI`…) | **60 Mo seulement** (1 %) | moyen : un nom peut être construit par concaténation dans un Blueprint | aucun si l'analyse est juste |
|
||
|
||
Conclusion de l'audit statique : **supprimer des assets rapporte peu** (O8). Les vrais gains de taille
|
||
sont dans le **build** (O1, O2) et dans les **morphs des vêtements** (O6). Les gains de fluidité sont
|
||
dans **l'animation et la déformation des personnages** (O3, O5, O6), à confirmer par la mesure du §5.
|
||
|
||
Ordre recommandé : O1 (sans risque, gain immédiat), puis mesure §5, puis O3 et O4, puis O2, O5, O6 selon
|
||
les résultats ; O7 et O8 en dernier.
|
||
|
||
## 7. Fonctions UE5 utiles, déjà dans le moteur
|
||
|
||
| Fonction | Usage pour LifePlay |
|
||
|---|---|
|
||
| Unreal Insights, profileur CSV, LLM | mesure (§5) |
|
||
| Size Map, Asset Audit, Reference Viewer (éditeur) | vérifier les dépendances avant O1, O7, O8 |
|
||
| Réduction de maillage squelettique intégrée | LOD des personnages (O5) |
|
||
| Animation Budget Allocator (plugin moteur), URO, `VisibilityBasedAnimTickOption` | coût d'animation des PNJ (O3) |
|
||
| Significance Manager (plugin moteur) | prioriser les PNJ proches |
|
||
| IoStore, compression Oodle | taille et chargement (O2) |
|
||
| Texture streaming, groupes de LOD de texture | mémoire vidéo (O4) |
|
||
|
||
Nanite ne s'applique pas aux personnages en 5.5 dans un cadre stable (maillages squelettiques) ; les
|
||
maillages statiques de LifePlay sont légers, sauf `CentralLondon` (1,08 million de triangles) et
|
||
`fnt_decor14` : Nanite pourrait être évalué pour ces deux-là seulement.
|
||
|
||
## 8. Fab
|
||
|
||
Recherche publique « optimization » (2026-10-02, sans connexion) : la plupart des outils sont payants
|
||
(10 à 150 €) et génériques. Ils reprennent pour l'essentiel les fonctions du §7 : optimisation du tick,
|
||
Significance, outils de mesure, instanciation. Candidats à examiner, au choix de l'utilisateur :
|
||
- gratuits : *Ultimate Optimization Toolkit* (IchiQ), *Optimization Tools plugin* (Creative Elicya) ;
|
||
- adaptés aux nombreux PNJ : *Significance Optimizer* (MateoPlugins), *Flex Significance*
|
||
(GameRec Studios), *Open World NPC Optimization* (Sergio Cavalli) ;
|
||
- gestion des assets : *Project Optimization Toolkit* (Leartes Tools).
|
||
|
||
Règles :
|
||
- l'ajout d'un produit à la bibliothèque Fab se fait par l'utilisateur, avec son compte ;
|
||
- tout plugin tiers est évalué **dans une copie du projet**, jamais livré sans lot dédié ;
|
||
- il ne doit jamais devenir une dépendance du build sans accord.
|
||
|
||
Recommandation : commencer par les fonctions du moteur (§7), qui couvrent les besoins identifiés sans
|
||
dépendance nouvelle.
|
||
|
||
## 9. Résultats de la mesure en jeu (2026-10-02)
|
||
|
||
Build L7cdj (Development), `LifePlay_profil_O0.bat`, ≈ 12 minutes de jeu sur une machine AMD Ryzen 7 5800H avec carte graphique Radeon :
|
||
4 tranches complètes de 9 000 images (36 004 images). Données archivées dans
|
||
`D:\Game\LifePlay_Backup_5.5\O0_profil_20261002`, journal `Saved/Logs/portage/O0_profil_20261002.log`.
|
||
|
||
> Lancement : la capture CSV doit être démarrée par `-ExecCmds="csvprofile repeat=20, csvprofile frames=9000"`.
|
||
> L'option `-csvCaptureFrames` sur la ligne de commande démarre la capture avant l'initialisation du rendu, et le
|
||
> moteur s'arrête (`IsRayTracingAllowed() may only be called once RHI is initialized`).
|
||
|
||
### 9.1 Régime normal : aucun goulot
|
||
|
||
| Mesure (médiane par tranche) | Valeur |
|
||
|---|---|
|
||
| Temps d'image | **16,7 ms** : le jeu est plafonné à 60 images/s et tient ce plafond |
|
||
| Thread de jeu | 3,9 à 4,4 ms |
|
||
| Thread de rendu | 7,8 à 8,5 ms (dont ≈ 9 ms d'attente, `EventWait`) |
|
||
| GPU | 7,3 à 11,1 ms |
|
||
|
||
Il reste environ deux fois de marge sur chaque thread. Les hypothèses G1, G2 et G4 (§4) ne se vérifient
|
||
pas en régime normal sur cette machine.
|
||
|
||
### 9.2 Le vrai problème : les à-coups du thread de jeu
|
||
|
||
| Seuil | Images concernées (sur 36 004) |
|
||
|---|---:|
|
||
| > 33 ms | 262 |
|
||
| > 50 ms | 159 |
|
||
| > 100 ms | 112 |
|
||
| > 250 ms | 43 |
|
||
| > 1 s | 3 (chargement de partie : 31,5 s ; application des réglages : 5,4 s ; 1,7 s) |
|
||
|
||
- Les images longues durent **de 0,5 à 0,9 s**, à intervalles irréguliers, plusieurs fois par minute ; le
|
||
thread de jeu en est la cause, le rendu restant à 8 ms.
|
||
- Dans ces images, le temps va aux **minuteries Blueprint** (`TimerManager`, 38 s cumulées) et aux nœuds
|
||
`Delay` (`FlushLatentActions`, 9 s cumulées).
|
||
- Ce sont les traitements de `GI` déclenchés par minuterie : passage du temps, IA, recherche de scènes,
|
||
génération de personnages avec lecture de fichiers texte et chargement synchrone de maillages.
|
||
|
||
**Nouvelle priorité : G6, à-coups des traitements Blueprint sur minuterie.** Le CSV ne nomme pas les
|
||
fonctions Blueprint. L'étape suivante est une trace Unreal Insights avec les événements nommés
|
||
(`-trace=cpu,frame,loadtime -statnamedevents`), pour identifier les fonctions de `GI` en cause et les
|
||
chargements synchrones.
|
||
|
||
### 9.3 Mémoire (fin de session, LLM)
|
||
|
||
| Catégorie | Mo |
|
||
|---|---:|
|
||
| Total processus | 3 546 |
|
||
| Textures | 624 |
|
||
| **Physique (Chaos)** | **463**, dont 124 de structures d'accélération et 92 de maillages de collision (trimesh) |
|
||
| UObject | 226 |
|
||
| Cibles de rendu | 215 |
|
||
| Maillages | 75 |
|
||
|
||
La physique occupe presque autant que les textures. Hypothèse : collisions détaillées du maillage de la
|
||
ville (`CentralLondon`, 1,08 million de triangles) et des meubles. Ce poste devient le levier mémoire n° 1.
|
||
|
||
### 9.4 Lots révisés
|
||
|
||
| Ordre | Lot | Justification |
|
||
|---|---|---|
|
||
| 1 | **O1** build (plugins, `.pdb`) | inchangé : gain sûr de ≈ 350 Mo |
|
||
| 2 | **O9** (nouveau) : trace Insights des à-coups, puis correction ciblée (chargement asynchrone, étalement des traitements) | seul défaut ressenti en jeu |
|
||
| 3 | **O10** (nouveau) : collisions (ville et meubles) | 463 Mo de physique |
|
||
| 4 | O4 textures, O2 compression | mémoire vidéo, taille |
|
||
| — | O3, O5, O6 (animation, LOD, morphs) | **reportés** : aucun goulot mesuré en régime normal ; à remesurer sur une machine plus modeste |
|
||
|
||
## 10. Bibliothèque Fab de l'utilisateur (lue le 2026-10-02 sur fab.com)
|
||
|
||
La bibliothèque compte environ 3 000 produits, dont 302 outils et plugins. Produits utiles au chantier,
|
||
**déjà possédés** :
|
||
|
||
| Produit | Éditeur | Intérêt pour LifePlay |
|
||
|---|---|---|
|
||
| Ultimate Optimization Toolkit | IchiQ | mesure et débogage des performances (O9) |
|
||
| Optimization Tools plugin | Creative Elicya | outils d'optimisation de niveau |
|
||
| Asset Analytics | Mohsen Tabasi | analyse du poids et de l'usage des assets (O7, O8) |
|
||
| Dash — Advanced Asset Manager | Polygonflow | gestion et recherche d'assets (O7) |
|
||
| Assets Auto Organizer | Beta Projects | réorganisation des dossiers (O7) : **à n'utiliser qu'avec redirecteurs et vérification**, le jeu cherchant les assets par nom |
|
||
| Asset Naming Convention Keeper ; Asset Sanitizer | Tobosoksini Games ; MallHockE | conventions de nommage (O7) |
|
||
| Ultimate UE5 Project Organizer | Iron Cauldron | modèle d'arborescence (O7) |
|
||
| **MetaHuman Crowd Sample** | Epic Games | **exemple officiel de foule optimisée** (budget d'animation, LOD) : référence pour O3/O5 |
|
||
| AssetDump: Agents-readable assets | fallingsappy | export lisible des assets pour un agent : pourrait compléter `AuditAssets.py` |
|
||
|
||
**Ajouts du 2026-10-02** (4 outils) : *UNOMi* (synchronisation labiale par IA, service en ligne avec compte), *Crimson Object
|
||
Pool* (réutilisation d'acteurs au lieu de les créer et détruire), *Crimson Input*, *Crimson Interaction*. **Tous ne
|
||
déclarent qu'UE 5.8** : ils sont distribués compilés pour cette version et sont inutilisables tels quels en 5.5. L'idée
|
||
de *Crimson Object Pool* est déjà appliquée par LifePlay, qui garde une réserve de personnages pré-créés
|
||
(`DummyPersons`, `SpawnDummy`).
|
||
|
||
Rien n'a été acheté, réclamé ni téléchargé. Chaque outil retenu sera évalué dans une copie du projet,
|
||
dans un lot dédié, avec l'accord de l'utilisateur.
|
||
|
||
## 11. Lot O1 : build allégé (2026-10-02)
|
||
|
||
| Modification | Fichier |
|
||
|---|---|
|
||
| 20 plugins moteur limités à l'éditeur (`"TargetAllowList": ["Editor"]`) : `NNEDenoiser`, `NNERuntimeORT`, `Interchange`, `InterchangeAssets`, `InterchangeTests`, `Fab`, `Bridge`, `MetaHumanSDK`, `SpeedTreeImporter`, `HairStrands`, `MovieRenderPipeline`, `Paper2D`, `USDCore`, `ChaosVD`, `LiveLink`, `ConcertMain`, `ConcertSyncClient`, `ConcertSyncCore`, `Takes`, `PythonScriptPlugin` | `LifePlay.uproject` |
|
||
| Leur contenu n'est plus cuit (`+DirectoriesToNeverCook`) : sans cela, la cuisson échoue sur les pipelines `Interchange` | `Config/DefaultGame.ini` |
|
||
| Build sans symboles de débogage (`-nodebuginfo`) | commande de build |
|
||
|
||
Justification : `Tools/AuditScriptDeps.py` (dépendances des 8 563 assets, lecture seule) montre que le contenu n'utilise
|
||
que 24 modules de code, dont aucun des plugins retirés. L'éditeur et l'outil MCP les gardent.
|
||
|
||
Piège : la cuisson incrémentale (`-iterate`) garde le contenu déjà cuit des plugins retirés ; il a été déplacé vers
|
||
`D:\Game\LifePlay_Backup_5.5\O1\_cuisson_retiree`.
|
||
|
||
| Build Shipping | Avant (V1.1) | Après (O1) |
|
||
|---|---:|---:|
|
||
| Taille | 3 246 Mo | **2 859 Mo (−387 Mo, −12 %)** |
|
||
| Fichiers | 24 249 | 23 901 |
|
||
| Paquets du jeu | 8 561 | 8 561 |
|
||
| `NNE`, `Interchange`, `.pdb`, `DirectML.dll` | présents | absents |
|
||
|
||
Build : `D:\Game\LifePlay_Build_5.5_O1`. **Validé en jeu le 2026-10-02** (« pas de soucis rencontrés »), tag `O1-valide`.
|
||
|
||
## 12. Lot O9 : trace Unreal Insights (2026-10-02)
|
||
|
||
Trace courte (≈ 4 min, 841 Mo, `-trace=cpu,frame,bookmark,loadtime -statnamedevents`), analysée en ligne de commande :
|
||
`UnrealInsights.exe -OpenTraceFile=… -AutoQuit -NoUI -ExecOnAnalysisCompleteCmd="@=export.rsp"` avec
|
||
`TimingInsights.ExportTimerStatistics … -threads=GameThread`. Résultats : `D:\Game\LifePlay_Backup_5.5\O9`.
|
||
|
||
> Pièges : chemins avec `/` (les `\` sont lus comme des échappements) ; une trace de 10 minutes (3,3 Go) demande
|
||
> plus de 50 Go de mémoire à l'analyse, et Insights s'arrête quand on ferme son avertissement de mémoire.
|
||
|
||
**Constat principal : le chargement d'une partie (« Continue ») prend 71 s**, dont :
|
||
|
||
| Fonction (thread de jeu) | Durée | Détail |
|
||
|---|---:|---|
|
||
| `PC.AutoLoad` → `GI.loadgame` | 60,8 s | — |
|
||
| `MapMarkers.SpawnMapMarkers` (3 appels) | 59,9 s | `MoveCity` 29,4 s ; `ActualSpawnMarkers` 29,2 s |
|
||
| `MapMarkers.GenerateTrees` / `GenerateHISM` | 28,8 s | — |
|
||
| `HISMC_AddInstance` | **54,8 s** pour 160 916 appels | arbres de la carte ajoutés un par un |
|
||
| `FChaosScene::AddActorsToScene`, `Init Body` | 161 272 appels | **un corps physique par arbre** |
|
||
| `TickAsyncLoading GT` (chargements bloquants) | 19,8 s | dont 10,5 s pour l'instance de jeu au démarrage |
|
||
| `LoadTxt` | 8,0 s pour 1 413 appels | lecture des fichiers texte, répartie dans la partie |
|
||
|
||
Cause : les composants `Tree` et `Car` de `MapMarkers` (`HierarchicalInstancedStaticMeshComponent`) gardent la
|
||
collision par défaut (`BlockAll`). Chaque arbre de la carte (≈ 160 000) reçoit donc un corps physique Chaos. Cela
|
||
explique probablement aussi la **physique à 463 Mo** mesurée en §9.3. En jeu, hors chargement, le thread de jeu reste
|
||
léger : il est inactif la moitié du temps (`Game thread idle time`).
|
||
|
||
Pistes, par ordre de risque :
|
||
1. Couper la collision des arbres et des voitures de la carte (`NoCollision`) : chargement et mémoire fortement
|
||
réduits. Cela change le comportement si le joueur doit être bloqué par les arbres sur la carte de la ville
|
||
(**à confirmer par l'utilisateur**).
|
||
2. Garder la collision, mais ne la créer qu'une fois tous les arbres ajoutés (sous-système C++ : collision coupée
|
||
pendant `GenerateTrees`, puis rétablie). Le gain porte sur le temps seulement, pas sur la mémoire.
|
||
|
||
Question préalable (protocole §3.1) : le chargement d'une partie prend-il aussi environ une minute en 4.27 ?
|
||
|
||
### 12.1 Correction appliquée et résultat (option 1, décision utilisateur)
|
||
|
||
Commandlet `LPSetComponentCollision` : composants `Tree` et `Car` de `MapMarkers` en `NoCollision` (CHG-062). Diff
|
||
`LPDumpAssets` avant/après : 2 lignes. Les composants `HISM_C` des bâtiments, ajoutés à la volée, gardent leur
|
||
collision. Build `LifePlay_Build_5.5_O9`, validé en jeu le 2026-10-02 : chargement plus court, arbres et voitures
|
||
toujours affichés. Tag `O9-valide`.
|
||
|
||
| Mesure (trace Insights et LLM) | Avant | Après |
|
||
|---|---:|---:|
|
||
| Bouton « Continue » jusqu'à la partie jouable | **71,1 s** | **22,5 s (−68 %)** |
|
||
| `GenerateTrees` (par appel) | 15,4 s | 0,3 s |
|
||
| Chargements bloquants (`TickAsyncLoading GT`, plus long) | 10,5 s | 1,3 s |
|
||
| Mémoire physique (Chaos) | 463 Mo | **313 Mo (−150 Mo)** |
|
||
| Mémoire totale du processus | 3 546 Mo | 3 324 Mo |
|
||
|
||
Les deux sessions ont des durées différentes : les chiffres de mémoire sont indicatifs ; les durées de fonctions sont
|
||
directement comparables.
|
||
|
||
Reste : `ActualSpawnMarkers` prend encore **15 s**. Il ajoute ≈ 80 000 instances aux composants `HISM_C` des bâtiments,
|
||
avec ≈ 49 500 corps physiques. Une piste O9b serait d'en couper la collision, si elle ne sert pas aux clics (à vérifier).
|
||
|
||
### 12.2 Lot O9b : marqueurs de bâtiments (2026-10-02)
|
||
|
||
Les clics se font sur les icônes, pas sur les bâtiments (utilisateur). Les modèles `NODE_AddHISM-0` et `-1` (`HISM_C`)
|
||
de `MapMarkers` sont passés en `NoCollision` (CHG-063, diff : 2 lignes). Build `LifePlay_Build_5.5_O9b`, validé en jeu
|
||
le 2026-10-02 : icônes cliquables, affichage inchangé. Tag `O9b-valide`.
|
||
|
||
| Mesure | Origine (4.27 = 5.5) | Après O9 | Après O9b |
|
||
|---|---:|---:|---:|
|
||
| « Continue » jusqu'à la partie jouable | 71,1 s | 22,5 s | **14,7 s (−79 %)** |
|
||
| `ActualSpawnMarkers` | 15,0 s | 15,1 s | 1,2 s |
|
||
| `HISMC_AddInstance` (≈ 80 000 appels) | — | 13,4 s | < 0,1 s |
|
||
| Corps physiques créés au chargement | 161 272 | 49 557 | 530 |
|
||
| Mémoire physique | 463 Mo | 313 Mo | **83 Mo (−82 %)** |
|
||
| Mémoire totale du processus | 3 546 Mo | 3 324 Mo | **3 112 Mo** |
|
||
|
||
Le levier O10 (§9.4, collisions de la ville) est ainsi largement traité : il ne reste que 83 Mo de physique.
|
||
|
||
## 13. Lot O2 : contenu compressé (IoStore + Oodle) (2026-10-02)
|
||
|
||
Retour aux réglages par défaut d'UE5, que le projet désactivait : `UsePakFile=True`, `bUseIoStore=True`,
|
||
`bCompressed=True` (Oodle Kraken). `Modules` (`DirectoriesToAlwaysStageAsNonUFS`) et `Movies` restent en fichiers nus.
|
||
Le jeu lit ses données texte et ses images externes directement sur le disque (`ModdingExtra`, `LPVictoryCompat`) : ces
|
||
lectures ne sont pas concernées (CHG-064).
|
||
|
||
| Mesure (build Development) | Fichiers nus (O9b) | Compressé (O2) |
|
||
|---|---:|---:|
|
||
| Taille du build | 3 367 Mo | **2 002 Mo (−40 %)** |
|
||
| Nombre de fichiers | 23 928 | **2 104** |
|
||
| Contenu cuit | 2,5 Go (≈ 21 000 fichiers) | 1,24 Go (5 fichiers) |
|
||
| « Continue » jusqu'à la partie jouable | 14,7 s | 15,9 s (écart dans le bruit des sessions) |
|
||
| Chargements bloquants (`Flush Async Loading GT`) | 6,0 s | 1,7 s |
|
||
| Initialisation de l'instance de jeu | 1,4 s | 0,7 s |
|
||
| Mémoire totale | 3 112 Mo | 3 255 Mo (sessions différentes) |
|
||
|
||
Validé en jeu le 2026-10-02 (7 contrôles) : vidéo d'introduction, liste des mods, chargement de partie, personnages et
|
||
scène, sauvegarde et rechargement, image externe, fermeture normale. Tag `O2-valide`.
|
||
|
||
Le gain porte sur la taille et le nombre de fichiers ; le temps de chargement reste du même ordre.
|
||
|
||
**Décision (utilisateur, 2026-10-02)** : la compression est conservée.
|
||
- Les mods sont tous des modules listés dans le jeu, sous `Modules`.
|
||
- Vérification : les 17 dossiers de `Content/Modules` ne contiennent que du texte (`.lpscene`, `.lpaction`,
|
||
`.lpcharacter`, `.lpworld`, `.txt`…) et 20 images `.jpg`, aucun `.uasset`. Ils restent en fichiers nus et ne sont
|
||
donc pas concernés.
|
||
- Un mod qui remplacerait des `.uasset` de `Content` ne fonctionnerait plus. Si un tel mod apparaît, il faudra prévoir
|
||
une variante de distribution en fichiers nus.
|
||
|
||
## 14. Lot O4 : mipmaps des textures 3D (2026-10-02)
|
||
|
||
`Tools/FixTextureMips.py` (CHG-065) retient les textures sans mipmaps ou non streamées qui remplissent toutes ces conditions :
|
||
- dimensions en puissance de 2 ;
|
||
- référencées par au moins un matériau, et par aucun widget ni Blueprint ;
|
||
- ni cheveux, ni masques de transparence (les mipmaps amincissent mèches et découpes à distance).
|
||
|
||
**29 textures** sont retenues : 27 de vêtements (`Clothes4`), la route et le trottoir de la carte. Sont écartées : 733 aux
|
||
dimensions non standard (surtout des icônes), 44 d'interface ou chargées par nom, et 29 de cheveux ou de transparence.
|
||
Le diff ne porte que sur `MipGenSettings`, `NeverStream` et `LightingGuid` (régénéré).
|
||
|
||
Validé en jeu le 2026-10-02 (« la build semble bonne »), tag `O4-valide`. Gain surtout visuel (scintillement à distance) ;
|
||
gain mémoire faible, ces textures étant petites.
|
||
|
||
Conclusion du levier « textures » : l'essentiel des 835 textures non streamées est fait d'icônes d'interface, pour
|
||
lesquelles c'est le bon réglage. Aucun autre lot de textures n'est justifié.
|
||
|
||
## 15. Build Shipping de distribution (O1 + O2 + O4 + O9 + O9b) (2026-10-02)
|
||
|
||
Commande : `BuildCookRun … -clientconfig=Shipping -build -cook -iterate -stage -pak -iostore -compressed -archive
|
||
-archivedirectory=D:\Game\LifePlay_Build_5.5_Shipping_V1.2 -nodebuginfo`. Cuisson : 0 erreur, 0 avertissement.
|
||
|
||
| Build Shipping | V1.1 (fichiers nus) | Optimisé |
|
||
|---|---:|---:|
|
||
| Taille | 3 246 Mo | **1 494 Mo (−54 %)** |
|
||
| Fichiers | 24 249 | **2 084** |
|
||
| Exécutable et DLL | 375 Mo (dont `.pdb` 207 Mo) | 145 Mo |
|
||
| Contenu (`Paks`, `Modules`, `Movies`) | ≈ 2,6 Go | 1,33 Go |
|
||
| Moteur | ≈ 270 Mo (dont `NNE` 119 Mo) | 13 Mo |
|
||
|
||
Disposition : `LifePlay.exe`, `LifePlay/Binaries`, `LifePlay/Content/{Paks, Modules, Movies}`, `Engine` (10 fichiers).
|
||
|
||
Premier essai : **aucune ville proposée** en nouvelle partie. `UI/CityMenu` listait les fichiers `Heavy/StreetMap/*.uasset`
|
||
sur le disque, absents avec IoStore. Le build Development d'O2 avait le même défaut : le test, passé par « Continue »,
|
||
n'ouvrait pas ce menu. Correction O2b (CHG-067) dans `ModdingExtra::GetAllFilesFromFolder` : repli sur le registre
|
||
d'assets quand le disque ne renvoie aucun paquet. Build reconstruit, **validé en jeu le 2026-10-02** (« fonctionne comme
|
||
attendu »), tag `O2b-valide`.
|
||
|
||
Leçon (reportée dans `10_Protocole_Operations.md` §4) : un changement de packaging se teste aussi en **nouvelle partie**
|
||
(choix de ville, création de personnage), pas seulement par « Continue ».
|
||
|
||
## 16. Lot O7 : réorganisation des dossiers — audit (2026-10-02, lecture seule)
|
||
|
||
### 16.1 Carte de `Content/Heavy` (6,2 Go)
|
||
|
||
| Dossier | Taille | Contenu principal | Sous-dossiers |
|
||
|---|---:|---|---|
|
||
| `Clothes4` | 2 705 Mo | vêtements : 940 maillages, 996 textures, 883 matériaux | `Materials` |
|
||
| `New2` | 1 359 Mo | meubles, animations, sons, cheveux | `Furniture` 803, `Anims2` 481, `Sound` 418, `Daily` 344, `Hairs` 243, `BDSM`, `Beasts`, `Buildings` |
|
||
| `Daz` | 1 054 Mo | corps Bridget et Michael, animations, vêtements | `Anims` 314, `Bridget` 180, `Michael` 113, `Clothes` 52 |
|
||
| `New3` | 695 Mo | icônes, animations, cheveux, tatouages | `UI` 555, `Anims` 443, `Hairs` 225, `Tattoos` 71, `Characters`… |
|
||
| `New4` | 239 Mo | animations, cheveux | `Anims` 145, `Hairs` 118, `Misc`, `Tentacles` |
|
||
| `Backgrounds` | 82 Mo | 80 images de fond | — |
|
||
| `StreetMap` | 79 Mo | 280 villes et leurs 280 maillages | `Static` |
|
||
| `Characters`, `New`, `New5` | 7 Mo | divers (squelette, 37 icônes, 1 animation) | — |
|
||
|
||
### 16.2 Contrainte : des chemins de dossiers font partie du fonctionnement du jeu
|
||
|
||
Les références directes entre assets sont mises à jour par l'éditeur lors d'un déplacement (redirecteurs). En revanche,
|
||
**10 préfixes de dossiers sont écrits en texte** dans les Blueprints, et le jeu y ajoute un nom lu dans les données :
|
||
|
||
| Préfixe | Blueprint | Usage |
|
||
|---|---|---|
|
||
| `/Game/Heavy/New2/Furniture/` | `Room` | meubles des `.lpworld` (modules et mods) |
|
||
| `/Game/Heavy/Clothes4/` | `GI` | vêtements de `Clothes4.txt` |
|
||
| `/Game/Heavy/StreetMap/`, `…/StreetMap/Static/` | `GI` | villes |
|
||
| `Heavy/StreetMap` (relatif) | `UI/CityMenu` | liste des villes |
|
||
| `/Game/Heavy/New3/Tattoos/` | `GI` | tatouages |
|
||
| `/Game/Heavy/New3/Characters/Tanlines/` | `Person` | marques de bronzage |
|
||
| `/Game/Heavy/Daz/Bridget/Hairs/Pubic/`, `/Game/Heavy/Daz/Michael/hairs/other/` | `GI`, `Person` | pilosité |
|
||
| `/Game/Heavy/New3/UI/` | `UI/VisualMorph` | icônes de morphs |
|
||
| `Heavy/Daz/Clothes/` (relatif) | `UI/Inventory_Cloth` | vêtements Daz |
|
||
|
||
S'y ajoutent 17 chemins complets dans `Content/Modules` (`New2`, `New3`). Les modules et les mods de la communauté
|
||
désignent meubles, vêtements et cheveux **par leur nom**, dans ces dossiers : leur emplacement fait partie du contrat
|
||
de modding.
|
||
|
||
### 16.3 Options
|
||
|
||
| Option | Contenu | Risque | Recommandation |
|
||
|---|---|---|---|
|
||
| **O7a, ménage** | `Content/Saves` (239 parties de test de l'éditeur, 85 Mo, non versionnées, non livrées) déplacées vers la sauvegarde ; dossiers vides `Content/Developers` et `Content/Collections` retirés ; 3 captures de diagnostic à la racine déplacées vers `D:\Game\LifePlay_Backup_5.5` | nul | **oui** |
|
||
| **O7b, carte documentée** | §16.1 et §16.2 portés dans `08_Guide_Developpeur.md` : ce que contient chaque dossier, et quels dossiers ne doivent pas bouger | nul | **oui** |
|
||
| **O7c, renommage réel** | renommer `New`, `New2`… par thème (`Furniture`, `Animations`, `Hair`…), corriger les 10 préfixes dans 6 Blueprints et les 17 chemins des données | élevé : mods de la communauté cassés, comparaisons avec 4.27 perdues, des milliers de paquets réenregistrés | **non** (gain seulement cosmétique) |
|
||
|
||
### 16.4 Réalisé (2026-10-02)
|
||
|
||
- **O7a** :
|
||
- `Content/Saves` vidé : 14 125 fichiers (239 parties de test) déplacés vers
|
||
`D:\Game\LifePlay_Backup_5.5\O7\Content_Saves`, nombre de fichiers et d'octets vérifiés identiques ; le dossier
|
||
est conservé, vide ;
|
||
- `Content/Developers` et `Content/Collections` retirés : ils ne contenaient que des dossiers vides, que l'éditeur
|
||
recrée ;
|
||
- 3 captures de diagnostic de la racine rangées dans `D:\Game\LifePlay_Backup_5.5\O7\racine`.
|
||
- **O7b** : carte des dossiers et liste des dossiers à ne pas déplacer dans `08_Guide_Developpeur.md` §2.1.
|
||
|
||
Aucun asset déplacé, aucun Blueprint modifié : ni build ni test en jeu nécessaires.
|
||
|
||
### 16.5 O7d : collections thématiques (2026-10-02)
|
||
|
||
Pour retrouver les assets par thème sans renommer de dossier, `Tools/BuildCollections.py` crée 13 collections statiques
|
||
de l'éditeur (`Saved/Collections/LifePlay*.collection`), rangées sous une collection parente `LifePlay` :
|
||
|
||
| Collection | Assets | Contenu |
|
||
|---|---:|---|
|
||
| `LifePlay_Animations` | 1 709 | toutes les animations (`Daz/Anims`, `New2/Anims2`, `New2/Daily`, `New3/Anims`, `New4/Anims`…) |
|
||
| `LifePlay_Vetements` | 2 926 | `Clothes4` et ses matériaux, `Daz/Clothes`, `New3/Clothes`, `New2/BDSM` |
|
||
| `LifePlay_Meubles` | 803 | `New2/Furniture` |
|
||
| `LifePlay_Cheveux` | 776 | tous les dossiers `Hairs` (dont pilosité Daz) |
|
||
| `LifePlay_Icones_UI` | 796 | icônes et fonds d'écran |
|
||
| `LifePlay_Villes` | 594 | `StreetMap` et `New2/Buildings` |
|
||
| `LifePlay_Sons` | 419 | sons |
|
||
| `LifePlay_Corps` | 236 | corps Daz, squelettes, visages, créatures |
|
||
| `LifePlay_Gameplay` | 169 | Blueprints, widgets, structures, carte, rendu |
|
||
| `LifePlay_Tatouages` | 71 | `New3/Tattoos` |
|
||
| `LifePlay_Divers` | 62 | `Misc`, particules, accessoires d'animation |
|
||
| `LifePlay_Chemins_Fixes` (rouge) | 4 984 | **transversale** : assets des dossiers à chemin écrit en dur (§16.2), à ne jamais déplacer |
|
||
|
||
Chaque asset du projet (8 561, hors redirecteur et données de carte) est dans exactement une collection thématique.
|
||
Les collections ne sont que des listes : aucun asset n'est modifié, rien n'est cuit ni livré dans le jeu. Elles ne
|
||
sont ni versionnées ni archivées : le script est la source et les régénère à l'identique (GUID fixes).
|
||
|
||
Ce sont des collections **locales** (`Saved/Collections`). Une première version les écrivait en collections partagées
|
||
(`Content/Collections`) : l'éditeur associe toujours celles-ci au contrôle de révision, désactivé dans ce projet, et
|
||
affichait l'avertissement « Collection is missing its revision control provider » (constaté par l'utilisateur). Les
|
||
fichiers ont été déplacés vers `D:\Game\LifePlay_Backup_5.5\O7d\Content_Collections` et régénérés en local,
|
||
identiques à l'octet près. Contrôles : relecture des 13 fichiers, 13 545 chemins, 0 inconnu du registre ; l'éditeur les
|
||
charge (`LogCollectionManager: Loaded 13 collections`).
|
||
|
||
## 17. Couche de données : stratégie (2026-10-02)
|
||
|
||
Proposition utilisateur : convertir les fichiers texte de `Modules` en fichiers JSON groupés par type, avec un calque de
|
||
valeurs par défaut, chargés une seule fois, avec un sous-module pour ingérer l'ancien format (mods).
|
||
|
||
Retenu : **le texte reste la source** (jeu de base et mods), et **le JSON devient la représentation compilée** chargée en
|
||
une fois. Cela évite deux sources de vérité, deux analyseurs à maintenir à l'identique, et une rupture avec le format
|
||
connu des moddeurs.
|
||
|
||
| Étape | Contenu | Effort |
|
||
|---|---|---|
|
||
| 1 | mesure : temps de chargement des données et lectures par type | 1 lot |
|
||
| 2 | sous-système C++ : `Modules` lu une seule fois et gardé en mémoire ; `LoadTxt` servi depuis la mémoire | 1 lot |
|
||
| 3 | cache compilé par type (JSON ou binaire), régénéré quand les sources changent, avec calque de valeurs par défaut | 1 à 2 lots |
|
||
| 4 (facultatif) | analyseurs de `GI` réécrits en C++, format par format, vérifiés à l'identique | 1 lot par format |
|
||
|
||
Rappels :
|
||
- `Modules` pèse 14 Mo : le gain porte sur le nombre de fichiers et le temps, pas sur la taille.
|
||
- Les corps de `.lpscene`/`.lpai` sont des scripts : un format JSON ne change rien à leur interprétation.
|
||
|
||
### 17.1 Étape 1 : premières mesures (trace O2, build Development)
|
||
|
||
| Fonction (`GI`) | Durée | Remarque |
|
||
|---|---:|---|
|
||
| `PopulateRaws` | **12,6 s par appel**, 3 appels dans la session | lit et analyse tout `Modules` ; **relancé à chaque chargement de partie** |
|
||
| `LoadTxt` | 7,4 s pour 2 705 lectures | 2,75 ms par fichier de quelques Ko : coût d'ouverture de fichier |
|
||
| `PopulateScenes` | 3,6 s par appel | analyse des en-têtes de scènes |
|
||
| `PopulateActions` | 1,9 s par appel | — |
|
||
| `PlayScene`, `LoadPreset` en jeu | 0,2 s et 0,3 s au total | négligeable |
|
||
|
||
Au menu principal, seuls 11 fichiers sont lus (0,085 s) : la lecture de `Modules` a lieu au lancement d'une partie.
|
||
Instrumentation ajoutée à `ModdingExtra::LoadTxt` : bilan par type de fichier à la fermeture du jeu et par la commande
|
||
console `ModdingExtra.LoadTxtStats` (build `LifePlay_Build_5.5_DATA1`).
|
||
|
||
### 17.2 Étape 1 : résultats (2026-10-02)
|
||
|
||
Lancement d'une partie (« Continue ») sur le build DATA1, juste après sa construction (fichiers jamais lus) :
|
||
|
||
| Type | Lectures | Fichiers | Relectures | Volume | Temps de lecture |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| `.lpscene` | 816 | 813 | 3 | 2,5 Mo | 3,86 s |
|
||
| `.lpaction` | 305 | 305 | 0 | 113 Ko | 1,23 s |
|
||
| `.lpstat` | 74 | 74 | 0 | 19 Ko | 0,33 s |
|
||
| autres (`.lpai`, `.lpworld`, `.txt`, `.lpcharacter`…) | 96 | 59 | 37 | 0,9 Mo | 0,26 s |
|
||
| **Total** | **1 291** | 1 251 | 40 | 3,6 Mo | **5,7 s** |
|
||
|
||
Comparaison hors du jeu, sur les 1 271 `.lpscene` : 2,4 ms par fichier à la première lecture, mais **0,11 ms par fichier
|
||
une fois le cache du système chaud**. Le coût vient de l'ouverture à froid de centaines de petits fichiers (cache disque,
|
||
antivirus), pas de leur taille.
|
||
|
||
Cela se retrouve dans la trace O2 :
|
||
- `PopulateRaws` prend 12,6 s au premier passage (fichiers froids), puis ≈ 6 s quand il est relancé (fermeture du
|
||
gestionnaire de mods, `CloseModManager` 6,2 s) ;
|
||
- **≈ 6 s** viennent donc de la lecture à froid et **≈ 6 s** de l'analyse en Blueprint (`PopulateScenes` 3,6 s,
|
||
`PopulateActions` 1,9 s…), à chaque passage.
|
||
|
||
Conséquences pour la suite :
|
||
- **Étapes 2 et 3, réunies** (un fichier compilé lu une fois, puis `LoadTxt` servi depuis la mémoire) : environ −5 à
|
||
−6 s au premier chargement d'une partie, gain faible ensuite.
|
||
- **Étape 4** (analyse en C++) ou suppression des relances inutiles de `PopulateRaws` : jusqu'à −6 s **à chaque**
|
||
passage.
|
||
|
||
### 17.3 Étapes 2 et 3 : couche de données (2026-10-02)
|
||
|
||
Nouveau `Plugins/ModdingExtra/Source/ModdingExtra/Private/LPDataCache.h/.cpp`, lancé au démarrage du module (hors
|
||
commandlets) :
|
||
- **relevé** : date et taille des fichiers texte de `Modules` (`.lp*`, `.txt`, `.config`, `.cfg`), sans ouverture ;
|
||
- **cache compilé** : un JSON par type dans `Saved/LPDataCache/<type>.json` (`version`, `type`, `files`). Pour chaque
|
||
fichier : `stamp`, `size`, `text` et, pour `.lpaction`, `.lpstat`, `.lpquest`, `.lpmod`, des `fields` (champs
|
||
« CLÉ: valeur » analysés). Le **calque** de valeurs par défaut, fichier optionnel
|
||
`Content/Modules/_lpdata_defaults.json`, complète les champs absents des enregistrements ;
|
||
- **mise à jour incrémentale** : seuls les fichiers nouveaux ou modifiés sont relus (mods ajoutés, éditions) ;
|
||
- **`LoadTxt`** sert le texte depuis la mémoire, identique à la lecture du disque ; **`SaveTxt`** met la mémoire à
|
||
jour ; la lecture se fait sur le disque avant la fin du chargement, ou hors `Modules` (sauvegardes) ;
|
||
- options : `-LPNoDataCache` pour désactiver, `-LPDataCacheVerify` pour comparer chaque texte servi au disque.
|
||
|
||
| Mesure (build `LifePlay_Build_5.5_DATA23`, en arrière-plan au menu) | Valeur |
|
||
|---|---:|
|
||
| 1ᵉʳ lancement : construction du cache (2 051 fichiers, images comprises) | 12,3 s |
|
||
| Lancements suivants : chargement depuis le cache (2 031 fichiers texte) | **0,14 s** |
|
||
| Relevé des dates et tailles | 0,014 s |
|
||
| Cache (11 fichiers JSON) | ≈ 8 Mo, dont `lpscene` 4,6 Mo |
|
||
|
||
**Validé en jeu le 2026-10-02** (`LifePlay_verif_cache.bat`, `-LPDataCacheVerify`) : partie avec « Continue »,
|
||
scènes, changement de lieu, gestionnaire de mods.
|
||
- **2 658 textes servis par le cache, 0 écart** avec la lecture du disque.
|
||
- Temps de lecture de toute la session : **0,074 s** pour 2 690 lectures, contre 5,7 s pour un seul chargement de
|
||
partie auparavant.
|
||
- Ce qui reste lu sur le disque est voulu : `.lpcharacter` des sauvegardes (`Saves/_session`), hors `Modules`.
|
||
|
||
Tag `DATA23-valide`. Reste l'analyse en Blueprint (≈ 6 s par passage de `PopulateRaws`) : étape 4.
|
||
|
||
Constat annexe : 4 erreurs `GroomComponent : Failed to find /HairStrands/Materials/…` au démarrage depuis le lot O1. Le
|
||
module `HairStrands` reste intégré au jeu, car d'autres plugins en dépendent, alors que son contenu n'était plus cuit.
|
||
Correction ERR-039 (CHG-077) : `/HairStrands` retiré de `DirectoriesToNeverCook` (≈ 0,8 Mo). Plus aucune erreur au
|
||
démarrage.
|
||
|
||
### 17.4 Étape 4 : étude (2026-10-02, lecture seule)
|
||
|
||
**Déclencheurs de `PopulateRaws`** (EventGraph de `GI`, relevé avec `LPDumpFunction -Exec`) :
|
||
- l'événement `LoadSettings`, au lancement d'une partie (« Continue » ou nouvelle partie) ;
|
||
- l'événement de fermeture du gestionnaire de mods (`ShowUI` → `ClearModManagerWidget` → `PopulateRaws`),
|
||
**même sans changement de mods**.
|
||
|
||
**Découpage d'un passage** (trace O2, fenêtres temporelles des événements) :
|
||
|
||
| Phase | 1ᵉʳ passage (fichiers froids) | 2ᵉ passage (fichiers chauds) | Avec la couche de données |
|
||
|---|---:|---:|---:|
|
||
| Lecture des fichiers (`LoadTxt`…) | 7,0 s | 0,66 s | ≈ 0,07 s |
|
||
| `PopulateActions` | 1,93 s | 1,84 s | inchangé |
|
||
| `PopulateScenes` | 3,64 s | 3,59 s | inchangé |
|
||
| **Total `PopulateRaws`** | **12,6 s** | **6,1 s** | **≈ 5,5 s** |
|
||
|
||
**Où passe le temps de l'analyse** (statistiques limitées à la fenêtre de chaque événement) :
|
||
- `PopulateScenes` : **94 % dans une seule fonction, `WhatWhereToArray`** (3,43 s pour 1 558 appels, un par scène).
|
||
Elle développe les listes `WHAT:`/`WHERE:` (par exemple `all, -sleep, -nap`) en parcourant pour chaque scène les
|
||
tableaux de structures `ActionDetail` et `AmenityAction`. Cela fait 503 000 lectures d'éléments de tableau, chaque
|
||
structure étant copiée par le Blueprint (2,18 s), et 1,27 million de comparaisons de texte (0,55 s).
|
||
- `PopulateActions` : boucle de l'EventGraph sur les lignes des actions. 473 000 lectures d'éléments (0,94 s), et
|
||
≈ 234 000 appels chacun à `Trim`, `StartsWith`, `EndsWith` et à des comparaisons (≈ 0,6 s).
|
||
|
||
**Options** :
|
||
|
||
| Option | Contenu | Gain par passage | Effort | Risque |
|
||
|---|---|---:|---|---|
|
||
| **4a** | ne plus relancer `PopulateRaws` à la fermeture du gestionnaire de mods si la liste des mods actifs est inchangée (branche ajoutée dans `GI` par commandlet, contrôle de diff) | **≈ 5,5 s** à chaque fermeture sans changement | 1 lot | faible |
|
||
| **4b** | `WhatWhereToArray` réécrite en C++ (`LPDataCompat`, même signature), nœuds rebranchés par commandlet comme les correctifs CX-B ; preuve d'équivalence : commandlet qui exécute les deux versions sur les 1 558 en-têtes et compare | **≈ 3,3 s** à chaque passage | 1 à 2 lots | moyen (lecture des structures Blueprint par réflexion) |
|
||
| 4c | boucle de `PopulateActions` en C++ | ≈ 1,5 s | 1 à 2 lots | moyen (logique au milieu de l'EventGraph) |
|
||
| 4d | réécriture complète des analyseurs (étape 4 d'origine) | — | 10 à 15 lots | **abandonnée** : le coût est concentré dans 4b et 4c |
|
||
|
||
Ordre recommandé : 4b (le plus gros gain, à chaque chargement de partie), puis 4a, puis 4c si nécessaire.
|
||
Chargement de données attendu après 4b et 4c : ≈ 0,7 s au lieu de 12,6 s au premier lancement.
|
||
|
||
### 17.5 Étape 4b : `WhatWhereToArray` en C++ — résultats (2026-10-02)
|
||
|
||
- **Équivalence** (`-LPVerifyWhatWhere`, chaque appel compare la version C++ à la fonction Blueprint d'origine) : plus de
|
||
3 000 appels sur deux chargements complets (« Continue », puis fermeture du gestionnaire de mods), **0 écart**.
|
||
- **Mesure** (trace `DATA4b.utrace`, avec la couche de données) :
|
||
|
||
| Fonction | Avant (trace O2) | Après 4b |
|
||
|---|---:|---:|
|
||
| `PopulateScenes` | 3,6 s | **0,15 s** |
|
||
| `PopulateActions` | 1,9 s | 0,9 à 1,0 s |
|
||
| **`PopulateRaws` (chargement de partie)** | **12,6 s** (froid) / 6,1 s (chaud) | **1,26 s** / 1,17 s |
|
||
| `WhatWhereToArray`, 3 185 appels | ≈ 3,4 s par passage | 0,2 s au total |
|
||
|
||
Le chargement des données d'une partie est **divisé par 10**. Les avertissements `LoadTxt ECHEC` (`OldPlayer.lpcharacter`,
|
||
nom vide) existaient déjà avant ce lot (journaux O2, ERR038). Tag `DATA4b-valide`.
|
||
|
||
Reste `PopulateActions` (≈ 1 s, option 4c) et la relance à la fermeture du gestionnaire de mods (option 4a, ≈ 1,2 s
|
||
désormais) : gains devenus faibles.
|
||
|
||
## 18. Build Shipping V1.3 (2026-10-02)
|
||
|
||
`BuildCookRun … -clientconfig=Shipping … -pak -iostore -compressed -nodebuginfo`, sortie
|
||
`D:\Game\LifePlay_Build_5.5_Shipping_V1.3`. Cuisson : 0 erreur, 0 avertissement. 1 494 Mo, 2 084 fichiers (comme la V1.2).
|
||
|
||
Contenu par rapport à la V1.2 :
|
||
- couche de données (CHG-075, CHG-076) ;
|
||
- `WhatWhereToArray` en C++ (CHG-078) ;
|
||
- contenu `HairStrands` de nouveau cuit (ERR-039, CHG-077) ;
|
||
- retrait du sous-système ERR-038 (CHG-073 : aucun changement de comportement par rapport à la V1.2).
|
||
|
||
En Shipping, le dossier `Saved` est dans le profil de l'utilisateur, `%LOCALAPPDATA%\LifePlay\Saved`, comme les
|
||
sauvegardes `.sav`. Le cache s'y trouve donc dans `LPDataCache`. Lancement de contrôle jusqu'au menu : cache construit
|
||
(11 fichiers), aucun plantage. **Validé en jeu le 2026-10-02** (nouvelle partie, Continue, scènes, gestionnaire de
|
||
mods, sauvegarde et rechargement, carte de la ville). |