DOC-MOD-2 : cycle de vie d'un mod, § 2.4, 3.1 à 3.4, 5, 6

Phase DOC-MOD-2 (CHG-226).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
edujiro5972 2026-10-07 15:49:58 +02:00
parent 135468380f
commit 18abdee4fc
2 changed files with 87 additions and 7 deletions

View file

@ -98,6 +98,30 @@ moitié n'a pas été laissée seule (voir § 6).
| 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.ModEnableds` est ordonné. Les boutons monter / descendre de chaque ligne du gestionnaire (`UI/ModuleTick`)
appellent l'événement `GI.SortLoadOrder(ForUp, ModuleIndex)`, qui échange deux éléments de `ModEnableds`
(`Array_Swap`) puis reconstruit la liste (`AddTempModuleTicks`). `GI.ToggleMod(Mod, IsEnabled)` parcourt
`ModEnableds` et remplace l'élément dont `UniqueID` correspond.
- 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é (garde `ModuleIndex == 1 && ForUp == 1`), de même qu'un indice hors bornes.
- Effet (`PopulateRaws`, événement de `GI`) : boucle sur `ModEnableds` du début à la fin, modules cochés seulement.
Pour chaque type (`lpstat`, `lpaction`, `lpscene`, `lptalk`, `lpdesc`, `lpquest`, `lpai`), les fichiers de
`Modules/<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.txt` l. 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 `GI` contient aussi une `ReverseForEachLoop`.
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 `PopulateRaws` le 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 |
@ -119,7 +143,11 @@ Convention des clés d'animation : `<préfixe du pack>_<clip>` en minuscules (`q
| `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`, `SupportedTargetPlatforms`, `EngineVersion` | oui si présentes | dépendances, plateformes ; `EngineVersion` ne fait qu'avertir |
| `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)
@ -133,9 +161,54 @@ Convention des clés d'animation : `<préfixe du pack>_<clip>` en minuscules (`q
| `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é : 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.
`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 <auteur>) » | | 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 » contre `pack.json:source` « Quaternius Universal
Animation Library (Standard) » ; `MODULE_LICENSE` « CC0 » contre `pack.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.ps1` n'écrit pas `MODULE_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
@ -160,11 +233,14 @@ 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, ni être démonté à chaud.
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
@ -181,7 +257,10 @@ exiger un autre mod, ni être démonté à chaud.
| 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 de chargement des modules (priorité dans `.lpmod`) | surcharge contrôlée d'un module par un autre | moyen ; dépend de `PopulateRaws` |
| 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`).
lectures que `LPModInfoSubsystem`), puis E14.

View file

@ -1131,6 +1131,7 @@ Validation L7c/L7d (2026-10-02, parc, même cadrage) : la nuit reste claire (sol
| CHG-155 | 2026-10-05 | ShowCouple | Un lit est reconnu par son nom. Il ne bloque un déplacement que vers le bas, pour se poser ; le retour horizontal n'est plus arrêté et le contact ne renvoie plus la boîte | après avoir quitté le lit, la boîte ne pouvait plus y revenir | revenir au test `DoesPackageExist` et au filtre du flanc seul |
| CHG-156 | 2026-10-05 | Clavier | `LPKeyboardSubsystem` : bouton « Clavier » ajouté à l'exécution dans `MainMenu.SettingsScrollBox` ; panneau pour changer, ajouter ou retirer une touche (actions et axes clavier). Écrit dans `Saved/Config/Windows`, pas dans `GameSettings.sav` | pouvoir réaffecter les touches, dont Q, sans modifier les Blueprints | retirer `LPKeyboardSubsystem.h/.cpp` et la dépendance `UMG` |
| CHG-158 | 2026-10-05 | Réglages | `LPSettingsSubsystem` : onglets Audio, Video, Lewd, General, Keyboard, Misc au-dessus de `SettingsScrollBox`. Les lignes du Blueprint restent en place et sont montrées selon leur texte ; le reste va dans Misc. Keyboard affiche la liste des touches | la liste unique ne montrait pas le clavier | retirer `LPSettingsSubsystem.h/.cpp` |
| CHG-226 | 2026-10-07 | DOC-MOD-2 | `Docs/Migration/23_Cycle_De_Vie_Mod.md` (§ 2.4, 3.1, 3.2, 3.3 et 3.4 nouveaux, 5, 6) ; `Docs/Migration/Journal_Modifications.md` | complément de la documentation du cycle de vie d'un mod, constats vérifiés dans les Blueprints (`GI`, `UI/ModuleTick`, relevés `LPDumpFunction`) et le moteur UE 5.5 : l'ordre de chargement existe (`GI.SortLoadOrder`, `PopulateRaws` : le premier fichier lu par nom gagne, le module le plus bas l'emporte, fichiers texte seulement) ; `vin_Base` verrouillé en dur dans `UI/ModuleTick` ; dépendance `.uplugin` obligatoire absente = le jeu ne démarre pas, donc aucune dépendance entre mods dans le `.uplugin` ; doublons entre `.uplugin`, `.lpmod` et `pack.json`, divergences dues à `New-IfMissing` de `DeliverAnims.ps1` ; évolutions E12 corrigée, E13 à E15 ajoutées | aucun changement de code ni de configuration | `.\Tools\Restore.ps1 -Lot DOC-MOD-2` |
| CHG-225 | 2026-10-07 | DOC-MOD | `Docs/Migration/23_Cycle_De_Vie_Mod.md` (nouveau) ; `Docs/Migration/README.md` (ligne d'index) | documentation demandée par l'utilisateur : cycle de vie d'un mod, propriétés réellement lues par le moteur (`.uplugin`) et par le jeu (`.lpmod`), classes, architecture, capacités, évolutions possibles. Constat consigné : `LPModDailies` ne consulte pas la case du gestionnaire de mods (un pack d'animations décoché fournit encore ses clés, évolution E1) ; `MODULE_REQUIREMENTS` n'est pas vérifié | aucun changement de code ni de configuration | supprimer `23_Cycle_De_Vie_Mod.md` et cette entrée ; `.\Tools\Restore.ps1 -Lot DOC-MOD` |
| CHG-224 | 2026-10-07 | AP7 | Cuisson DLC et essai en jeu empaqueté. `Config/DefaultGame.ini` : `ProjectVersion=2026.10.1.6` (version de référence d'essai, non publiée) ; `+DirectoriesToNeverCook` pour `/Game/Quaternius`, `/Game/FreeAnimationsPack`, `/Game/AnimPacks`, `/Game/Retarget_ue5` (sources de travail, jamais dans le jeu). `Tools/anim/DeliverAnims.py` : à la copie dans le mod, les réglages de compression qui pointent sur `/Engine/` sont remis à vide (les clips d'un pack UE5 référençaient `/Engine/Animation/DefaultAnim*CompressionSettings` : cuisson DLC refusée) ; la compression par défaut du projet s'applique, comme pour Quaternius | lot AP7, étape 7. Empaquetage Shipping `2026.10.1.6` (`D:\Game\LifePlay_Build_5.5_Shipping_AP7\Windows`, `Releases/2026.10.1.6`) ; mods cuits contre cette version : `lpr_anim_quaternius` (84 paquets, zip 15 798 332 o), `lpr_anim_freeanims` (20 paquets, 0 référence moteur, zip 4 416 299 o) dans `D:\Game\LifePlay_Publication\Mods\` ; module d'essai `lpr_anim_essai` copié dans le seul jeu d'essai (hors du projet : `LifePlay_Backup_5.5/AP7/hors_build`). **Essai utilisateur en jeu empaqueté : animations jouées** (`qua_*`, `fap_*`, témoin `dance`) | `.\Tools\Restore.ps1 -Lot AP7` ; supprimer `D:\Game\LifePlay_Build_5.5_Shipping_AP7` et `Releases/2026.10.1.6` ; rien n'est commité dans le dépôt du jeu |
| CHG-223 | 2026-10-07 | AP7 | Pilote. `Tools/anim/AnimPipeline.ps1` (étapes 0 inventaire, 1 import, 2 identification, 3 calque, 4 conversion + torsion, 5 évaluation + rapport HTML + vignettes et planches par la sandbox, 6 livraison dans le mod + fiches + catalogue, 7 cuisson DLC ; rapport JSON par étape dans `Saved/AnimPipeline/<pack>/etapes`, `etat.json`, arrêt au premier contrôle en échec, reprise `-From`, ancien contenu déplacé dans `precedent_<date>`, `-DryRun`, `-SansCuisson`) ; `BuildMod.ps1 -Anim <pack>` ; `pack.json` étendu (bloc `chaine` : méthode, profil attendu, source glb|uasset, sorties, corps et gabarits Daz `Idle_F_Daz` / `idle_Daz`, mod, dossier de travail, sortie sandbox) ; `AnimSources/freeanims/pack.json` (licence CC BY 4.0, auteur SoerGame, page Fab, page de l'auteur `url_auteur`, 10 animations déclarées) ; outils de livraison et de catalogue génériques (`DeliverAnims -Pipeline -Pack -Vignettes -Planches`, textes du mod et lien d'auteur tirés de `pack.json`, adresse de la source dans `CREDITS.txt`). Défauts corrigés pendant les passages réels : console `start /wait` restée ouverte (lancement par `cmd /c`), lancement de la sandbox par un tuyau qui attendait sa fermeture | lot AP7. Quaternius de bout en bout (reprises à l'étape 4 puis 5 après corrections) : mesures, verdicts, fiches et catalogue identiques au passage précédent (42 fiches, 42 vignettes, 42 planches) ; FreeAnimationsPack de bout en bout en 10 min, code 0 : mod `lpr_anim_freeanims` (10 clips × 2, `.lpmod` CC BY 4.0, crédits), catalogue de 10 fiches. Étape 7 (cuisson DLC) non faite : la version de référence `Releases/2026.10.1.5` (V1.5) ne contient ni le correctif de `Person` ni `LPModDailies` ; nouvel empaquetage à décider avec l'utilisateur | `.\Tools\Restore.ps1 -Lot AP7` (jeu) et `.\Tools\Restore.ps1 -Lot AP7-addon -ProjectRoot D:\Game\LifePlay-Sandbox` (sources de l'addon ; les commits de l'addon restent dans son historique) ; rien n'est commité dans le dépôt du jeu |