> Depuis le lot DC3 (2026-10-07), ces scripts, `ModSources/` et `AnimSources/` sont dans le dépôt addon `LifePlay-Sandbox` (même disposition relative ; lancer depuis l'addon, `D:\Game\LifePlay-Sandbox`).
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
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 |
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 |