24 KiB
23. Cycle de vie d'un mod (2026-10-07)
Référence pour les développeurs du jeu et des outils de mods : ce qu'est un mod LifePlay, comment il est fabriqué,
livré, découvert, activé et consommé, quelles propriétés sont réellement lues, et ce qui pourrait évoluer.
Constats relevés dans le code du jeu, des Blueprints (GI) et du moteur UE 5.5 installé
(Engine/Source/Runtime/Projects) le 2026-10-07. Guide des moddeurs (anglais) :
Docs/Modding/FullGuides/Creating_Asset_Mods.md.
Documents liés : 01 (données texte, GI), 15 (modules
livrés à part), 16 (mods d'assets H3), 17 (gestionnaire de mods
depuis l'écran titre), 20 (packs d'animations AP1–AP7).
1. Deux moitiés, deux mécanismes
Un mod LifePlay est un module texte du jeu, éventuellement accompagné d'un plugin de contenu Unreal.
| Module LifePlay (texte) | Plugin de contenu (assets cuits) | |
|---|---|---|
| Emplacement installé | LifePlay/Content/Modules/<id>/ |
LifePlay/Mods/<id>/ |
| Descripteur | <id>.lpmod (CLÉ: valeur) |
<id>.uplugin (JSON) |
| Contenu | .lpaction, .lpscene, .lpstat, .lpquest, .lptalk, .lpdesc, .lpai, .lpcharacter, .lpworld, .lphair, tables, crédits, catalogue |
Content/Paks/Windows/<id>LifePlay-Windows.pak/.utoc/.ucas (IoStore, AssetRegistry.bin du mod dans le .pak) |
| Lu par | ModdingExtra (LoadTxt, LPDataCache), Blueprint GI, sous-systèmes C++ |
Gestionnaire de plugins du moteur (montage), registre d'assets |
| Activation | case du gestionnaire de mods (GI.ModEnableds) |
toujours monté s'il est présent (plugin Mod activé par défaut) |
| Existe depuis | jeu d'origine (Vinfamy) | lot H3 (2026-10-03) |
Mods texte seuls : vin_*. Mods d'assets : lpr_hair_pocolov (coiffures), lpr_anim_quaternius et
lpr_anim_freeanims (animations). Les deux moitiés portent le même identifiant <id> : MODULE_UNIQUEID du
.lpmod = nom du plugin = point de montage /<id>/ des assets.
2. Cycle de vie
FABRICATION (projet source) LIVRAISON JEU (à chaque démarrage)
───────────────────────── ───────── ────────────────────────
Tools/NewMod.ps1 → ModSources/<id>/ <id>-<v>-for-LifePlay-<jeu>.zip
.uplugin, Module/<id>.lpmod, CREDITS LifePlay/Mods/<id>/… 1. moteur : découverte Mods/, montage
import des assets (HairPipeline, LifePlay/Content/Modules/<id>/ 2. registre d'assets : AssetRegistry.bin
AnimPipeline → DeliverAnims) README.txt 3. GI : LoadSettings → ModEnableds
Tools/BuildMod.ps1 -Name <id> → removeDeletedMods → PopulateRaws
cuisson DLC -basedonreleaseversion installation : extraire 4. sous-systèmes C++ : métadonnées,
contrôle du conteneur, archive dans le dossier du jeu coiffures, animations, avertissement
désinstallation : supprimer 5. gestionnaire de mods : cocher / décocher
les deux dossiers → PopulateRaws, SaveModSelection
2.1 Fabrication
| Étape | Outil | Résultat |
|---|---|---|
| Squelette | Tools/NewMod.ps1 -Name <id> [-Hairs] |
ModSources/<id>/<id>.uplugin, Module/<id>.lpmod (trois premières lignes imposées, voir § 3.2), CREDITS.txt |
| Édition | Tools/EditMod.ps1, Tools/ModSource.ps1 |
le mod est déplacé dans <projet>/Mods/ le temps du travail, puis remis dans ModSources/ : le jeu de base n'en contient jamais rien |
| Assets : coiffures | Tools/HairPipeline.ps1 -Config Tools/mods/<id>.json |
/<id>/Hairs/… + fichiers .lphair |
| Assets : animations | Tools/anim/AnimPipeline.ps1 (BuildMod.ps1 -Anim <pack>), étape 6 DeliverAnims |
/<id>/Anims/Female/<clé>_F, /<id>/Anims/Male/<clé>_M, .lpmod et CREDITS.txt tirés de AnimSources/<pack>/pack.json, catalogue, vignettes, planches |
| Cuisson | Tools/BuildMod.ps1 -Name <id> -Version <jeu> |
cuisson DLC du seul plugin contre Releases/<jeu> ; refus si un autre plugin est dans Mods/, si une entrée du conteneur sort de Mods/<id>/, si un mod payant cite une licence non commerciale |
| Archive | BuildMod.ps1 |
<id>-<version>-for-LifePlay-<jeu>.zip testée ; le .lpmod livré reçoit MODULE_PACKAGED et MODULE_GAME_VERSION, le .uplugin livré VersionName et CreatedByURL |
Contrainte de compatibilité : un conteneur de mod est cuit contre une version de référence précise du jeu
(Releases/<version>, produite par -createreleaseversion à chaque publication). Les assets de base qu'il référence
(squelettes Genesis, matériau DazHair, paramètres de compression du projet) ne doivent plus être renommés ni déplacés.
Un mod ne doit référencer aucun contenu /Engine/ non cuit par le jeu (cas des clips UE5 en AP7 : compression remise
au défaut du projet par DeliverAnims.py).
2.2 Installation et désinstallation
Le joueur extrait l'archive dans le dossier du jeu (celui de LifePlay.exe), en fusionnant le dossier LifePlay.
Pour désinstaller : supprimer Content/Modules/<id> et Mods/<id>. Aucun outil ne vérifie aujourd'hui qu'une
moitié n'a pas été laissée seule (voir § 6).
2.3 Démarrage du jeu
| Ordre | Qui | Ce qui se passe |
|---|---|---|
| 1 | Moteur, FPluginManager::ReadAllPlugins |
lit toujours <jeu>/Mods/ ; chaque Mods/<id>/<id>.uplugin devient un plugin de type Mod, activé par défaut (FPlugin::IsEnabledByDefault : chargé « depuis le projet ») |
| 2 | Moteur | CanContainContent: true : le point de montage /<id>/ est ajouté, les conteneurs Content/Paks/Windows/* sont montés |
| 3 | Registre d'assets | ajoute le AssetRegistry.bin de chaque plugin de contenu : les assets du mod sont trouvables par chemin et par classe sans être chargés |
| 4 | ULPModInfoSubsystem::Initialize (C++) |
lit chaque Modules/<id>/<id>.lpmod (toutes les clés), retient MODULE_GAME_VERSION ; journal Modules : N .lpmod lu(s) |
| 5 | ULPModDailiesSubsystem::Initialize (C++, AP5) |
relève les UAnimSequence sous /<plugin>/Anims de chaque plugin Mod monté ; clé = nom sans suffixe _F/_M |
| 6 | GI.LoadSettings (Blueprint) |
GameSettings.sav → ModEnableds ; ReadModLauncher (Modules/ModLauncher.config, absent en pratique) ; removeDeletedMods retire de la liste les modules dont le .lpmod n'existe plus |
| 7 | ULPHairstyleSubsystem (C++) |
après LoadSettings, ajoute cochés les modules MODULE_DEFAULT_ENABLED: true absents de la liste ; relève les .lphair |
| 8 | GI.PopulateRaws (Blueprint) |
pour chaque module coché : lecture des fichiers texte (LoadTxt, cache LPDataCache) → actions, scènes, stats, quêtes, dialogues, mondes |
| 9 | ULPModDailiesSubsystem::Tick |
dès que GI.Room existe : ajoute les clips de mod à Room.Dailies (une fois par pièce) |
| 10 | ULPModInfoSubsystem::Tick (toutes les 2 s) |
module coché dont MODULE_GAME_VERSION ≠ ProjectVersion : fenêtre « Mod version warning », une fois par module et par session |
2.4 Activation et désactivation
- État : tableau
GI.ModEnabledsde structuresModEnabled(UniqueID,IsEnabled). Un module absent de la liste est inactif (GI.IsModEnabled,ULPModInfoSubsystem::IsModuleEnabled,ULPHairstyleSubsystem::IsModuleEnabled). - Gestionnaire de mods (
UI/ModManager) : en partie (entrée d'origine) ou depuis l'écran titre (lot UI15). À la fermeture :PopulateRaws(données relues avec les modules choisis) ; depuis l'écran titre, le choix est écrit dansGameSettings.savparULPModSettingsLibrary::SaveModSelection(seulModEnabledsest remplacé). - Effet de la case selon la nature du contenu :
| Contenu | Décoché → |
|---|---|
| Données texte (actions, scènes, stats…) | non lues par PopulateRaws : absentes du jeu |
Coiffures (.lphair) |
retirées des listes (LPHairstyleSubsystem) ; paquet toujours monté, inutilisé |
Animations (/<id>/Anims) |
toujours ajoutées à Room.Dailies : LPModDailies ne consulte pas la case (§ 6, E1) |
| Avertissement de version | non affiché |
| Plugin Unreal | toujours monté : le moteur ignore ModEnableds |
Ordre de chargement (relevés LPDumpFunction de GI et UI/ModuleTick) :
GI.ModEnabledsest ordonné. Les boutons monter / descendre de chaque ligne du gestionnaire (UI/ModuleTick) appellent l'événementGI.SortLoadOrder(ForUp, ModuleIndex), qui échange deux éléments deModEnableds(Array_Swap) puis reconstruit la liste (AddTempModuleTicks).GI.ToggleMod(Mod, IsEnabled)parcourtModEnabledset remplace l'élément dontUniqueIDcorrespond.- L'affichage est inversé par rapport au tableau : indice dans
ModEnableds= longueur − 1 − position affichée. Monter vers la position affichée 0 est refusé (gardeModuleIndex == 1 && ForUp == 1), de même qu'un indice hors bornes. - Effet (
PopulateRaws, événement deGI) : boucle surModEnabledsdu début à la fin, modules cochés seulement. Pour chaque type (lpstat,lpaction,lpscene,lptalk,lpdesc,lpquest,lpai), les fichiers deModules/<id>sont lus (GetAllFilesFromFolder) et un fichier est ignoré si son nom de fichier (partie après le dernier/) a déjà été lu (FilenamesUsed). Le premier lu gagne : le module le plus bas dans la liste affichée l'emporte, ce que dit le guide d'origine (Docs/Modding/FullGuides/Getting_Started.txtl. 27 : « the one lowest in the load order wins »). - Nuance : la comparaison porte sur le nom de fichier seul, pas sur le chemin (le guide dit « same file in the same place »).
- Réserve : le relevé n'affiche pas le nom des macros de boucle, et
GIcontient aussi uneReverseForEachLoop. Le sens de la boucle est déduit de la cohérence avec l'affichage inversé et avec le guide ; à confirmer par un relevé qui nomme les macros (§ 6, E15). - Les animations et les assets ne suivent pas cet ordre (seuls les fichiers texte lus par
PopulateRawsle suivent).
Verrouillage de vin_Base : il est en dur dans UI/ModuleTick. La case n'appelle GI.ToggleMod que si
UniqueID != 'vin_Base' ; pour vin_Base, les boutons monter / descendre sont masqués (SetVisibility(Hidden)).
Aucune clé .lpmod ne permet de verrouiller un autre module.
2.5 Consommation des assets
| Type | Déclaration côté texte | Résolution | Code |
|---|---|---|---|
| Coiffure | .lphair : HAIRSTYLE: /<id>/Hairs/X.X |
registre d'assets, repli FPackageName::DoesPackageExist |
LPHairstyleSubsystem |
| Animation | ANIMATION: <clé> (.lpaction), Actor.animate(<clé>) (.lpscene) |
Person::PlayDaily : clés en dur, sinon (correctif LPPatchDailies) IsModDaily(<clé>) → PlayDailyAnim parcourt Room.Dailies, suffixe _F/_M selon le sexe |
LPModDailies, Person.uasset patché |
Convention des clés d'animation : <préfixe du pack>_<clip> en minuscules (qua_dance_loop, fap_as_talk), assets
<clé>_F et <clé>_M. Une clé inconnue ne joue rien (journal PlayDaily(<clé>) -> cle inconnue hors Shipping).
3. Propriétés réellement lues
3.1 <id>.uplugin (moteur)
| Propriété | Lue | Effet |
|---|---|---|
| nom du fichier / dossier | oui | nom du plugin, point de montage /<id>/ |
CanContainContent |
oui | indispensable : sans elle, le conteneur n'est pas monté |
EnabledByDefault |
oui (absente) | absente : plugin Mod activé |
ExplicitlyLoaded |
oui (absente) | absente : monté au démarrage |
Modules |
oui (absente) | aucun code : un mod Shipping ne peut pas en apporter (pas de binaire compatible) |
Plugins : [{ "Name": "...", "Enabled": true, "Optional": false }] |
oui, appliqué | dépendance obligatoire absente : la configuration des plugins échoue et le jeu ne démarre pas (LaunchEngineLoop.cpp renvoie false après LoadModulesForEnabledPlugins) ; "Optional": true : ignorée si absente |
Hidden |
oui | utilisé seulement par le navigateur de plugins de l'éditeur ; sans effet en jeu |
Sealed |
oui | interdit qu'un autre plugin en dépende |
DisallowedPlugins |
oui | interdit une dépendance donnée |
SupportedTargetPlatforms, EngineVersion |
oui si présentes | plateformes ; EngineVersion ne fait qu'avertir |
FriendlyName, Description, Category, CreatedBy, CreatedByURL, Version, VersionName, IsBetaVersion, Installed |
non en jeu | descriptifs (navigateur de plugins de l'éditeur) |
3.2 <id>.lpmod (jeu)
| Clé | Lue par | Effet |
|---|---|---|
ligne 1 MODULE_UNIQUEID |
GI (par position), sous-systèmes C++ (par clé) |
identifiant du module |
ligne 2 MODULE_NAME |
GI (par position), LPModInfoSubsystem |
nom dans le gestionnaire, dans l'avertissement |
ligne 3 MODULE_AUTHOR |
GI (par position) |
auteur dans le gestionnaire |
MODULE_DEFAULT_ENABLED |
LPHairstyleSubsystem |
coché au premier démarrage où il est présent |
MODULE_GAME_VERSION |
LPModInfoSubsystem |
avertissement de version |
MODULE_LINK, MODULE_DESCRIPTION, MODULE_REQUIREMENTS, MODULE_VERSION, MODULE_CREATED, MODULE_LICENSE, MODULE_AUTHOR_LINK, MODULE_PRICE, MODULE_PACKAGED |
aucun code | affichées telles quelles : le gestionnaire montre le fichier entier ; GetModuleMetadata les rend accessibles aux Blueprints |
MODULE_REQUIREMENTS n'est pas vérifié : aucun contrôle, aucune chaîne MODULE_REQUIREMENTS dans GI ; seuls
MODULE_UNIQUEID:, MODULE_NAME: et MODULE_AUTHOR: sont découpés (LPStringCompat::Split). Un mod dont un
prérequis manque se charge quand même. Les trois premières lignes sont lues par position : BuildMod.ps1 en contrôle
l'ordre. Réserve : la recherche dans les Blueprints porte sur les noms de clés écrits en clair ; une clé assemblée à
l'exécution n'y apparaîtrait pas.
3.3 Notions de visibilité, verrouillage, priorité et dépendances
| Notion | Jeu (.lpmod, Blueprints) |
Moteur (.uplugin) |
État |
|---|---|---|---|
| Visible / masqué | aucune notion : tout .lpmod présent est listé ; le gestionnaire affiche le fichier entier dans le panneau de détail (FullString) |
Hidden : lu, utilisé seulement par le navigateur de plugins de l'éditeur ; sans effet en jeu |
pas de masquage possible |
| Verrouillé / non désactivable | vin_Base en dur dans UI/ModuleTick (case sans effet, boutons d'ordre masqués) ; aucune clé .lpmod |
aucun verrouillage d'un plugin Mod : monté dès qu'il est présent |
seul vin_Base est verrouillé |
| Module système chargé avant les autres (dossier distinct) | aucun : tous les modules sont dans Content/Modules/<id> |
les plugins du jeu (Plugins/, cuits avec lui) sont configurés avant ceux de Mods/ |
existe côté moteur seulement, hors de portée d'un mod |
| Ordre de chargement / priorité | GI.ModEnableds ordonné, GI.SortLoadOrder ; le plus bas dans la liste affichée l'emporte, par nom de fichier (§ 2.4) ; fichiers texte seulement |
seul ordre réglable : LoadingPhase des modules de code (un mod n'en a pas) ; conteneurs montés avec la même priorité (FCoreDelegates::MountPak.Execute(PakPath, 0), PluginManager.cpp) |
ordre réel pour les textes, aucun pour les assets |
| Dépendances | MODULE_REQUIREMENTS non vérifié |
Plugins appliqué ; dépendance obligatoire absente : le jeu ne démarre pas ; Optional, Sealed, DisallowedPlugins (§ 3.1) |
côté jeu : aucune ; côté moteur : bloquante |
Conséquence pour les mods : ne jamais déclarer de dépendance obligatoire entre mods dans le .uplugin (un mod
manquant empêcherait le jeu de démarrer). Un prérequis entre mods se gère côté jeu (§ 6, E2).
3.4 Doublons entre descripteurs
| Information | .uplugin |
.lpmod |
pack.json / config |
Autres | Source de vérité | Écrit par |
|---|---|---|---|---|---|---|
| Identifiant | nom du fichier | MODULE_UNIQUEID |
chaine.mod |
dossiers | aucune désignée | NewMod.ps1, DeliverAnims.ps1 |
| Titre | FriendlyName |
MODULE_NAME |
source |
1re ligne de CREDITS.txt et de README.txt |
aucune désignée | NewMod.ps1, DeliverAnims.ps1 ; README par BuildMod.ps1 |
| Auteur | CreatedBy |
MODULE_AUTHOR |
auteur, enveloppé en « LifePlay Revival (animations by ) » |
aucune désignée | NewMod.ps1, DeliverAnims.ps1 |
|
| Description | Description |
MODULE_DESCRIPTION |
aucune désignée | NewMod.ps1, DeliverAnims.ps1 |
||
| Version | VersionName |
MODULE_VERSION |
README | .lpmod (recopié) |
BuildMod.ps1 : MODULE_VERSION → VersionName dans la copie livrée |
|
| Lien de l'auteur | CreatedByURL |
MODULE_AUTHOR_LINK |
url_auteur ou url |
.lpmod (recopié) |
BuildMod.ps1 : MODULE_AUTHOR_LINK → CreatedByURL |
|
| Licence | MODULE_LICENSE |
licence, credit |
CREDITS.txt, description |
aucune désignée | DeliverAnims.ps1 |
|
| Version du jeu visée | MODULE_GAME_VERSION |
README (×3), nom du zip | BuildMod.ps1 |
BuildMod.ps1 (ajoute aussi MODULE_PACKAGED) |
Tools/NewMod.ps1 et Tools/anim/DeliverAnims.ps1 écrivent le .uplugin et le .lpmod source. Tools/BuildMod.ps1
retouche la copie livrée (clés ci-dessus, plus MODULE_PACKAGED et MODULE_GAME_VERSION) et écrit le README depuis
le .lpmod.
Cause des divergences : DeliverAnims.ps1 crée les descripteurs une seule fois (New-IfMissing). Une modification
ultérieure de pack.json n'est jamais reportée. Divergences constatées :
lpr_anim_quaternius:MODULE_NAME« Quaternius Animations » contrepack.json:source« Quaternius Universal Animation Library (Standard) » ;MODULE_LICENSE« CC0 » contrepack.json:licence« CC0 1.0 ».lpr_hair_pocolov: auteur « LifePlay Revival (hairstyles by Pocolov) » (descripteurs) contre « Pocolov (Pocolov Studio, artist Thang) » (Tools/mods/lpr_hair_pocolov.json,CREDITS.txt).NewMod.ps1n'écrit pasMODULE_DEFAULT_ENABLED.
Champs constants ou sans usage : .uplugin FileVersion, Version (entier), Category, IsBetaVersion,
Installed ; .lpmod MODULE_REQUIREMENTS: vin_Base, MODULE_PRICE: Free, MODULE_LINK (URL du dépôt),
identiques dans les trois mods.
4. Classes et fichiers
| Élément | Rôle |
|---|---|
FPluginManager (moteur) |
découverte de Mods/, activation, montage du contenu |
| Registre d'assets (moteur) | AssetRegistry.bin des plugins, recherche par chemin / classe |
Plugins/ModdingExtra : LoadTxt, SaveTxt, GetAllFilesFromFolder, LPDataCache |
accès disque aux Modules (fichiers nus, DirectoriesToAlwaysStageAsNonUFS) ; cache analysé des formats CLÉ: valeur dont .lpmod |
Content/BPs/GI.uasset |
LoadSettings, ReadModLauncher, removeDeletedMods, PopulateRaws, IsModEnabled, CreateModManagerWidget, CloseModManager, ModEnableds |
UI/ModManager, UI/MainMenu |
gestionnaire de mods ; entrée de l'écran titre (LPTitleModManager) |
ULPModInfoSubsystem |
lecture des .lpmod, GetModuleMetadata, IsModuleEnabled, avertissement de version |
ULPModSettingsLibrary::SaveModSelection |
enregistre ModEnableds seul dans GameSettings.sav |
ULPHairstyleSubsystem |
MODULE_DEFAULT_ENABLED, coiffures .lphair des modules cochés |
ULPModDailiesSubsystem, ULPModDailiesLibrary::IsModDaily |
clips de mod → Room.Dailies ; reconnaissance des clés de mod dans Person::PlayDaily |
ULPSessionLogSubsystem |
inventaire des modules au démarrage (journal) |
| Outils | NewMod, EditMod, ModSource, BuildMod, SplitModules, HairPipeline, anim/AnimPipeline, anim/DeliverAnims |
5. Capacités actuelles
Un mod peut, sans recompiler ni recuire le jeu :
- ajouter ou modifier des données de jeu en texte (actions, scènes, stats, quêtes, dialogues, IA, personnages, mondes) ;
- apporter des assets cuits : coiffures (H3), animations (AP5–AP7), tout asset que le jeu trouve par le registre ;
- être coché ou décoché dans le gestionnaire (sauf les animations, § 6 E1), coché d'office au premier démarrage ;
- être ordonné avec les autres modules dans le gestionnaire (le plus bas l'emporte, par nom de fichier, pour les fichiers texte) ;
- prévenir le joueur s'il a été construit pour une autre version du jeu ;
- documenter licence, auteur, liens et crédits (affichés, non interprétés).
Il ne peut pas : apporter du code (C++ ou Blueprint exécuté en Shipping), remplacer un asset du jeu de base,
exiger un autre mod (MODULE_REQUIREMENTS n'est pas vérifié ; une dépendance .uplugin obligatoire bloquerait le
démarrage), ni être démonté à chaud (le plugin reste monté, décoché ou non).
6. Évolutions possibles
| Réf. | Évolution | Intérêt | Ampleur |
|---|---|---|---|
| E1 | LPModDailies : ne garder que les clips des modules cochés (même règle que IsModuleEnabled), au remplissage de Room.Dailies |
un seul interrupteur pour tous les types de contenu ; clé « inconnue » quand le mod est décoché | petit lot C++, essai empaqueté coché / décoché |
| E2 | Vérifier MODULE_REQUIREMENTS au démarrage et à la fermeture du gestionnaire (avertissement comme pour la version) |
prérequis manquant signalé au lieu d'un mod à moitié fonctionnel | petit lot C++ |
| E3 | Contrôle de cohérence des deux moitiés : Mods/<id> sans Modules/<id> (assets orphelins) ou l'inverse (.lphair / clés vers des assets absents) |
désinstallation partielle détectée | petit lot C++ |
| E4 | Avertissement de version élargi aux mods d'assets décochés (un conteneur incompatible est monté même décoché) | prévenir avant un échec de chargement | très petit |
| E5 | Détection des collisions : deux mods qui déclarent la même clé d'animation, la même coiffure, le même identifiant d'action | comportement déterministe, message clair | moyen |
| E6 | Lecture des trois premières lignes du .lpmod par clé plutôt que par position (Blueprint GI ou relais C++) |
un .lpmod écrit à la main dans le désordre ne casse plus le gestionnaire |
moyen (graphe de GI) |
| E7 | Ne pas monter les plugins des mods décochés (liste lue avant le montage, ExplicitlyLoaded + montage par IPluginManager::MountExplicitlyLoadedPlugin) |
mémoire et temps de démarrage ; mod réellement inerte | moyen, à prototyper (ordre de démarrage) |
| E8 | Déclaration explicite des animations (.lpanim : clé, clips F/M, catégorie, usage, posture) plutôt que par convention de nom |
catalogue en jeu, filtres par posture, alias, plusieurs variantes par clé | moyen |
| E9 | Autres types d'assets par le même schéma registre + fichier texte : vêtements, meubles, décors de pièce (.lpworld vers /<id>/…) |
extension naturelle de H3 | un lot par type |
| E10 | Empreintes dans l'archive (SHA-256 par fichier, vérifiées par un outil d'installation) | intégrité, mods modifiés détectés | petit (outillage) |
| E11 | Gestionnaire enrichi : description, licence, lien, version, état (cuit pour, prérequis, conflits), catalogue d'animations | information du joueur, aujourd'hui texte brut | moyen (UI) |
| E12 | Ordre étendu aux mods d'assets et clés d'animation (aujourd'hui seuls les fichiers texte suivent l'ordre) | surcharge contrôlée aussi pour les animations et les coiffures | moyen ; dépend de PopulateRaws et de LPModDailies |
| E13 | Notions déclarées dans le .lpmod : MODULE_LOCKED, MODULE_HIDDEN, MODULE_PRIORITY ou rang système, en remplacement du verrouillage en dur de vin_Base |
verrouillage, masquage et priorité par module, sans Blueprint codé en dur | moyen (graphe de UI/ModuleTick et de GI) |
| E14 | Descripteur unique : .lpmod (ou pack.json) source de vérité, .uplugin et README générés à chaque construction, New-IfMissing remplacé par une régénération |
fin des divergences entre descripteurs (§ 3.4) | petit à moyen (outillage) |
| E15 | Relevé LPDumpFunction : afficher le nom des événements personnalisés et des macros |
confirmer le sens de la boucle de PopulateRaws (§ 2.4) |
petit (outillage) |
Recommandation : E1 en premier (seule incohérence visible du joueur), puis E2 et E3 dans un même lot (mêmes
lectures que LPModInfoSubsystem), puis E14.