- LPModInfoSubsystem : metadonnees des .lpmod ; fenetre d'avertissement quand un mod actif a ete construit pour une autre version du jeu (Slate, sans Blueprint). - NewMod/BuildMod : MODULE_VERSION, _CREATED, _LICENSE, _AUTHOR_LINK, _PRICE, _PACKAGED, _GAME_VERSION ; ordre des 3 premieres lignes controle ; prix et licences controles. - lpr_hair_pocolov 1.0 : les 12 coiffures Pocolov CC BY ; lp_Revival et les 6 Pocolov retires du jeu de base ; mod d'essai LPHairSample retire. Valide en jeu le 2026-10-03 (CHG-106, CHG-107). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 KiB
16. H3 : assets apportés par les mods (étude, 2026-10-03)
Objectif : qu'un mod apporte ses propres maillages, textures et matériaux (coiffures d'abord, puis vêtements, meubles,
animations) sans recompiler ni recuire le jeu. Aujourd'hui, un mod Content/Modules/<mod> ne contient que du texte :
tout asset doit être cuit avec le jeu (lots H1, H2).
1. Constats (lecture du moteur 5.5 et de la configuration du projet)
| Point | Constat | Source |
|---|---|---|
| Dossier des mods | Dans un jeu empaqueté, le gestionnaire de plugins lit toujours <jeu>/Mods/ (« Always add the mods from the loose directory ») ; chaque Mods/<Nom>/<Nom>.uplugin devient un plugin de type Mod |
PluginManager.cpp, ReadAllPlugins |
| Activation | un plugin Mod est considéré comme chargé depuis le projet : activé par défaut |
FPlugin::IsEnabledByDefault |
| Paquets | pour un plugin de contenu, les paquets Mods/<Nom>/Content/Paks/Windows/*.pak (et leurs conteneurs IoStore .utoc/.ucas) sont montés au démarrage ; ses assets ont le préfixe /<Nom>/ |
PluginManager.cpp, montage des paquets de plugins |
| Registre d'assets | au démarrage, le registre ajoute le AssetRegistry.bin de chaque plugin de contenu activé : les assets du mod sont trouvables par classe et par nom (GetAssetsByClass, utilisé par le jeu pour vêtements, animations, meubles…) |
AssetRegistry.cpp, LoadPremadeAssetRegistry_Plugins |
| Signature | aucun DefaultCrypto.ini : paquets non signés, non chiffrés |
Config/ |
| Shaders | bShareMaterialShaderCode=False : les shaders sont dans les matériaux eux-mêmes, pas de bibliothèque partagée à fournir ; une instance de matériau (DazHair) n'en ajoute aucun |
DefaultGame.ini |
| Format | le jeu est cuit en conteneurs IoStore (O2) : un mod doit l'être aussi, avec le même moteur et contre la même version cuite du jeu | DefaultGame.ini |
Le mécanisme existe donc dans le moteur ; il n'a jamais été utilisé par LifePlay.
2. Architecture proposée
<jeu>/LifePlay/Mods/<Nom>/<Nom>.uplugin descripteur (plugin de contenu, type Mod)
<jeu>/LifePlay/Mods/<Nom>/AssetRegistry.bin registre des assets du mod
<jeu>/LifePlay/Mods/<Nom>/Content/Paks/Windows/<Nom>*.pak/.utoc/.ucas assets cuits
<jeu>/LifePlay/Content/Modules/<Nom>/<Nom>.lpmod module LifePlay (texte, comme aujourd'hui)
<jeu>/LifePlay/Content/Modules/<Nom>/Hairstyles/*.lphair HAIRSTYLE: /<Nom>/Hairs/X.X
Un mod se distribue en une archive à extraire dans le dossier du jeu. Le texte reste dans Modules (gestionnaire de
mods, activation, données) ; les assets sont dans Mods (moteur). Désactiver le module retire ses coiffures
(H1) ; le paquet reste monté mais n'est plus utilisé.
Fabrication d'un mod (par un moddeur, avec le projet source publié) :
- créer un plugin de contenu dans
Mods/<Nom>du projet ; - y importer ses assets (coiffures :
Tools/HairPipeline.ps1avecfolder=/<Nom>/Hairs) ; - cuire ce seul plugin en DLC contre la version publiée du jeu :
RunUAT BuildCookRun ... -cook -stage -pak -iostore -dlcname=<Nom> -basedonreleaseversion=2026.10.4; - assembler l'archive du mod (plugin cuit + module texte).
Côté jeu : rien à recompiler pour le montage. À ajuster :
LPHairstyleSubsystem: contrôle d'une coiffure par le registre (déjà) avec repli surFPackageName::DoesPackageExistsi le registre du mod manquait ;- version de référence : chaque publication doit produire
Releases/<version>/Windows/(option-createreleaseversion=<version>du build de distribution) et la livrer avec les sources ; un mod est cuit contre elle. Pour la V1.4 publiée, elle se recrée par une cuisson incrémentale (contenu inchangé depuis le tagv1.4).
3. Risques et inconnues à lever par un prototype
| Risque | Conséquence | Vérification |
|---|---|---|
Cuisson DLC dans ce projet (plugin dans Mods/, -basedonreleaseversion) |
outil des moddeurs inutilisable | cuisson d'un mod d'essai |
| Compatibilité du conteneur IoStore du mod avec celui du jeu publié | mod non chargé, ou plantage au chargement | montage dans une copie du build Shipping V1.4 |
Références du mod vers le jeu (squelette Genesis, matériau DazHair) |
coiffure sans matériau ou sans squelette | contrôle visuel en jeu |
| Mod cuit contre une version, joué avec une autre | incompatibilités si les assets référencés changent | règle : un mod indique la version du jeu ; les assets de base référencés (squelettes, matériaux maîtres) ne sont plus renommés |
Taille de Releases/<version> à livrer avec les sources |
dépôt alourdi | mesure ; hors git si volumineux (archive des sources seulement) |
| Mods malveillants | un paquet ne contient que des assets cuits (pas de code) ; les plugins de code ne sont pas chargés dans un jeu Shipping sans binaire compatible | rien à faire au-delà de l'avertissement |
4. Lots proposés
| Lot | Contenu | Sortie |
|---|---|---|
| H3a, prototype | version de référence Releases/2026.10.4 ; mod d'essai LPHairSample (une coiffure Pocolov non encore intégrée, ex. Pocolov 05/07) ; cuisson DLC ; installation dans une copie du build Shipping V1.4 |
coiffure du mod visible et fonctionnelle en jeu, sans recuire le jeu |
| H3b, outillage | Tools/BuildMod.ps1 (squelette de plugin, cuisson DLC, archive du mod) ; option HairPipeline vers /<Nom>/ ; repli DoesPackageExist dans le sous-système |
un mod de coiffures en une commande |
| H3c, documentation moddeurs | guide (anglais) : créer, cuire, distribuer, compatibilité de version ; intégration de la création de Releases/<version> au protocole de publication |
guide publié avec la version suivante |
5. Prototype H3a (2026-10-03) : résultats
Validé en jeu le 2026-10-03 : la coiffure Pocolov 05, apportée par un mod cuit à part, est chargée par le jeu publié sans recuisson du jeu ; décocher le mod la retire.
| Étape | Résultat |
|---|---|
| Version de référence | -createreleaseversion=2026.10.4 (build Shipping, cuisson incrémentale) : Releases/2026.10.4/Windows ; paquets identiques octet pour octet à ceux du V1.4 publié. Taille : 1,3 Go (copie complète des paquets du jeu, à livrer aux moddeurs : H3c) |
| Mod d'essai | plugin LPHairSample (CanContainContent), coiffure importée par Tools/HairPipeline.ps1 -Config Tools/mods/LPHairSample.json dans /LPHairSample/Hairs ; dépendances : ses assets et /Game/Heavy/Daz/Bridget/Hairs/DazHair |
| Cuisson DLC | -dlcname=<chemin du .uplugin> -basedonreleaseversion=2026.10.4 : 6 paquets, 0 erreur, 0 avertissement ; LPHairSampleLifePlay-Windows.pak/.utoc/.ucas (≈ 337 Ko) ; le .pak contient le AssetRegistry.bin du mod |
| Installation | <jeu>/LifePlay/Mods/LPHairSample/ (.uplugin + Content/Paks/Windows/*) et <jeu>/LifePlay/Content/Modules/LPHairSample/ (.lpmod, .lphair, CREDITS.txt) |
| Compatibilité | mod cuit contre 2026.10.4, chargé aussi par le build UI15b (menu principal modifié depuis) |
Commandes :
cmd /c '"<UE>\Build\BatchFiles\RunUAT.bat" BuildCookRun -project="<projet>" -platform=Win64 -clientconfig=Shipping -build -cook -iterate -stage -pak -iostore -compressed -createreleaseversion=2026.10.4 -archive -archivedirectory=<dossier> -nodebuginfo -unattended -utf8output -nop4'
cmd /c '"<UE>\Build\BatchFiles\RunUAT.bat" BuildCookRun -project="<projet>" -platform=Win64 -clientconfig=Shipping -cook -stage -pak -iostore -compressed -dlcname="<projet>\Mods\LPHairSample\LPHairSample.uplugin" -basedonreleaseversion=2026.10.4 -nodebuginfo -unattended -utf8output -nop4'
Enseignements :
- Version en argument : appelé directement depuis PowerShell,
-createreleaseversion=2026.10.4est coupé en2026et.10.4(version2026créée, déplacée versLifePlay_Backup_5.5\H3a) : passer parcmd /c '…'. - Sources des mods hors du jeu de base : un plugin dans
<projet>/Mods/est un plugin Mod chargé par l'éditeur et cuit avec le jeu ; un module dansContent/Modules/est livré avec le jeu. Les sources du mod d'essai sont donc dansModSources/LPHairSample/(.uplugin,Content/non versionné,Module/texte) ; pour la cuisson DLC, le plugin est placé temporairement dansMods/(H3b :Tools/BuildMod.ps1). Les builds de test H3a/UI15 ont été faits avec les sources sorties du projet ; vérifié : aucun asset/LPHairSample/dans les paquets du jeu. - Activation des modules (défaut de H1, présent en V1.4) : pour le jeu (
GI.IsModEnabled, gestionnaire de mods), un module absent deGI.ModEnabledsest inactif ;LPHairstyleSubsystemle croyait actif (coiffure du mod présente, mod décoché). Corrigé : même règle que le jeu ; nouvelle clé.lpmodMODULE_DEFAULT_ENABLED: true, qui ajoute le module coché à la liste des mods s'il n'y figure pas (lp_Revival, livré avec le jeu). - Gestionnaire de mods : accessible seulement en partie ; entrée ajoutée sur l'écran titre (lot UI15, 17_Mods_Ecran_Titre.md).
Tools/HairPipeline.ps1accepte un dossier de plugin (/<Plugin>/...→Mods/<Plugin>/Content/...) et un fichier de crédits propre au mod (credits) ;Tools/HairMaterials.pycontrôle les dépendances par chemin de paquet.- Relancer
HairMaterials.pysur une coiffure dont les textures existent déjà dans un plugin fait planter la commandlet (boîte de dialogue de remplacement à l'import) : à traiter en H3b.
6. Outillage H3b (2026-10-03)
Validé en jeu le 2026-10-03 (build LifePlay_Build_5.5_H3b, mod installé par l'outil).
Organisation d'un mod d'assets :
ModSources/<Nom>/<Nom>.uplugin plugin de contenu (versionné)
ModSources/<Nom>/Content/ assets du mod (non versionnés, comme Content/Heavy)
ModSources/<Nom>/Module/ module LifePlay en texte : <Nom>.lpmod (MODULE_UNIQUEID = <Nom>),
Hairstyles/*.lphair, CREDITS.txt (versionnés)
<projet>/Mods/ reste vide : Tools/ModSource.ps1 y déplace le mod le temps d'un travail (import, cuisson) puis le
remet dans ModSources/ (déplacements seulement). Le build du jeu de base ne contient donc rien des mods sans
manipulation (vérifié : aucun asset /LPHairSample/, ni Mods/, ni module dans le build H3b).
Fabrication :
.\Tools\HairPipeline.ps1 -Config Tools\mods\<Nom>.json -Step Inspect # "mod": "<Nom>", "folder": "/<Nom>/Hairs"
.\Tools\HairPipeline.ps1 -Config Tools\mods\<Nom>.json -Step Apply
.\Tools\BuildMod.ps1 -Name <Nom> [-Version 2026.10.4] [-Out D:\Game\LifePlay_Publication\Mods] [-Install <jeu>\Windows]
BuildMod.ps1 : contrôles (plugin, module, version de référence Releases/<version>, aucun autre plugin dans Mods/),
cuisson DLC par un .cmd écrit à côté du journal (Saved/Logs/portage/mods/), contrôle du conteneur (toutes les
entrées sous Mods/<Nom>/), assemblage <Nom>-for-LifePlay-<version> (LifePlay/Mods/<Nom>,
LifePlay/Content/Modules/<Nom>, README.txt bilingue), archive .zip testée ; un assemblage précédent est déplacé
(precedent_<date>). Mod d'essai : LPHairSample-for-LifePlay-2026.10.4.zip, 334 Ko, 8 fichiers.
Corrections du lot :
Tools/HairMaterials.py: dans un plugin, le registre d'assets de la commandlet ne connaît pas encore les assets existants (does_asset_existfaux) ; la création d'un matériau existant ouvrait une boîte de dialogue et plantait (Assertion failed: IsValid()). Analyse synchrone du dossier au départ ; texture déjà importée depuis la même source réutilisée (autre source dans un plugin : refus,-Rebuild).HairPipeline.ps1 -Rebuildd'un mod déplace aussi les textures vers la sauvegarde ; une reconstruction demande une nouvelle inspection (les maillages de travail sont rangés dans la sauvegarde après chaque application).LPHairstyleSubsystem: coiffure de mod absente du registre d'assets acceptée si son paquet existe (FPackageName::DoesPackageExist, avertissement).BuildMod.ps1:cmd /cavec guillemets imbriqués échoue depuis PowerShell (« syntaxe du nom de fichier incorrecte ») ; d'où le fichier.cmd.
7. Documentation et publication (H3c, 2026-10-03)
- Guide des moddeurs (anglais, avec les guides d'origine de Vinfamy) :
Docs/Modding/FullGuides/Creating_Asset_Mods.md(fonctionnement, prérequis, création, coiffures, éditeur, cuisson et essai, diffusion, dépannage) ;Docs/Modding/ShortGuides/explanation.lphair(format.lphair) ;explanation.lpmodcomplété (MODULE_DEFAULT_ENABLED). - Outils des moddeurs :
Tools/NewMod.ps1(squeletteModSources/<Nom>:.uplugin,Module/<Nom>.lpmod,CREDITS.txt, et avec-HairsTools/mods/<Nom>.json),Tools/EditMod.ps1(éditeur ouvert avec le mod monté, remis en place à la fermeture). Essai deNewMod.ps1sur un mod jetableH3cTest(déplacé versLifePlay_Backup_5.5\H3c) : fichiers conformes, nom déjà pris refusé. - Publication : la version de référence fait partie de chaque publication (
10_Protocole_Operations.md§6, liste de contrôle09_Commandes_Utiles.md§7). L'archive des sources V1.4 publiée ne la contient pas : les mods d'assets sont donc possibles pour les moddeurs à partir de la publication suivante (la V1.4 reste jouable avec des mods cuits ici contreReleases/2026.10.4). - Ne pas faire de build complet destiné à la publication sans recréer la version de référence correspondante.
8. Métadonnées, avertissement de version et paquet Pocolov (H3d, 2026-10-03)
Validé en jeu le 2026-10-03 (build LifePlay_Build_5.5_H3d).
- Lecture des
.lpmodpar le jeu (vérifiée dansGI) : seules les lignes 1 à 3 sont lues, par position (MODULE_UNIQUEID,MODULE_NAME,MODULE_AUTHOR) ; le gestionnaire de mods affiche le fichier entier (ModuleTick.FullString). Toute ligne ajoutée après la troisième est donc sans risque et visible des joueurs. - Clés ajoutées :
MODULE_VERSION,MODULE_CREATED,MODULE_LICENSE,MODULE_AUTHOR_LINK,MODULE_PRICE(écrites parTools/NewMod.ps1),MODULE_PACKAGED,MODULE_GAME_VERSION(écrites parTools/BuildMod.ps1dans la copie livrée).BuildMod.ps1contrôle l'ordre des trois premières lignes, reporte la version et le lien de l'auteur dans le.upluginlivré (VersionName,CreatedByURL), nomme l'archive<Nom>-<version>-for-LifePlay-<jeu>.zipet refuse un mod payant dontCREDITS.txtcite une licence non commerciale ou de magasin. - Avertissement :
ULPModInfoSubsystem(C++,Source/LifePlay) lit les.lpmodet, toutes les 2 s, compare leMODULE_GAME_VERSIONdes modules actifs àProjectVersion; un écart ouvre une fenêtre Slate « Mod version warning » (indépendante des Blueprints, aussi sur l'écran titre), une fois par module et par session. Testé avec un module texte déclaré pour 2026.9.1 (déplacé ensuite versLifePlay_Backup_5.5\H3d). Métadonnées accessibles aux Blueprints :GetModuleMetadata(Module, Key). - Paquet
lpr_hair_pocolov1.0 : sur 192 produits Pocolov (Fab), les 12 coiffures CC BY (03, 05, 06, 07, 09, 10, 11, 13, 14, 15, 16, 17) ; exclus : 5 coiffures payantes (licence standard Fab : redistribution interdite), vêtements « Avatall » (autre squelette), objets, armes, véhicules. ConfigurationTools/mods/lpr_hair_pocolov.json(réglages HAIRS1 repris ; détection identique aux choix validés). Pocolov 07, 09, 10, 13, 14 téléchargées (CC BY 4.0, accord du 2026-10-03). La Pocolov 09 a sa calotte en maillage séparé, non convertie : rendu jugé correct en jeu.MODULE_DEFAULT_ENABLED: true(les sauvegardes qui utilisaient les anciennes coiffures du jeu les retrouvent dès que le paquet est installé). Archivelpr_hair_pocolov-1.0-for-LifePlay-2026.10.4.zip(3,8 Mo, 70 paquets cuits). - Jeu de base allégé : les 6 Pocolov de
/Game/Heavy/New5/Hairset le modulelp_Revivalsont retirés du jeu (déplacés versLifePlay_Backup_5.5\H3d\retires), leurs crédits passent dans leCREDITS.txtdu paquet ; le mod d'essaiLPHairSampleest retiré (même dossier). Modules essentiels de la prochaine publication :Tools/modules/next.json.