LifePlay-Revival/Docs/Migration/16_H3_Mods_Paquets.md
edujiro5972 5a2829ebd9 H3d : metadonnees des mods, avertissement de version, paquet lpr_hair_pocolov (12 coiffures)
- 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>
2026-10-03 10:14:37 +02:00

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é) :

  1. créer un plugin de contenu dans Mods/<Nom> du projet ;
  2. y importer ses assets (coiffures : Tools/HairPipeline.ps1 avec folder = /<Nom>/Hairs) ;
  3. 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 ;
  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 sur FPackageName::DoesPackageExist si 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 tag v1.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.4 est coupé en 2026 et .10.4 (version 2026 créée, déplacée vers LifePlay_Backup_5.5\H3a) : passer par cmd /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 dans Content/Modules/ est livré avec le jeu. Les sources du mod d'essai sont donc dans ModSources/LPHairSample/ (.uplugin, Content/ non versionné, Module/ texte) ; pour la cuisson DLC, le plugin est placé temporairement dans Mods/ (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 de GI.ModEnableds est inactif ; LPHairstyleSubsystem le croyait actif (coiffure du mod présente, mod décoché). Corrigé : même règle que le jeu ; nouvelle clé .lpmod MODULE_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.ps1 accepte un dossier de plugin (/<Plugin>/... → Mods/<Plugin>/Content/...) et un fichier de crédits propre au mod (credits) ; Tools/HairMaterials.py contrôle les dépendances par chemin de paquet.
  • Relancer HairMaterials.py sur 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_exist faux) ; 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 -Rebuild d'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 /c avec 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.lpmod complété (MODULE_DEFAULT_ENABLED).
  • Outils des moddeurs : Tools/NewMod.ps1 (squelette ModSources/<Nom> : .uplugin, Module/<Nom>.lpmod, CREDITS.txt, et avec -Hairs Tools/mods/<Nom>.json), Tools/EditMod.ps1 (éditeur ouvert avec le mod monté, remis en place à la fermeture). Essai de NewMod.ps1 sur un mod jetable H3cTest (déplacé vers LifePlay_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ôle 09_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 contre Releases/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 .lpmod par le jeu (vérifiée dans GI) : 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 par Tools/NewMod.ps1), MODULE_PACKAGED, MODULE_GAME_VERSION (écrites par Tools/BuildMod.ps1 dans la copie livrée). BuildMod.ps1 contrôle l'ordre des trois premières lignes, reporte la version et le lien de l'auteur dans le .uplugin livré (VersionName, CreatedByURL), nomme l'archive <Nom>-<version>-for-LifePlay-<jeu>.zip et refuse un mod payant dont CREDITS.txt cite une licence non commerciale ou de magasin.
  • Avertissement : ULPModInfoSubsystem (C++, Source/LifePlay) lit les .lpmod et, toutes les 2 s, compare le MODULE_GAME_VERSION des 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 vers LifePlay_Backup_5.5\H3d). Métadonnées accessibles aux Blueprints : GetModuleMetadata(Module, Key).
  • Paquet lpr_hair_pocolov 1.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. Configuration Tools/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é). Archive lpr_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/Hairs et le module lp_Revival sont retirés du jeu (déplacés vers LifePlay_Backup_5.5\H3d\retires), leurs crédits passent dans le CREDITS.txt du paquet ; le mod d'essai LPHairSample est retiré (même dossier). Modules essentiels de la prochaine publication : Tools/modules/next.json.