Fiche U1-T1 — Niveau N3 — Modèle prévu opus-xhigh | utilisé claude-opus-5-5 — Agent lp-cart — Skills sk-protocol, ue-cpp-build, lp-commandlets, lp-paths (préchargés) ; lp-ue-compat (outil Skill absent : `SKILL.md` lu comme fichier) # U1-T1 — Montage des mods : diff des sources moteur 5.5 / 5.8 (risque R2 d'UA-MODS) Lot U1 du plan [27_Plan_Migration_UE58.md](../../../../27_Plan_Migration_UE58.md), synthèse 28. Date : 2026-10-08. Lecture seule (moteurs, jeu, addon) ; seul fichier écrit : celui-ci. Aucune compilation, aucun éditeur, aucun git d'écriture. - Moteurs : `E5` = `D:\Game\Launcher\Engine\UE_5.5\Engine\Source` (5.5.4, CL 40574608, `Engine/Build/Build.version`) ; `E8` = `D:\Game\Launcher\Engine\UE_5.8\Engine\Source` (5.8.3, CL 58210709). Sources complètes dans les deux (fichiers de la fiche § 4 présents, `ls`). Une référence `fichier:a → :b` = ligne `a` dans `E5`, ligne `b` dans `E8`. - « R2 » ici = risque R2 d'`UA-MODS.md` § 5 (découverte / montage de `Mods/` modifié). À ne pas confondre avec R2 de `lp-ue-compat` (C2664 `LPDataCache.cpp:198`, hors chemin de montage) ni avec R2 de la synthèse 28 (resave). - Statuts : **établi** = lu dans le code ou un fichier (référence) ; **estimé** = déduit, raisonnement donné ; **incertain** = à trancher par l'essai nommé. ## 1. Résumé - **Le contrat tient sans changement de code** (établi) : dossier `Mods//`, `.uplugin` sans `Modules`, type `Mod`, activation par défaut, montage automatique de `Content/Paks/Windows/*.pak` (+ `.utoc/.ucas`) avec l'ordre 0, point de montage `//`, registre `Mods//AssetRegistry.bin` lu dans le paquet, `-dlcname -basedonreleaseversion`, chemin `Releases//Windows`. Les changements 5.8 sont des réécritures internes sans effet sur notre disposition. - **Trois changements de comportement** à connaître (établis dans le code, sans effet sur le contrat) : (1) en 5.8 le `.pak` n'est monté que si son conteneur IoStore l'est aussi (avant : pak monté même si IoStore échouait) ; (2) le `AssetRegistry.bin` d'un plugin n'est plus cherché que **dans les paquets** quand le jeu tourne sur paquets ; (3) le `.uplugin` est lu par RapidJson au lieu de `FJsonSerializer`. - **Binaires** : tout change (pak v11 → v12, en-tête de conteneur v4 → v5, versions d'objet UE5 1013 → 1018, versions personnalisées en hausse). Recuisson obligatoire, déjà prévue (U7). Conséquence nouvelle (estimé) : un mod **5.8** installé dans le jeu **5.5** provoque un arrêt fatal au démarrage (version de pak 12 refusée) ; un mod **5.5** dans le jeu **5.8** est monté **sans erreur** et n'échoue qu'au chargement d'un asset (incertain : T4). - **Verdict R2** : rupture du mécanisme écartée par lecture du code (établi) ; reste une confirmation d'exécution en build empaqueté 5.8 (test T-M1, § 6). Pas d'escalade N4 nécessaire. ## 2. Tableau des écarts (fiche § 4) Effet sur le contrat : **aucun** / **à adapter** / **rupture**. « Binaire » = rupture du format cuit, attendue et couverte par la recuisson (U7), sans effet sur la forme du contrat. | # | Sujet | 5.5 (`E5`) | 5.8 (`E8`) | Effet | Statut | |---|---|---|---|---|---| | **A** | **`Runtime/Projects/Private/PluginManager.cpp`** | | | | | | A1 | Découverte de `Mods/` | `ReadPluginsInDirectory(FPaths::ProjectModsDir(), EPluginType::Mod, …)` `:891-892`, hors manifestes (« Always add the mods from the loose directory ») | identique `:903-904` ; `ProjectModsDir()` = `ProjectDir()+"Mods/"` `Core/Private/Misc/Paths.cpp:501-504 → :518-521` | aucun | établi | | A2 | Recherche des `.uplugin` (`FindPluginsInDirectory`) | `:1083-1129` : descente arrêtée au premier `.uplugin` d'un dossier | `:1120-1178` : idem + sous-dossiers finissant par `/Content` exclus (`:1144-1150`) | aucun (`.uplugin` est au niveau 1, son `Content/` n'était déjà pas exploré) ; seul cas perdu : un dossier nommé `Mods/Content/…` | établi | | A3 | Type `Mod`, libellé | `AddToPluginsList` `:640-642` ; `EnumToString` « Mod » `:486` | `:649-651` ; `:495` | aucun | établi | | A4 | Lecture du `.uplugin` | `FJsonSerializer` (`PluginDescriptor.cpp:132`) ; `FileVersion` ≤ `Latest` = 3 (`:64`, `:172`) ; `EnabledByDefault` / `CanContainContent` `:266-272` | RapidJson `UE::Json::Parse` (`PluginDescriptor.cpp:216`, virgules finales tolérées `Json/Private/JsonUtils/RapidJsonUtils.cpp:9`, `:243-256`) ; `Latest` = 3 (`:66`, `:273`) ; mêmes champs `:361-367` ; lecteur personnalisé jamais lié dans le moteur (`grep CustomPluginDescriptorReaderDelegate`) | aucun : nos `.uplugin` (addon `ModSources/*/*.uplugin`, archives `LifePlay_Publication/Mods/lpr_*`) = JSON strict, sans BOM (octets `7b 0d 0a`), `FileVersion: 3` ; réécriture `BuildMod.ps1:275` en UTF-8 sans BOM | établi | | A5 | Activation par défaut | `IsEnabledByDefault` `:412-426` ; `GetLoadedFrom` (Mod → Project) `:428-438` ; boucle « AddPluginsEnabledByDefault » `:1751-1767` | identiques `:421-435`, `:437-447`, `:1740-1756` (déplacée dans `FindTargetPlugins` `:1604`) | aucun (descripteurs sans `EnabledByDefault` → `Unspecified` → activé ; `.uproject` ne cite aucun `lpr_*`) | établi | | A6 | Montage des paquets du plugin | dans `ConfigureEnabledPlugins` `:1386` : journal « Mounting %s plugin %s » `:1973` ; `Content/Paks/` récursif `:2009-2029` si `RequiresCookedData` `:2014` ; `MountPak.Execute(PakPath, 0)` `:2023` | refactorisé : `ProcessEnabledPlugins` `:1875` (appel `:2066`) ; journal `:1926` ; `:1964-1985`, `:1969`, `MountPak.Execute(PakPath, 0)` `:1978` | aucun (même dossier, même ordre 0, même délégué) | établi | | A7 | Point de montage `//` | `RegisterMountPointDelegate.Execute(GetMountedAssetPath(), ContentDir)` `:2061` | `MountContentPlugins` `:1991`, `:2018` (appel `:2068`) | aucun | établi | | A8 | Montage rapide « BinaryConfig » | `QuickMountingPaks` / `Core.System:PluginPaks` `:1890-1925` ; `IntegratePluginsIntoConfig` `:1304-1367` (ignore les Mods `:1327-1331`) | supprimé ; `IntegratePluginsIntoConfig` = stub `UE_DEPRECATED(5.6)` (`Interfaces/IPluginManager.h:632-633`) | aucun (jamais utilisé par le projet ni pour les Mods) | établi | | A9 | Ajouts sans effet | — | `CheckForDeprecatedPlugin` `:58-64` (appel `:1929`) ; couche ini `ProjectPlugin` pour tout plugin non Engine `:1933` (5.5 : `Plugin` `:1978`) ; `UE_DISABLE_PLUGIN_DISCOVERY` = 0 `:44-46`, `:776` | aucun (mods sans `Config/`, sans `DeprecatedEngineVersion`) | établi | | A10 | `MountNewlyCreatedPlugin` / montage explicite | `:3253-3266` ; `MountExplicitlyLoadedPlugin(const FString&)` `:3268` (`IPluginManager.h:528`) | `:3294-3307` identique ; `MountExplicitlyLoadedPlugin(const FString&, ELoadingPhase::Type = Max)` `:3309` (`IPluginManager.h:556`) | aucun (compatible source). Ni l'une ni l'autre ne monte de `.pak` (`TryMountExplicitlyLoadedPluginVersion` `:3396-3600 → :3497-3720`, `grep MountPak` vide) : le repli E7 d'UA-MODS exigerait aussi `FCoreDelegates::MountPak` | établi | | A11 | Ordre au démarrage | pak : `LaunchEngineLoop.cpp:2298` puis `AppInit` `:2924` → `LoadModulesForEnabledPlugins(EarliestPossible)` `:6489` → `ConfigureEnabledPlugins` (`PluginManager.cpp:2836`) | `:2135` → `:2779` → `:6564` → `:2848` | aucun | établi | | **B** | **Montage pak `Runtime/PakFile` (`IPlatformFilePak`)** | | | | | | B1 | Délégué et point d'entrée | `TDelegate MountPak` `Core/Public/Misc/CoreDelegates.h:126` ; liaison `IPlatformFilePak.cpp:5628` ; `HandleMountPakDelegate` `:6222-6237` | même signature `:121` (+ `MountPaksEx` `:125`, inutilisé ici) ; `:5803` ; `:6509-6524` identique | aucun | établi | | B2 | Ordre de priorité | ordre explicite 0 ; `GetPakOrderFromPakFilePath` `:6200-6220` (paquets du jeu : 4) ; tri `ReadOrder` décroissant (`IPlatformFilePak.h:1948`, `IPlatformFilePak.cpp:5847`) | identiques `:6487-6507`, `IPlatformFilePak.h:1940`, `:6215` | aucun (un mod ne remplace toujours pas un fichier du jeu : 0 < 4) | établi | | B3 | Signature | `bSigned = GetPakSigningKeysDelegate().IsBound()` `:5557` | `:5723` | aucun (projet sans `DefaultCrypto.ini`, `ls Config`) | établi | | B4 | Pak + IoStore : atomicité | pak ajouté à la liste avant IoStore (`:5840-5854`) ; IoStore en échec ou `.utoc` absent = avertissement, **pak reste monté** (`:5923-5930`), retour `:6004` | `Mount(FPakMountArgs)` `:6016` : « Pak will be added to list if iostore mount also succeeds » `:6067` ; retrait si échec `:6199-6202`, ajout `:6203-6219` ; `.utoc` absent = échec par défaut (`bMountFailOnMissingUtoc = true` `:72`, `:252-263`, `:6186-6191`) ; `PakFileMountFailedDelegate` (`CoreDelegates.h:152`, absent en 5.5) | aucun sur le contrat (archive = 3 fichiers, contrôle `BuildMod.ps1:240-241`) ; **mode d'échec changé** : conteneur refusé ⇒ ni paquets ni `AssetRegistry.bin` du mod | établi | | B5 | Format `.pak` | `PakFile_Version_Latest` = 11 `Fnv64BugFix` (`IPlatformFilePak.h:149`) ; version > 11 = **Fatal** « Invalid pak file version » (`PakFile.cpp:300`) ; taille de queue identique pour 11 et 12 (`IPlatformFilePak.h:193-200`) | 12 `Utf8PakDirectory` (`IPlatformFilePak.h:175`), écrit par défaut (`:205`) ; lecture ≤ 12 (`PakFile.cpp:276`, branche `:726`) | binaire ; contrat aucun | établi (code) ; effet T5 estimé | | **C** | **`Core/Internal/IO/IoStore.h`** (pas de `Core/Public/IO/IoStore.h` dans les deux, `find`) | | | | | | C1 | Version de TOC | `EIoStoreTocVersion` `:22-35`, `Latest` = `ReplaceIoChunkHashWithIoHash` (8) ; contrôle « Outdated » / « Too new » `IoStore.cpp:1140-1147` | identique `:25-38` ; `FIoStoreTocHeader` inchangé (`diff -u` : premier écart à `:172`) ; `IoStore.cpp:1313-1320` ; ajout lecture mappée `FIoStoreTocResourceStorage/View` `:178-272` | aucun (même TOC ; la TOC ne distingue pas 5.5 de 5.8) | établi | | **D** | **`Core/Public/IO/IoContainerHeader.h`** | | | | | | D1 | Version d'en-tête de conteneur | `Latest` = 4 `SoftPackageReferences` (`:85-94`) ; lecture exige `== Latest` (`Core/Private/IO/IoContainerHeader.cpp:52`) ; sinon « Invalid container header » et en-tête **vide**, montage poursuivi (`PakFile/Private/IoDispatcherFileBackend.cpp:1018-1023`) | `Latest` = 5 `SoftPackageReferencesOffset` (`:96-107`) ; lecture accepte `>= NoExportInfo` (3) (`IoContainerHeader.cpp:60`, `:86-106`) ; message `:985` | binaire ; contrat aucun. Un conteneur 5.5 est **accepté** par 5.8 | établi | | D2 | Entrées du magasin de paquets | `ShaderMapHashes` en `FSHAHash` (20 o) `:46` | `FShaderHash` = `FXxHash64` (8 o) `:46`, `Core/Public/Hash/ShaderHash.h:11-17` ; relu comme `FShaderHash` (`CoreUObject/Private/Serialization/AsyncLoading2.cpp:5571`) | binaire ; contrat aucun | établi (types) ; effet estimé (tableau vide si `bShareMaterialShaderCode=False`, `Config/DefaultGame.ini:31`) | | **E** | **`Core/Public/UObject/ObjectVersion.h` et versions UE5** | | | | | | E1 | `EUnrealEngineObjectUE5Version` | dernière `ASSETREGISTRY_PACKAGEBUILDDEPENDENCIES` = 1013 (`:88`) | + 5 : `METADATA_SERIALIZATION_OFFSET`, `VERSE_CELLS`, `PACKAGE_SAVED_HASH`, `OS_SUB_OBJECT_SHADOW_SERIALIZATION`, `IMPORT_TYPE_HIERARCHIES` = 1018 (`:90-103`) ; `GPackageFileUE4Version` dépréciés retirés (5.5 `:870-875`) | binaire ; contrat aucun | établi | | E2 | Versions personnalisées (dernière valeur) | `FUE5MainStreamObjectVersion` 119 (`UE5MainStreamObjectVersion.h:374-378`) ; `FUE5ReleaseStreamObjectVersion` 51 (`.h:170`) ; `FFortniteMainBranchObjectVersion` 170 (`.h:531`) ; `FFortniteReleaseBranchCustomObjectVersion` 15 (`.h:61`) | listes déplacées en `.inl` : 123 (`UE5MainStreamObjectVersions.inl:381`), 68 (`UE5ReleaseStreamObjectVersions.inl:214`), 268 (`FortniteMainBranchObjectVersions.inl:818`), 20 (`FortniteReleaseBranchCustomObjectVersions.inl:70`) ; recomptage : les dernières entrées 5.5 portent 119 / 51 / 170 / 15 dans les `.inl` (`:369`, `:163`, `:524`, `:55`) | binaire ; contrat aucun | établi | | E3 | Paquets cuits sans version | `VersioningInfo` absent → version **du moteur qui charge** (`AsyncLoading2.cpp:6517-6528`) ; `EZenPackageVersion` `AsyncLoading2.h:246-255` ; `FZenPackageSummary` `:277` | identique `:8464-8475` ; `:271-280` identique ; `:302` même taille (`CookedHeaderSize` → `_Unused`) ; exemple de lecture conditionnée par une version neuve : `UObject/PropertyArray.cpp:447` | binaire ; contrat aucun. Un paquet 5.5 est relu avec le schéma 1018 : en-tête lisible, exports faussés | établi (mécanisme) ; effet incertain (T4) | | **F** | **Registre d'assets du plugin (`Runtime/AssetRegistry`)** | | | | | | F1 | Chargement du `.bin` du mod | `LoadPremadeAssetRegistry_Plugins` `AssetRegistry.cpp:938-962` : `GetEnabledPluginsWithContent()`, `GetBaseDir()/AssetRegistry.bin`, `IFileManager::FileExists` (paquets **ou** disque) | même boucle et même chemin `:633-660`, via `ActiveMountsLoader.TryLoadStateAndRegisterAssetProvider` ; ActiveMounts désactivé (`Engine/Config/BaseEngine.ini:2956` `bActiveMountsLoadingEnabled_Client=false`, journal `ActiveMountsLoader.cpp:105`) → repli `:411-424` : **paquets seulement** si la plateforme pak est active (`FindFileInPakFiles` `:414`, plateforme récupérée `AssetRegistry.cpp:635`) | aucun : notre `AssetRegistry.bin` est un fichier UFS du `.pak` (`ModSources/lpr_hair_pocolov/Saved/StagedBuilds/Windows/Manifest_UFSFiles_Win64.txt:1`, `.uplugin` en NonUFS) ; un registre livré en fichier libre ne serait plus lu | établi | | F2 | Format du `.bin` | `FAssetRegistryVersion` dernière `AssetPackageDataHasExtension` (`CoreUObject/Public/AssetRegistry/AssetData.h:103`) ; versions anciennes acceptées (`AssetRegistryState.cpp:1866-1871`) | + 7 jusqu'à `MemoryMappedTagDataStore` (`:103-109`) ; idem `:2669-2674` | binaire (recuit) ; contrat aucun | établi | | **G** | **Compléments : cuisson DLC et version de référence** | | | | | | G1 | `-dlcname -basedonreleaseversion`, `-createreleaseversion` | transmis au cuiseur `Programs/AutomationTool/Scripts/CookCommand.Automation.cs:212-214` ; `UnversionedCookedContent = true` `AutomationUtils/ProjectParams.cs:1989` ; `Releases//` `Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:253-267` ; `Metadata/DevelopmentAssetRegistry.bin` `:12582-12601` ; copie pak/utoc/ucas vers `Releases` `CopyBuildToStagingDirectory.Automation.cs:4113-4124` ; `.uplugin` DLC `:1197-1208` | `:244-246` ; `:2101` ; `:271-285` (identique, `diff`) ; `:12115-12134` ; `:5091-5105` (+ `.sig`) ; `:1650-1660` | aucun | établi | | G2 | Zen store par défaut | `bUseZenStore=False` (`Engine/Config/BaseGame.ini:93`) | `True` (`:95`) ; le projet ne le fixe pas (`grep bUseZenStore Config/DefaultGame.ini` vide, 5.5 et 5.8) | **à adapter ou à valider** (U5) : cuisson DLC et version de référence produites via Zen | incertain | | G3 | `UnrealPak -List` (contrôle `BuildMod.ps1:247`) | `"" offset: …` `Developer/IoStoreUtilities/Private/IoStoreUtilities.cpp:6581` | même format `:6761` ; `UnrealPak.exe` présent dans `E8/../Binaries/Win64` | aucun | estimé (filtre inchangé) | ## 3. Points d'appel côté jeu et addon (rien à casser) | Site | API moteur | 5.5 → 5.8 | Statut | |---|---|---|---| | `Source/LifePlay/LPModDailies.cpp:50-63` | `IPluginManager::GetEnabledPluginsWithContent`, `IPlugin::GetType/GetName`, `EPluginType::Mod`, `IAssetRegistry::GetAssetsByPath`, `FAssetData::AssetClassPath` | déclarations aux mêmes lignes (`IPluginManager.h:45, 121, 168`, `:416 → :435`) ; implémentation identique (`PluginManager.cpp:3097-3111 → :3132-3146`) | établi | | `LPModDailies.cpp:119` | `TSoftObjectPtr::LoadSynchronous` | premier point où un paquet de mod est lu (T4) | établi | | `Source/LifePlay/LPHairstyleSubsystem.cpp:484-511` | `GetAssetByObjectPath(FSoftObjectPath)` ; repli `FPackageName::DoesPackageExist(FString)` | `AssetRegistry/Public/AssetRegistry/IAssetRegistry.h:363 → :425` ; `CoreUObject/Public/Misc/PackageName.h:390 → :450` (la surcharge à `FGuid*` de 5.5 `:376` a disparu, non utilisée) | établi | | `Source/LifePlay/LPModInfoSubsystem.cpp:46, 135-143` | `UGeneralProjectSettings::ProjectVersion` | `EngineSettings/Classes/GeneralProjectSettings.h:56` (les deux) | établi | | `Plugins/ModdingExtra/.../LPDataCache.cpp:102-116` | `IFileManager` sur `Content/Modules` | hors montage de plugin ; sa rupture C2664 (`:198`) relève de `lp-ue-compat` R2 | établi | | Compilation 5.8 de l'essai UA-T5 | — | `Module.LifePlay.cpp` (contient les trois sous-systèmes : 3 occurrences dans `D:\Game\U58-essai\LifePlay\Intermediate\Build\Win64\x64\UnrealEditor\Development\LifePlay\Module.LifePlay.cpp`) compilé sans erreur (`D:\Game\U58-essai\essai-A2.log:90` ; erreurs seulement `:65-77` LPCoupleSimCore et `:215` LPDataCache) | établi (cible Editor) ; estimé pour la cible Game | | Addon `Tools/BuildMod.ps1:233` | `RunUAT BuildCookRun … -pak -iostore -dlcname -basedonreleaseversion` | options inchangées (G1) ; seul le chemin moteur `:53` change (déjà R0 d'UA-MODS) | établi | ## 4. Verdict sur R2 R2 (UA-MODS § 5) : « mécanisme de découverte / montage de `Mods/` modifié en 5.6-5.8 », P 1, I 3, statut incertain faute de source 5.8. **Verdict : écarté par le code (établi), confirmation d'exécution à faire (T-M1).** 1. Les six maillons du mécanisme sont présents en 5.8 avec la même logique : découverte (A1-A3), lecture du descripteur (A4), activation par défaut (A5), montage des paquets (A6, B1-B3), point de montage (A7), registre dans le paquet (F1). Les écarts sont des refactorisations (A6, A7), des suppressions de voies que nous n'utilisons pas (A8) ou des ajouts neutres (A2, A9). 2. Aucune API C++ appelée par le jeu ne change (§ 3) ; aucun code de jeu n'est imposé par le mécanisme. 3. Les deux changements de comportement réels (B4 atomicité pak + IoStore, F1 registre cherché dans les paquets seulement) sont satisfaits par la forme actuelle des archives (3 fichiers de conteneur, `AssetRegistry.bin` en UFS). 4. Proposition de nouveau statut pour R2 : P 1 → « résiduel », statut **établi (code) / à confirmer par T-M1 en U7**. Ce qui reste de risque sur les mods se reporte sur R1 (mod d'une autre version, § 5) et R3 (Zen store, G2). ## 5. Conséquences signalées hors R2 (estimées, à confirmer) - **Mod 5.5 dans le jeu 5.8 (T4, R1 d'UA-MODS)** : pak v11 lu (B5), TOC v8 lue (C1), en-tête de conteneur v4 accepté (D1), registre lu (F2) → lignes « Mounted IoStore container » / « Mounted Pak file » **normales**, assets inscrits ; l'échec n'arrive qu'à la désérialisation (E3) : `LPModDailies.cpp:119` ou la coiffure. Nature (erreur ou plantage) incertaine : T4. L'avertissement de version (modules cochés) reste la seule protection ; un abonnement à `PakFileMountFailedDelegate` n'aiderait pas (le conteneur n'est pas refusé, et les paquets de plugins sont montés avant le chargement des modules du jeu, A11). - **Mod 5.8 dans le jeu 5.5 (T5)** : la queue du pak se lit (même taille, B5) puis la version 12 > 11 déclenche `UE_CLOG(… Fatal, "Invalid pak file version …")` (`E5/Runtime/PakFile/Private/PakFile.cpp:300`) au montage du plugin, donc **arrêt au démarrage** du jeu 5.5. Corrige l'attendu d'UA-MODS T5 (« TOC Too new refusé ») : la TOC n'a pas changé de version (C1). Message pour le guide des moddeurs. - **Conteneur incomplet en 5.8** (`.utoc` absent ou refusé) : le mod disparaît entièrement (pas d'assets, pas de registre) au lieu d'un montage partiel en 5.5 (B4) ; côté jeu, cela donne les lignes « introuvable » déjà prévues. ## 6. Actions par lot **U3 (code)** — rien d'imposé par le mécanisme de montage. - Garder `LPModDailies`, `LPHairstyleSubsystem`, `LPModInfoSubsystem` tels quels ; preuve = build 5.8 Game et Editor sans erreur dans `Module.LifePlay*.cpp`. - Option, décision utilisateur après T4 (pas avant) : garde « ignorer les assets d'un module dont `MODULE_GAME_VERSION` ≠ `ProjectVersion` » (UA-MODS R1). Ne pas s'appuyer sur `PakFileMountFailedDelegate` (§ 5). **U5 (cuisson)** - Trancher G2 : vérifier qu'un build Shipping 5.8 `-pak -iostore -createreleaseversion=` produit `Releases//Windows/AssetRegistry.bin`, `Metadata/DevelopmentAssetRegistry.bin` et les `.pak/.utoc/.ucas` copiés (G1) avec `bUseZenStore` hérité (`True`) ; sinon proposer `bUseZenStore=False` dans `Config/DefaultGame.ini` (décision). - Contrôler la version écrite des paquets du jeu (v12) n'a pas d'effet : rien à faire. **U7 (recuisson)** - Recuire les 3 mods (obligatoire : B5, D1, E1-E3), même commande `BuildMod.ps1:233` contre `Releases/2026.10.2.0`. - Contrôle de sortie à ajouter à la liste de vérification (proposé, non appliqué) : `Manifest_UFSFiles_Win64.txt` du staging contient `LifePlay/Mods//AssetRegistry.bin` (F1 : seul emplacement lu en 5.8) et l'archive contient les 3 fichiers de conteneur (B4). - `UnrealPak -List` : relire une fois la sortie brute 5.8 (G3). - Guide moddeurs et README : « supprimer l'ancienne version du mod avant d'installer » ; un mod 5.8 fait planter le jeu 5.5 au démarrage (§ 5, après T5). ## 7. Tests pour prouver le montage en 5.8 (build empaqueté Development, puis Shipping) Lignes attendues dans `Windows/LifePlay/Saved/Logs/LifePlay.log` (formats lus dans `E8` et le jeu). | Test | Procédure | Lignes attendues (source) | Lignes interdites | |---|---|---|---| | T-M1 montage nominal (par mod, ×3) | archives recuites 5.8 installées ; démarrer ; écran titre puis nouvelle partie | `LogPluginManager: Mounting Mod plugin ` (`PluginManager.cpp:1926`) ; `LogPakFile: Display: Mounted IoStore container "…/Mods//Content/Paks/Windows/LifePlay-Windows.utoc"` (`IPlatformFilePak.cpp:6175`) ; `LogPakFile: Display: Mounted Pak file '…/LifePlay-Windows.pak', mount point: '…/Mods//'` (`:6235`) ; une fois : `LogAssetRegistry: ActiveMountsLoading is disabled.` (`ActiveMountsLoader.cpp:105`) | `Failed to load Plugin (` (`PluginManager.cpp:1113`) ; `Failed to mount IoStore container` (`IPlatformFilePak.cpp:6180`) ; `IoStore container "…" not found` (`:6189`) ; `Invalid container header` (`IoDispatcherFileBackend.cpp:985`) ; `is not mounted to a valid Root Path yet` | | T-M2 registre lu dans le paquet | même session | `Modules : lpr_hair_pocolov actif par defaut (MODULE_DEFAULT_ENABLED)…` (`LPHairstyleSubsystem.cpp:402`) ; `Coiffures : … modules : 12 coiffure(s) …` (`:249`) et `… 12 ajoutee(s) par les modules …` (`:533`) ; `LPModDailies : lpr_anim_quaternius, N clip(s) sous /lpr_anim_quaternius/Anims` et idem `lpr_anim_freeanims` (`LPModDailies.cpp:79`) ; `Modules : N .lpmod lu(s), 3 avec MODULE_GAME_VERSION (jeu 2026.10.2.0)` (`LPModInfoSubsystem.cpp:73`, N = relevé de référence 5.5 + 3) | `absent du registre d'assets mais paquet present` (`LPHairstyleSubsystem.cpp:504` : registre non lu) ; `introuvable` (`:508`, `LPModDailies.cpp:125`) ; `construit pour LifePlay` (`LPModInfoSubsystem.cpp:143`) | | T-M3 conteneur incomplet (information, copie jetable) | retirer le `.utoc` d'un mod dans une copie du build | `IoStore container "…utoc" not found` (`:6189`) ; pas de `Mounted Pak file` pour ce mod ; coiffures ou clips de ce mod absents | plantage | | T4 mod 5.5 dans le jeu 5.8 | archive `…-for-LifePlay-2026.10.1.6` installée | montage **normal** attendu (lignes T-M1) ; puis observation au chargement (`LPModDailies.cpp:119`) : erreur ou plantage, `Saved/Crashes` | — (résultat à relever) | | T5 mod 5.8 dans le jeu 5.5 | archive recuite dans une copie de `LifePlay_Build_5.5_DC4` | arrêt fatal `Invalid pak file version (12) in '…'` (`E5/.../PakFile.cpp:300`) | — (résultat à relever) | T-M1 et T-M2 suffisent à passer R2 en « établi ». T4/T5 informent R1 et le guide, pas R2. ## 8. Limites et incertitudes - Lecture de code seulement : aucune exécution 5.8 ; la cible Game 5.8 n'a pas encore été compilée (essai = Editor). - G2 (Zen store × DLC × version de référence) : non tranché par le code lu (incertain ; U5). - Effets exacts de E3 et D2 sur un paquet 5.5 (erreur ou plantage) : incertains (T4). - T5 « Fatal » : estimé (la macro Fatal arrête le processus ; non essayé en Shipping). - Notes de version officielles 5.6-5.8 non relues ici (non nécessaires : la conclusion repose sur le code installé). ## 9. Commandes de reproduction (Git Bash, lecture seule) ```bash E5=D:/Game/Launcher/Engine/UE_5.5/Engine/Source; E8=D:/Game/Launcher/Engine/UE_5.8/Engine/Source diff -rq "$E5/Runtime/Projects" "$E8/Runtime/Projects" diff -u "$E5/Runtime/Projects/Private/PluginManager.cpp" "$E8/Runtime/Projects/Private/PluginManager.cpp" | wc -l # 2345 diff -u "$E5/Runtime/Core/Public/UObject/ObjectVersion.h" "$E8/Runtime/Core/Public/UObject/ObjectVersion.h" diff -u "$E5/Runtime/Core/Internal/IO/IoStore.h" "$E8/Runtime/Core/Internal/IO/IoStore.h" diff -u "$E5/Runtime/Core/Public/IO/IoContainerHeader.h" "$E8/Runtime/Core/Public/IO/IoContainerHeader.h" grep -n "PakFile_Version_" "$E5/Runtime/PakFile/Public/IPlatformFilePak.h" "$E8/Runtime/PakFile/Public/IPlatformFilePak.h" grep -n "FindFileInPakFiles\|ActiveMountsLoading is disabled" "$E8/Runtime/AssetRegistry/Private/ActiveMountsLoader.cpp" grep -n "bUseZenStore" D:/Game/Launcher/Engine/UE_5.5/Engine/Config/BaseGame.ini D:/Game/Launcher/Engine/UE_5.8/Engine/Config/BaseGame.ini grep -n "AssetRegistry" "D:/Game/LifePlay-Sandbox/ModSources/lpr_hair_pocolov/Saved/StagedBuilds/Windows/Manifest_UFSFiles_Win64.txt" ```