# LifePlay 5.5 — Architecture du projet et devenir du VictoryPlugin > Document généré le 2026-09-08 par analyse statique de `D:\Game\LifePlay-master 5.5`, > des journaux de `Saved/Logs`, de `output.txt` et du journal AutomationTool de la dernière > chaîne cook/package. > Pendant : `LifePlay-master 4.27/Docs/Architecture/VictoryPlugin_Architecture.md`. > Portée : architecture globale du projet 5.5, dissection du remplacement du `VictoryBPLibrary`, > état réel de la chaîne de build, **points de remédiation** (§9) et **compte rendu de leur > exécution** (§10). > > Mis à jour le 2026-09-08 après la campagne R-01 à R-11. --- ## 0. Ce qui a changé depuis le document 4.27 — en une page | Sujet | 4.27 | 5.5 | |---|---|---| | `Plugins/VictoryPlugin` | présent, 9 327 lignes, 17 fichiers | **supprimé** | | Dépendance `ApexDestruction` | obligatoire (`.uplugin`) | **disparue** | | PhysX / APEX / `PhysXSupport.h` | inclus par le plugin | **aucune occurrence dans l'arbre** | | Nœuds Victory consommés par le jeu | 2 (sur ~330 exposés) | 2 — **réimplémentés dans le module `LifePlay`** | | Porteur des 2 nœuds | `UVictoryBPFunctionLibrary` | `ULPVictoryCompat` (128 lignes) | | Raccordement des Blueprints | — | `[CoreRedirects]` de `Config/DefaultEngine.ini` | | Outillage éditeur | 1 commandlet | **6 commandlets** — voir §1.2 | | État de la chaîne | portage en cours | **cook + package + archive OK**, et depuis la campagne §10 : **0 erreur, 0 avertissement** | **Le levier de simplification identifié au §6.2 du document 4.27 a été appliqué.** Le plugin généraliste de 9 327 lignes a été remplacé par 128 lignes dans le module du projet, soit **1,4 % du volume d'origine**, et tous les points bloquants 🔴 du tableau §7.2 de ce document ont disparu. --- ## 1. Vue d'ensemble du projet | Élément | Valeur | |---|---| | Nom / version | LifePlay 2026.9 beta — portage UE 5.5 | | `EngineAssociation` | `5.5` (moteur installé : 5.5.4-40574608) | | `DefaultBuildSettings` | `BuildSettingsVersion.V5` | | `IncludeOrderVersion` | `EngineIncludeOrderVersion.Unreal5_5` | | Plateformes cibles | `WindowsNoEditor` (Win64) | | Modules C++ du projet | `LifePlay` (Runtime, Default) · `LifePlayEditorTools` (Editor, Default) | | Plugins locaux | `ModdingExtra` · `StreetMap` | | Entrées `.uproject` désactivées | aucune (`ModdingPlus` et `MultiTask` retirés le 2026-09-08, R-08) | | Content | 8 562 `.uasset` + 1 `.umap`, ≈ 6,5 Go | | C++ projet | **1 900 lignes** sur 28 fichiers (dont `.Build.cs` / `.Target.cs`) | Le profil du projet n'a pas changé : **la logique de jeu vit dans les Blueprints** (`Content/BPs/GI.uasset` = 51,9 Mo à lui seul, contre 47,8 Mo en 4.27) et dans un **DSL texte de modding**. Le C++ n'est qu'une couche d'adaptation. ### 1.1 Répartition du contenu de gameplay `Content/Modules/` contient **16 modules** (`vin_Base` + 15 modules thématiques), plus des tables texte à la racine (`Clothes4.txt`, `outfits_*.txt`, `names_*.txt`, `uniforms.txt`…). Le contenu y est du **texte interprété à l'exécution**, pas des assets : | Extension | Nombre | Rôle | |---|---:|---| | `.lpscene` | 1 271 | scènes / dialogues avec choix | | `.lpaction` | 346 | actions contextuelles | | `.lpcharacter` | 141 | presets de personnages | | `.lpworld` | 110 | lieux, bâtiments, `WHERE` | | `.lpstat` | 82 | statistiques d'acteur | | `.lpai` | 17 | comportements PNJ | | `.lpmod` | 16 | manifestes de module | | `.lpquest` | 8 | quêtes | | `.lptalk` | 6 | dirty talk | | `.lpdesc` | 3 | descriptions de sexe | Ces fichiers ne sont pas cuits : `DefaultGame.ini` les stage tels quels via `+DirectoriesToAlwaysStageAsNonUFS=(Path="Modules")`. ### 1.2 Modules C++ du projet **`LifePlay`** (Runtime, ~330 lignes) — dépendances publiques : `Core, CoreUObject, Engine, InputCore, AssetRegistry, NavigationSystem` ; dépendances privées : `ImageWrapper, ApplicationCore`. Les trois dernières ont été ajoutées par le portage 5.5. | Classe | Fichier | Rôle | |---|---|---| | `ALifePlayGameModeBase : AGameModeBase` | `LifePlayGameModeBase.h/.cpp` | coquille vide | | `ULPAssetRegistryHelpers : UBlueprintFunctionLibrary` | `LPAssetRegistryHelpers.h/.cpp` | rustine héritée du portage 4.27 : ré-expose `GetAssetByObjectPath` en `BlueprintPure` ; en 5.5 elle absorbe en plus la dépréciation de la surcharge `FName` en convertissant vers `FSoftObjectPath` | | `ULPVictoryCompat : UBlueprintFunctionLibrary` | `LPVictoryCompat.h/.cpp` | **remplacement du VictoryPlugin** — voir §2 | | `ULPNavigationHelpers : UBlueprintFunctionLibrary` | `LPNavigationHelpers.h/.cpp` | re-expose `K2_GetRandomLocationInNavigableRadius` en `BlueprintPure` — voir §10.3 | Le module a une **structure plate** (pas de sous-dossier `Public/`), d'où le `PublicIncludePaths.Add(ModuleDirectory)` explicite : `BuildSettingsVersion.V5` coupe les chemins d'include hérités, et `LifePlayEditorTools` inclut `LPAssetRegistryHelpers.h`. **`LifePlayEditorTools`** (Editor, ~1 550 lignes) — dépendances : `UnrealEd, BlueprintGraph, KismetCompiler, AssetRegistry, StreetMapRuntime, SlateCore, NavigationSystem, UMG, UMGEditor`. **Six commandlets** d'outillage de portage, toutes bâties sur le même patron (parcours de l'AssetRegistry, rapport `-DryRun`, correction, recompilation, resauvegarde) : | Commandlet | Point | Objet | |---|---|---| | `LPFixAssetRegistryNodes` | — | réécrit les nœuds `GetAssetByObjectPath` vers `ULPAssetRegistryHelpers` | | `LPFixEditableTextBoxFont` | — | rebranche la broche `Font` disparue de `FEditableTextBoxStyle` vers `TextStyle` | | `LPCheckStreetMap` | R-11 | charge les 280 `UStreetMap` et compte routes / nœuds / bâtiments / eaux / parcs / amenities, sortie CSV | | `LPFixDeprecatedNodes` | R-03, R-04 | `SkeletalMesh` → `GetSkeletalMeshAsset`, `GetRandomPointInNavigableRadius` → enrobage pur | | `LPFixOrphanBoundEvents` | R-05 | supprime les événements de composant dont le widget n'existe plus | | `LPFixZeroScaleActors` | R-06 | signale et corrige les composantes d'échelle nulles dans les cartes | ### 1.3 Schéma de dépendances 5.5 ```mermaid graph TD subgraph Projet["Projet LifePlay (UE 5.5)"] LP["LifePlay
Runtime · 251 l."] LPET["LifePlayEditorTools
Editor · 791 l."] BP["Content/BPs + UI
(Blueprints)"] MODS["Content/Modules
(DSL .lpscene/.lpaction/…)"] end subgraph Compat["Couche de compatibilité"] VC["ULPVictoryCompat
2 nœuds · 128 l."] AR2["ULPAssetRegistryHelpers
1 nœud pur"] CR["[CoreRedirects]
DefaultEngine.ini"] end subgraph Plugins["Plugins locaux"] MEX["ModdingExtra
Runtime · PreLoadingScreen · 7 nœuds"] SMR["StreetMapRuntime
Runtime (fork Vinfamy)"] SMI["StreetMapImporting
Editor"] end subgraph Engine["Modules moteur"] CORE["Core / CoreUObject / Engine"] AR["AssetRegistry"] IW["ImageWrapper"] APP["ApplicationCore"] IN["InputCore"] SL["Slate / SlateCore"] RHI["RHI / RenderCore"] NAV["NavigationSystem"] UED["UnrealEd / BlueprintGraph / KismetCompiler"] XML["XmlParser / RawMesh / AssetTools"] end LP --> VC LP --> AR2 LPET --> LP LPET --> SMR LPET --> UED BP --> LP BP --> MEX BP --> SMR CR -.réécrit les imports.-> BP MODS -.interprétés par.-> BP LP --> CORE LP --> AR LP --> IN VC --> IW VC --> APP AR2 --> AR MEX --> CORE MEX --> SL SMR --> CORE SMR --> RHI SMR --> NAV SMI --> SMR SMI --> XML SMI --> UED ``` À comparer au schéma 4.27 : **PhysX, APEX, ApexDestruction, HeadMountedDisplay, Vorbis, AIModule, HTTP et DeveloperSettings ont disparu du graphe de dépendances**, tous tirés par le seul VictoryPlugin. --- ## 2. Le VictoryPlugin en 5.5 — carte d'identité de son remplaçant Le plugin `VictoryBPLibrary` n'existe plus dans l'arbre 5.5. Aucun fichier `*ictory*` ne subsiste hors des artefacts de build de `ULPVictoryCompat` (`Intermediate/…/UHT/`), et aucune copie parasite ne traîne sous `Engine/Source` (le piège documenté au §7.1 du document 4.27). | Champ | Valeur | |---|---| | Chemin | `Source/LifePlay/LPVictoryCompat.{h,cpp}` | | Classe | `ULPVictoryCompat : UBlueprintFunctionLibrary`, `LIFEPLAY_API` | | Volume | **128 lignes** (48 en-tête + 80 implémentation) | | Nœuds exposés | **2** (1 `BlueprintPure`, 1 `BlueprintCallable`) | | Enum exposé | `EJoyImageFormats` (JPG, PNG, BMP, ICO, EXR, ICNS) | | Dépendances ajoutées | `ImageWrapper`, `ApplicationCore` (privées) | | Chargement | module `LifePlay`, `LoadingPhase: Default` (contre `PreDefault` pour le plugin d'origine) | ### 2.1 Les deux nœuds conservés ```cpp // BlueprintPure — Category "Victory BP Library|Load Texture From File" static UTexture2D* Victory_LoadTexture2D_FromFile( const FString& FullFilePath, EJoyImageFormats ImageFormat, bool& IsValid, int32& Width, int32& Height); // BlueprintCallable — Category "Victory BP Library|String" static void Victory_SaveStringToOSClipboard(const FString& ToClipboard); ``` Noms, signatures, catégories, `meta=(Keywords=…)` et **ordre des membres de l'enum** sont reproduits à l'identique : l'ordre de `EJoyImageFormats` est sérialisé en octet dans les valeurs par défaut des broches Blueprint, toute permutation corromprait les graphes existants. ### 2.2 Adaptations UE5 dans l'implémentation | Point 4.27 | Traitement 5.5 | |---|---| | `Texture->PlatformData->Mips[0]` | `PlatformData` est privé depuis 5.1 → `GetPlatformData()->Mips[0]` | | `EImageFormat` | conversion explicite via un `switch` local `GetJoyImageFormat()` | | `FPlatformApplicationMisc::ClipboardCopy` | inchangé, module `ApplicationCore` | | `DDSLoader.h`, `PhysXIncludes.h`, `SCOPED_SCENE_WRITE_LOCK` | **non repris** — les fonctions qui les utilisaient ne sont pas consommées par le jeu | Le contrat de sortie `IsValid` a été **volontairement laissé bogué à l'identique** : il ne vaut `false` que si le fichier est introuvable, et `true` même quand l'image est illisible et que le retour est nul. Le commentaire du `.cpp` justifie ce choix : les Blueprints existants branchent sur ce drapeau, en changer la sémantique changerait leur comportement. ### 2.3 Le raccordement — `[CoreRedirects]` Aucun asset n'a été réécrit nœud par nœud pour le Victory : le raccordement est déclaratif, dans `Config/DefaultEngine.ini`. ```ini [CoreRedirects] +PackageRedirects=(OldName="/Script/VictoryBPLibrary",NewName="/Script/LifePlay") +ClassRedirects=(OldName="/Script/VictoryBPLibrary.VictoryBPFunctionLibrary",NewName="/Script/LifePlay.LPVictoryCompat") +EnumRedirects=(OldName="/Script/VictoryBPLibrary.EJoyImageFormats",NewName="/Script/LifePlay.EJoyImageFormats") ``` Les trois lignes sont nécessaires et non redondantes : - `ClassRedirects` / `EnumRedirects` réaiguillent les références d'objets ; - `PackageRedirects` évite l'erreur de linker *« Failed to find script package for import object »* à chaque chargement, le package `/Script/VictoryBPLibrary` n'existant plus. Comme les 8 563 assets ont ensuite été **resauvegardés en place** (voir §7.2), les références sont aujourd'hui résolues en dur vers `/Script/LifePlay.LPVictoryCompat` — vérifié par recherche binaire : `VictoryBPFunctionLibrary` n'apparaît plus dans aucun asset, et `LPVictoryCompat` apparaît dans exactement 5. ```mermaid sequenceDiagram autonumber participant PKG as GI.uasset (import) participant CR as CoreRedirects participant LP as /Script/LifePlay participant VC as ULPVictoryCompat Note over PKG: avant resave — import = /Script/VictoryBPLibrary.VictoryBPFunctionLibrary PKG->>CR: résolution de l'import CR->>LP: PackageRedirects (package) CR->>VC: ClassRedirects (classe) + EnumRedirects (EJoyImageFormats) VC-->>PKG: nœud rebranché, graphe compilable Note over PKG: après resave — import écrit en dur = /Script/LifePlay.LPVictoryCompat ``` ⚠️ Les redirections doivent **rester en place** malgré le resave : les sauvegardes joueur (`Content/Saves/`) et les paquets de mods tiers antérieurs peuvent encore porter l'ancien chemin. --- ## 3. Schéma relationnel des types exposés ```mermaid classDiagram direction LR class UBlueprintFunctionLibrary class UCommandlet class UObject class UActorComponent class ULPVictoryCompat { +Victory_LoadTexture2D_FromFile() BlueprintPure +Victory_SaveStringToOSClipboard() BlueprintCallable } class ULPAssetRegistryHelpers { +GetAssetByObjectPath(FName, bool) BlueprintPure } class UModdingExtraBPLibrary { +7 UFUNCTION GetAllFilesFromFolder / LoadTxt / SaveTxt ContentDirectory / GetAllSubfolders IsPointInsidePolygon / SampleFunction } class UStreetMap { +FindBuilding() / FindRoad() +FindBuildingFromArray() +SearchByBuildingName() +SearchByBuildingNameFromArray() +SearchByAmenity() -FilterByAmenity() ~non UFUNCTION~ } class UStreetMapComponent class ULPFixAssetRegistryNodesCommandlet class ULPFixEditableTextBoxFontCommandlet class ULPCheckStreetMapCommandlet class EJoyImageFormats { <> JPG PNG BMP ICO EXR ICNS } class FStreetMapBuilding { FString BuildingName FString Amenity FString Building TArray~FVector2D~ BuildingPoints FVector2D BoundsMin = ZeroVector FVector2D BoundsMax = ZeroVector } class FStreetMapWater { FString WaterName TArray~FVector2D~ WaterPoints FVector2D BoundsMin ⚠ non initialise FVector2D BoundsMax ⚠ non initialise } class FStreetMapPark { FString ParkName TArray~FVector2D~ ParkPoints FVector2D BoundsMin ⚠ non initialise FVector2D BoundsMax ⚠ non initialise } UBlueprintFunctionLibrary <|-- ULPVictoryCompat UBlueprintFunctionLibrary <|-- ULPAssetRegistryHelpers UBlueprintFunctionLibrary <|-- UModdingExtraBPLibrary UObject <|-- UStreetMap UActorComponent <|-- UStreetMapComponent UCommandlet <|-- ULPFixAssetRegistryNodesCommandlet UCommandlet <|-- ULPFixEditableTextBoxFontCommandlet UCommandlet <|-- ULPCheckStreetMapCommandlet ULPVictoryCompat ..> EJoyImageFormats UStreetMap *-- FStreetMapBuilding UStreetMap *-- FStreetMapWater UStreetMap *-- FStreetMapPark ULPCheckStreetMapCommandlet ..> UStreetMap : charge les 280 villes ULPFixAssetRegistryNodesCommandlet ..> ULPAssetRegistryHelpers : rebranche les noeuds ``` ### 3.1 Ce qui a été abandonné avec le plugin Les 268 autres fonctions statiques, `UTKMathFunctionLibrary` (32 nœuds), `UVictoryTMapComp` (28 nœuds, obsolète depuis UE 4.15), `AVictoryPC`, `AVictoryISM`, `UVictoryBPHTML` (classe entièrement commentée) et `URamaVictoryPluginCreateProcessPipe` n'ont **pas** été portés. L'analyse 4.27 avait établi qu'aucun n'était référencé dans le contenu du jeu ; la vérification a été refaite sur l'arbre 5.5 avant suppression, avec le même résultat. Les énumérations `EJoyGraphicsFullScreen` et `EVictoryHMDDevice` (cette dernière annotée *« REMOVE THIS AFTER A FEW VERSIONS »* dans le code d'origine) sont parties avec elles. --- ## 4. Cartographie fonctionnelle et usage réel ### 4.1 Les deux nœuds, asset par asset Recherche binaire sur `Content/{BPs,UI,Structs,Scenes,Modules}` : | Asset | `Victory_LoadTexture2D_FromFile` | `Victory_SaveStringToOSClipboard` | `EJoyImageFormats` | |---|:-:|:-:|:-:| | `BPs/GI` | 5 | 1 | 1 | | `UI/ExtImg` | 5 | — | 1 | | `UI/FaceTexture` | 1 | — | 1 | | `UI/MainMenu` | 1 | — | 1 | | `UI/Inventory` | — | 1 | — | **5 assets, 2 fonctions.** Identique au relevé 4.27 : aucune régression, aucune nouvelle dépendance introduite par la migration. ```mermaid graph LR GI["BPs/GI
Game Instance"] EXT["UI/ExtImg"] FACE["UI/FaceTexture"] MENU["UI/MainMenu"] INV["UI/Inventory"] LOAD["Victory_LoadTexture2D_FromFile
UTexture2D depuis un fichier disque"] CLIP["Victory_SaveStringToOSClipboard
copie presse-papiers OS"] IW["ImageWrapper
(module moteur)"] APPC["ApplicationCore
FPlatformApplicationMisc"] GI --> LOAD EXT --> LOAD FACE --> LOAD MENU --> LOAD GI --> CLIP INV --> CLIP LOAD --> IW CLIP --> APPC ``` ### 4.2 Chaîne d'appel de `Victory_LoadTexture2D_FromFile` en 5.5 ```mermaid sequenceDiagram participant BP as Blueprint (GI / UI) participant V as ULPVictoryCompat participant IWM as IImageWrapperModule participant FS as Disque participant T as UTexture2D BP->>V: Victory_LoadTexture2D_FromFile(path, EJoyImageFormats) V->>IWM: LoadModuleChecked("ImageWrapper") V->>IWM: CreateImageWrapper(GetJoyImageFormat(...)) V->>FS: FFileHelper::LoadFileToArray() alt fichier introuvable V-->>BP: nullptr, IsValid = false else V->>IWM: SetCompressed() puis GetRaw(BGRA, 8) V->>T: CreateTransient(W, H, PF_B8G8R8A8) V->>T: GetPlatformData()->Mips[0].BulkData.Lock / Memcpy / Unlock V->>T: UpdateResource() V-->>BP: UTexture2D* + IsValid = true (même si nul — cf. §2.2) end ``` `Victory_SaveStringToOSClipboard` reste une ligne : `FPlatformApplicationMisc::ClipboardCopy(*ToClipboard)`. ### 4.3 Les autres bibliothèques Blueprint réellement consommées | Bibliothèque | Assets référençants | Nœuds | |---|---|---:| | `ULPVictoryCompat` | `GI`, `ExtImg`, `FaceTexture`, `MainMenu`, `Inventory` | 2 | | `ULPAssetRegistryHelpers` | `GI`, `Person`, `Room`, `VisualMorph` | 1 | | `UModdingExtraBPLibrary` | `GI`, `Room`, `BodyShapeMenu`, `Builder`, `CharGen`, `CityMenu`, `Contact`, `ContactMenu`, `Inventory`, `MainMenu`, `ModManager`, `StatMenu` | 7 | | `UStreetMap` (fork Vinfamy) | `GI`, `StreetMap_Static`, `Person`, `Room`, `Birdview`, `MapMarkers`, `PC`, `Save`, + 12 widgets UI | 6 | --- ## 5. Le voisinage : StreetMap et ModdingExtra ### 5.1 `StreetMap` — fork custom, seul C++ tiers restant `Plugins/StreetMap` est un **fork Vinfamy** du StreetMap de Mike Fricker, 4 900 lignes sur 2 modules (`StreetMapRuntime`, `StreetMapImporting`). **Ne jamais le remplacer par un fork public.** Les ajouts propres à LifePlay : - `FString Amenity` et `FString Building` sur `FStreetMapBuilding` ; - structs `FStreetMapWater` (`natural = water`) et `FStreetMapPark` (`leisure = park`) ; - 6 `UFUNCTION` de recherche : `FindBuilding`, `FindRoad`, `FindBuildingFromArray`, `SearchByBuildingName`, `SearchByBuildingNameFromArray`, `SearchByAmenity` (+ le helper interne non exposé `FilterByAmenity`). `Amenity` est le mécanisme d'identification des bars, salles de sport et commerces : **748 occurrences** dans `Content/BPs` + `Content/UI`, concentrées dans `GI` (265), `StreetMap_Static` (212), `Action` (64), `Person` (46), `TopRight` (38), `Birdview` (26), `Room` (26). Le projet embarque **280 assets `UStreetMap`** dans `Content/Heavy/StreetMap/` (une par ville). La commandlet `LPCheckStreetMap` existe précisément pour prouver que la migration n'a rien perdu sur ces 280 villes — **elle n'a jamais été exécutée** (voir §9, R-11). ### 5.2 `ModdingExtra` Plugin runtime `PreLoadingScreen`, 189 lignes, 7 nœuds Blueprint : I/O texte (`LoadTxt`, `SaveTxt`, `GetAllFilesFromFolder`, `GetAllSubfolders`, `ContentDirectory`), géométrie (`IsPointInsidePolygon`) et une fonction d'exemple jamais retirée (`ModdingExtraSampleFunction`). C'est le module qui alimente le lecteur du DSL de modding. Aucune adaptation UE5 n'a été nécessaire. --- ## 6. Configuration : ce que le portage a touché | Fichier | État | |---|---| | `LifePlay.uproject` | `EngineAssociation: 5.5`, plugins Victory / SteamVR / VisualStudioTools retirés | | `LifePlay.Target.cs` / `LifePlayEditor.Target.cs` | `BuildSettingsVersion.V5` + `EngineIncludeOrderVersion.Unreal5_5` | | `Config/DefaultEngine.ini` | section `[CoreRedirects]` ajoutée (§2.3) ; 4 clés PhysX mortes retirées le 2026-09-08 (R-08) | | `Config/DefaultInput.ini` | **inchangé — 55 `ActionMappings` + 13 `AxisMappings` en système d'entrée hérité** (R-07, non traité, §10.5) | | `Config/DefaultGame.ini` | `Description` et `StagingDirectory` remis à jour le 2026-09-08 (R-08) | --- ## 7. État réel de la chaîne de build > Cette section décrit l'état **avant** la campagne de remédiation du 2026-09-08. Les > chiffres après correction sont au §10 ; le rappel ci-dessous sert de point de comparaison. ### 7.1 Résultat de la dernière chaîne complète (2026-09-07) | Étape | Résultat | |---|---| | Compilation C++ | OK — **1 seul avertissement** (`C4996` sur `StreetMap.cpp:28`) — corrigé depuis (R-01) | | Cook | `Success - 0 error(s), 99 warning(s)` — **passé à 0 avertissement depuis** (§10) | | Package + IoStore | OK | | Stage | `Saved/StagedBuilds/Windows` — 3,3 Go en fichiers nus (`UsePakFile=False`) | | Archive | `D:\Game\LifePlay_Build_5.5\Windows` | | UAT | **`BUILD SUCCESSFUL`**, `ExitCode=0`, 4 min 10 s | ### 7.2 Historique de la migration du contenu - **8 563 assets** (`.uasset` + `.umap`) ont été **resauvegardés en place** au format UE5 (UE Version 516 → 1013). Contrôle : aucun fichier de `Content/` n'a de date antérieure au resave. Deux crashes du `ResavePackages` sont survenus en cours de route sur `Content/Heavy/New2/Furniture/fnt_new100` (`Assertion failed: IsUnlocked()`, BulkData.cpp) et `fnt_new111` (`Array index out of bounds: 0 into an array of size 0`, StaticMeshDescription) — **le lot a été repris et achevé** : les 343 assets `fnt_*` portent tous la date du passage final. - Un cook antérieur (`output.txt`, 21:01) échouait sur **6 erreurs Blueprint** : broche `Font` orpheline sur `Make`/`Break Editable Text Box Style` dans `UI/CharGen` (3) et `UI/StatMenu` (3). La commandlet `LPFixEditableTextBoxFont` a été écrite pour ça et a traité **6 nœuds sur 2 Blueprints, 0 liaison non gérée, 0 échec de sauvegarde**. Le cook suivant passe à 0 erreur. ### 7.3 Les 99 avertissements du cook du 2026-09-07 — tous traités depuis | Occurrences | Avertissement | Assets | |---:|---|---| | 53 × 2 | `Get SkeletalMesh` déprécié → `GetSkeletalMeshAsset()` / `GetSkinnedAsset()` | `Person` (74*), `GI` (41*), `CharGen` (11*), `Inventory` (8*), `Hairstyle` (8*), `Inventory_Cloth` (5*), `CharGenSlider` (5*) | | 6 | `GetRandomPointInNavigableRadius` déprécié → `GetRandomLocationInNavigableRadius` | `Room`, `Person`, `AI` | | 2 | `On Clicked (StatButtonL)` sans composant correspondant | `UI/TopRight` | | 2 | `On Clicked (ButtonPreviewErect)` sans composant correspondant | `UI/CharGen` | | 2 | `On Clicked (ButtonEyelashColor)` sans composant correspondant | `UI/CharGen` | | 1 | échelle nulle sur `CentralLondon:PersistentLevel.Wall` (X = 0,000) | `Scenes/CentralLondon` | \* comptages relevés sur le cook complet de `output.txt` ; le cook du 2026-09-07 n'en réémettait qu'une partie, les Blueprints déjà compilés en cache n'étant pas recompilés. Le balayage exhaustif du 2026-09-08 a trouvé **56** nœuds `SkeletalMesh` (et non 53 : `Cursor` et deux autres graphes n'étaient pas recompilés lors de ce cook) et **6** nœuds de navigation. Tous ont été corrigés — §10.1. ### 7.4 Erreurs hors cook du 2026-09-07 — corrigées depuis (R-02) Au démarrage de l'éditeur, à chaque session (relevé dans `Saved/Logs/LifePlay.log`) : ``` LogClass: Error: StructProperty FStreetMapWater::BoundsMin is not initialized properly. LogClass: Error: StructProperty FStreetMapWater::BoundsMax is not initialized properly. LogClass: Error: StructProperty FStreetMapPark::BoundsMin is not initialized properly. LogClass: Error: StructProperty FStreetMapPark::BoundsMax is not initialized properly. ``` Elles ne bloquaient ni le cook ni le package, mais elles polluaient chaque journal et étaient remontées en `LogAutomationTest: Error`, ce qui **faisait échouer toute automatisation** traitant le journal de démarrage comme critère de succès. Les quatre initialiseurs manquants ont été ajoutés le 2026-09-08 : plus aucune occurrence dans les journaux depuis. --- ## 8. Comparatif de dette technique 4.27 → 5.5 | Point 4.27 (§7.2) | Gravité 4.27 | État 5.5 | |---|:-:|---| | PhysX / APEX / `PhysXSupport.h` | 🔴 | ✅ **résolu** — plus aucune occurrence | | Plugin `ApexDestruction` obligatoire | 🔴 | ✅ **résolu** — dépendance supprimée | | `UDestructibleComponent` | 🔴 | ✅ **résolu** — fonction non portée | | Include de `Private/` moteur | 🟠 | ✅ **résolu** | | `Texture->PlatformData` direct | 🟠 | ✅ **résolu** — `GetPlatformData()` | | `DDSLoader.h` | 🟠 | ✅ **résolu** — fonction non portée | | `EVictoryHMDDevice` | 🟡 | ✅ **résolu** — enum non porté | | `UVictoryBPHTML` (code mort) | 🟡 | ✅ **résolu** — classe non portée | | `UVictoryTMapComp` (obsolète) | 🟡 | ✅ **résolu** — composant non porté | | `bEnforceIWYU = false` | 🟡 | ✅ **résolu** — le module `LifePlay` est IWYU-propre | | Copie parasite sous `Engine/Source` | ⚑ | ✅ **résolu** — vérifié absent | | Fork custom StreetMap à préserver | ⚑ | ⚠️ **toujours vrai** — voir §5.1 | | — | — | 🆕 `GetAssetRegistryTags` déprécié (R-01) — ✅ corrigé le 2026-09-08 | | — | — | 🆕 4 erreurs d'init de struct StreetMap (R-02) — ✅ corrigé le 2026-09-08 | | — | — | 🆕 99 avertissements Blueprint (R-03 à R-06) — ✅ corrigés le 2026-09-08 | | — | — | 🆕 système d'entrée hérité (R-07) — ⏸️ **non traité**, voir §10.5 | --- ## 9. ⚑ Points de remédiation Classés par gravité. Chaque entrée est actionnable ; les effets constatés sont sourcés sur les journaux du 2026-09-07. > **État d'avancement : R-01 à R-06 et R-08 à R-11 sont clos depuis le 2026-09-08.** > R-07 ne l'est pas. Le compte rendu d'exécution, les choix de conception retenus et les > corrections apportées à ce diagnostic sont au **§10**. Cette section est conservée telle > qu'elle a été rédigée, comme trace du diagnostic initial. ### 🔴 Bloquant pour la prochaine montée de version du moteur **R-01 — `UStreetMap::GetAssetRegistryTags` déprécié** `Plugins/StreetMap/Source/StreetMapRuntime/StreetMap.cpp:19-29` et `Public/StreetMap.h:395`. Le compilateur est explicite : > `warning C4996: 'UObject::GetAssetRegistryTags': Implement the version that takes > FAssetRegistryTagsContext instead. Please update your code to the new API before upgrading > to the next release, otherwise your project will no longer compile.` C'est **le seul avertissement C++ de tout le projet** et le seul obstacle dur à un passage en 5.6. Remède : basculer l'override sur `virtual void GetAssetRegistryTags(FAssetRegistryTagsContext Context) const override`, en utilisant `Context.AddTag(FAssetRegistryTag(...))` à la place de `OutTags.Add(...)`. Effort : quelques lignes. ### 🟠 Erreurs actives, non bloquantes **R-02 — 4 erreurs `StructProperty … is not initialized properly` à chaque démarrage** `Public/StreetMap.h:351,355` (`FStreetMapWater`) et `:375,379` (`FStreetMapPark`). Les `FVector2D BoundsMin` / `BoundsMax` de ces deux structs n'ont pas d'initialiseur, alors que `FStreetMapBuilding` (lignes 324, 328) porte déjà `= FVector2D::ZeroVector`. Le remède est la copie littérale du motif existant, 4 lignes. Sans lui, chaque session éditeur émet 4 `LogClass: Error` + 4 `LogAutomationTest: Error`. **R-03 — 53 nœuds `Get Skeletal Mesh` dépréciés** `GI`, `Person`, `CharGen`, `Inventory`, `Hairstyle`, `Inventory_Cloth`, `CharGenSlider`. `USkeletalMeshComponent::SkeletalMesh` est remplacé par `GetSkeletalMeshAsset()` / `GetSkinnedAsset()`. C'est de loin la première source d'avertissements (la moitié des 99 lignes du cook final ; le moteur émet deux lignes par nœud). Le projet possède déjà le patron de résolution : une commandlet calquée sur `LPFixEditableTextBoxFont` (repérer le nœud, relever la topologie, casser la broche, `ReconstructNode`, relier, resauvegarder) traiterait le lot sans ouvrir l'éditeur. **R-04 — 6 nœuds `GetRandomPointInNavigableRadius` dépréciés** `BPs/Room`, `BPs/Person`, `BPs/AI` → `GetRandomLocationInNavigableRadius`. Volume faible, correctif manuel envisageable. **R-05 — 3 liaisons d'événement orphelines** `UI/TopRight` : `On Clicked (StatButtonL)`. `UI/CharGen` : `On Clicked (ButtonPreviewErect)`, `On Clicked (ButtonEyelashColor)`. Le message *« n'a pas de composant correspondant valide »* signale un événement lié à un widget qui n'existe plus dans l'arbre : **le clic est silencieusement mort à l'exécution**. À arbitrer au cas par cas — recréer le widget, ou supprimer l'événement. **R-06 — Échelle nulle sur `CentralLondon:PersistentLevel.Wall`** `StaticMeshComponent0`, `Scale: X=0.000 Y=12.562 Z=5.750`. Produit un `MapCheck: Error`, un `LogPhysics: Warning` à chaque cook, et a déclenché un ensure `TMatrix::InverseFast() … results in NaNs` lors d'une session d'édition (crash `Ensure` enregistré sous `Saved/Crashes/UECC-Windows-7DC90D…`). Corps de collision invalide. Remède : donner une échelle X non nulle à cet acteur dans la carte. ### 🟡 Dette de portage résiduelle **R-07 — Système d'entrée hérité** `Config/DefaultInput.ini` conserve 55 `ActionMappings` et 13 `AxisMappings`. Enhanced Input est le système par défaut depuis UE 5.1 ; l'ancien reste fonctionnel en 5.5 mais est déprécié. Migration lourde (chaque `Input Action` Blueprint est concerné) : à planifier, pas à improviser. **R-08 — Configuration périmée ou incohérente** | Fichier | Constat | |---|---| | `Config/DefaultGame.ini` | `Description=Portage UE 4.27 - assets integres depuis LifePlay 5.9 Full Source` — faux depuis la migration | | `Config/DefaultGame.ini` | `StagingDirectory=(Path="D:/LifePlay_Build/topright")` alors que l'archive réelle part dans `D:\Game\LifePlay_Build_5.5\Windows` | | `Config/DefaultEngine.ini` | `[/Script/Engine.PhysicsSettings]` conserve 4 clés qui n'existent plus ni sur `UPhysicsSettings` ni sur `UPhysicsSettingsCore` en 5.5 : `bEnableAsyncScene`, `LockedAxis`, `bDefaultHasComplexCollision`, `AsyncSceneSmoothingFactor`. Les autres clés d'apparence PhysX (`bEnableShapeSharing`, `PhysXTreeRebuildRate`, `ContactOffsetMultiplier`, `bDisableKinematicStaticPairs`…) **survivent sur `UPhysicsSettingsCore` et doivent être conservées** | | `Config/DefaultEngine.ini` | section `[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]` dans un projet `WindowsNoEditor` uniquement | | `LifePlay.uproject` | entrées `ModdingPlus` et `MultiTask` (`Enabled: false`) alors que ces plugins sont absents de `Plugins/` | Aucun de ces points ne casse quoi que ce soit ; ils entretiennent la confusion sur l'état réel du portage. **R-09 — Commentaires d'en-tête obsolètes dans le C++** - `Source/LifePlayEditorTools/LPFixAssetRegistryNodesCommandlet.h:1` annonce *« Portage UE 4.27 »* et documente l'usage avec `UE4Editor-Cmd.exe` — la commande correcte en 5.5 est `UnrealEditor-Cmd.exe`. Idem `Source/LifePlay/LPAssetRegistryHelpers.h:1`. - `Source/LifePlay/LPVictoryCompat.cpp:72` renvoie à `notes/05-victory.md`, **fichier absent de l'arbre**. Soit le rapatrier dans `Docs/Architecture/`, soit retirer le renvoi. - `Source/LifePlay/LPVictoryCompat.h:3-4` cite « 9219 lignes » et « 8568 assets » ; l'analyse 4.27 comptait 9 327 lignes de plugin et l'arbre 5.5 contient 8 562 `.uasset`. Chiffres à aligner ou à retirer. **R-10 — `output.txt` (929 Ko) à la racine du projet** Journal d'un cook en échec, désormais périmé (les 6 erreurs qu'il documente sont corrigées). Il n'est couvert par aucune règle de `.gitignore`. À archiver sous `Docs/` ou à supprimer. **R-11 — La validation StreetMap n'a jamais été exécutée** `ULPCheckStreetMapCommandlet` a été écrite pour prouver que la migration n'a rien perdu sur les 280 villes, avec sortie CSV explicitement prévue *« pour comparer une exécution 4.27 et une exécution 5.5 »*. Aucune trace de `LogLPCheckStreetMap` dans `Saved/Logs`, aucun CSV dans l'arbre : **la comparaison reste à faire**. C'est le seul contrôle qui couvre le contenu de gameplay le plus volumineux du projet. ```bash UnrealEditor-Cmd.exe "D:\Game\LifePlay-master 5.5\LifePlay.uproject" -run=LPCheckStreetMap -CSV=Docs/Architecture/streetmap_5.5.csv -DumpAmenities ``` **R-12 — Aucun contrôle de version** Le projet n'est pas un dépôt git (pas de `.git`), alors qu'un `.gitignore` est présent et correctement rédigé. **8 563 assets ont été resauvegardés en place**, deux commandlets réécrivent des Blueprints et les resauvegardent, et deux crashes sont survenus au milieu d'un lot de resave. Il n'existe aujourd'hui aucun filet permettant de revenir en arrière ni de tracer précisément ce qu'un passage de commandlet a modifié. C'est le risque de projet le plus élevé de cette liste, indépendamment de sa gravité technique. ### ℹ️ Points de vigilance à conserver **R-13 — Ne pas retirer les `[CoreRedirects]`** Même après le resave complet, les sauvegardes joueur de `Content/Saves/` et les mods tiers antérieurs peuvent référencer `/Script/VictoryBPLibrary`. Les trois lignes coûtent zéro. **R-14 — `IsValid` de `Victory_LoadTexture2D_FromFile` ment** Le drapeau vaut `true` même quand la texture retournée est nulle (image illisible). Le comportement est repris volontairement du plugin d'origine pour ne pas changer celui des Blueprints. À documenter côté modding : le test fiable est `IsValid(Texture)`, pas la broche `IsValid`. **R-15 — `StreetMap` reste le seul C++ tiers du projet** 4 900 lignes, fork Vinfamy non rebasable sur l'amont. C'est là que se concentre désormais 100 % du risque de portage C++ (R-01 en est la première manifestation). Toute montée de version du moteur commence par une passe sur ce plugin. --- ## 10. Campagne de remédiation du 2026-09-08 — R-01 à R-11 Cette section rend compte de l'exécution. **Dix des onze points sont clos ; R-07 ne l'est pas — voir §10.5.** ### 10.1 Ce qui a été modifié | Point | Fichiers touchés | Nature | |---|---|---| | R-01 | `StreetMap.h`, `StreetMap.cpp` | `GetAssetRegistryTags(TArray&)` → `GetAssetRegistryTags(FAssetRegistryTagsContext)` | | R-02 | `StreetMap.h` | `= FVector2D::ZeroVector` sur les 4 `BoundsMin`/`BoundsMax` de `FStreetMapWater` et `FStreetMapPark` | | R-03 | 10 Blueprints | 56 `K2Node_VariableGet(SkeletalMesh)` → `K2Node_CallFunction(GetSkeletalMeshAsset)` | | R-04 | 3 Blueprints + `LPNavigationHelpers.{h,cpp}` | 6 nœuds réaiguillés vers un enrobage pur | | R-05 | `UI/TopRight`, `UI/CharGen` | 3 `K2Node_ComponentBoundEvent` orphelins supprimés | | R-06 | `Scenes/CentralLondon.umap` | `Wall.StaticMeshComponent0` : échelle X 0 → 0,1 | | R-08 | `DefaultGame.ini`, `DefaultEngine.ini`, `LifePlay.uproject` | nettoyage de configuration | | R-09 | 4 en-têtes C++ | commentaires et chiffres remis à jour | | R-10 | racine du projet, `.gitignore` | `output.txt` archivé sous `Saved/Logs/portage/` | | R-11 | `Docs/Architecture/streetmap_5.5.csv` | relevé des 280 villes produit | Trois commandlets ont été ajoutées à `LifePlayEditorTools`, sur le modèle de `LPFixEditableTextBoxFont` (repérage, rapport `-DryRun`, correction, recompilation, resauvegarde) : | Commandlet | Points | Lignes | |---|---|---:| | `LPFixDeprecatedNodes` | R-03, R-04 | 320 | | `LPFixOrphanBoundEvents` | R-05 | 200 | | `LPFixZeroScaleActors` | R-06 | 220 | Une sauvegarde des 13 assets réécrits a été déposée dans `Saved/Backups/avant-R03-R06/` (86 Mo) avant la première passe. ### 10.2 Vérification Quatre contrôles indépendants, tous passés après la campagne : | Contrôle | Avant (2026-09-07) | Après (2026-09-08) | |---|---|---| | Compilation C++ (`Build.bat LifePlayEditor`) | 1 avertissement `C4996` | **0 avertissement** | | `-run=CompileAllBlueprints` (103 Blueprints de `/Game/` + contenu moteur) | jamais exécuté | **0 erreur, 0 avertissement, 0 Blueprint en échec de chargement** | | `-run=Cook -TargetPlatform=Windows` | `0 error(s), 99 warning(s)` | **`0 error(s), 0 warning(s)`** | | `LogClass: ... is not initialized properly` au démarrage | 4 erreurs (×2 remontées) | **0** | La recompilation forcée de tous les Blueprints est le contrôle qui compte pour R-03 à R-05 : un cook itératif saute les assets déjà cuits, alors que `CompileAllBlueprints` recharge et recompile chacun. Elle confirme en particulier que le `ReconstructNode` de R-04 n'a perdu aucune liaison — une broche orpheline se serait traduite par une erreur de compilation. ### 10.3 Choix de conception à connaître **R-04 — pourquoi un enrobage plutôt que la fonction du moteur.** `K2_GetRandomPointInNavigableRadius` (déprécié) et `K2_GetRandomLocationInNavigableRadius` (son remplaçant) ont **exactement la même signature**, mais l'ancien est `BlueprintPure` et le nouveau `BlueprintCallable`. Réaiguiller directement les nœuds leur aurait ajouté des broches `Exec` non connectées : ils auraient été élagués à la compilation — précisément le piège que `ULPAssetRegistryHelpers` traite depuis le portage 4.27. `ULPNavigationHelpers` re-expose donc la version non dépréciée en `BlueprintPure`, avec des noms de broches identiques, et le réaiguillage se réduit à un changement de référence de fonction suivi d'un `ReconstructNode`. Coût : le module `LifePlay` gagne une dépendance publique à `NavigationSystem`. **R-05 — les nœuds en aval sont conservés.** Seul l'événement orphelin est supprimé (1, 5 et 1 nœuds en aval respectivement). La logique reste visible dans le graphe pour qui voudrait recréer le widget manquant ; elle est simplement inatteignable, ce qu'elle était déjà puisque le délégué ne pouvait pas se lier. **R-06 — pourquoi 0,1 et pas 1,0.** Le rapport de la commandlet a montré que `Wall` est un `/Engine/BasicShapes/Cube` (100 cm d'arête), **visible**, non caché en jeu, en collision `BlockAll`. Remettre X à 1,0 aurait fait apparaître un mur de 1 m d'épaisseur au milieu de Central London. X = 0,1 donne un panneau de 10 cm : corps physique valide, aspect visuel de mur plat préservé. La valeur est un paramètre de la commandlet (`-Scale=`), pas une constante. **R-08 — la moitié des clés « PhysX » devaient rester.** Contrôle fait contre `UPhysicsSettings` et `UPhysicsSettingsCore` de la 5.5 : seules `bEnableAsyncScene`, `LockedAxis`, `bDefaultHasComplexCollision` et `AsyncSceneSmoothingFactor` n'existent plus. `bEnableShapeSharing`, `PhysXTreeRebuildRate`, `ContactOffsetMultiplier`, `bDisableKinematicStaticPairs` et les autres survivent sur la classe de base et ont été conservées. L'estimation « ~15 clés mortes » de la première rédaction était fausse. ### 10.4 Résultat de R-11 — les 280 villes `LPCheckStreetMap` a été exécutée pour la première fois. Relevé complet dans `Docs/Architecture/streetmap_5.5.csv` (280 lignes, une par ville). | Mesure | Valeur | |---|---:| | Villes chargées | **280 / 280** | | Échecs de chargement | **0** | | Villes sans données | **0** | | Routes | 20 981 | | Nœuds | 27 058 | | Bâtiments | 53 050 | | Bâtiments nommés | 14 184 | | Bâtiments avec `Amenity` | 6 635 | | Parcs | 459 | | Plans d'eau | **0** | Les 0 plans d'eau méritent une note. `FStreetMapWater` est peuplé à l'import depuis les `natural=water` d'OpenStreetMap ; aucune des 280 villes n'en contient. **Ce n'est pas une régression de portage détectable** : le relevé 4.27 n'a jamais été fait, il n'existe donc pas de point de comparaison. Le constat est en revanche sans conséquence fonctionnelle : ni `Waters` ni `Parks` ne sont lus par un seul Blueprint du jeu — vérifié par recherche binaire sur `Content/BPs` et `Content/UI`. Le CSV produit ici devient la référence pour les montées de version suivantes. ### 10.5 R-07 — non exécuté, et pourquoi **Périmètre mesuré** : 34 actions et 6 axes déclarés dans `DefaultInput.ini` (les 55 `ActionMappings` correspondent à 34 actions, plusieurs touches par action), et **53 nœuds d'entrée concentrés dans un unique Blueprint, `Content/BPs/PC.uasset`** : | Type de nœud | Nombre | |---|---:| | `K2Node_InputAction` | 33 | | `K2Node_InputAxisEvent` | 8 | | `K2Node_InputKey` (touche brute) | 12 | Aucun autre asset du projet ne contient de nœud d'entrée. **Je ne l'ai pas exécuté.** La migration exige de créer ~40 `UInputAction` et un `UInputMappingContext`, de remplacer chaque événement hérité par son équivalent Enhanced Input, et surtout de **décider pour chaque nœud** de la correspondance `Pressed` → `Started` ou `Triggered`, `Released` → `Completed` ou `Canceled` : ce sont des choix sémantiques, pas des équivalences mécaniques comme R-03 et R-04. Le mode de défaillance est silencieux et total — une correspondance ratée ne produit ni erreur de compilation ni avertissement de cook, seulement une commande qui ne répond plus en jeu — et je n'ai aucun moyen de valider le résultat autrement qu'en jouant réellement. Mis en regard du bénéfice immédiat : **zéro**. Le système hérité fonctionne en 5.5, ne produit aucune erreur et aucun avertissement. R-07 est de la dette prospective, pas un défaut actif. Marche à suivre lorsque la décision sera prise : 1. `git init` d'abord (R-12) — c'est la seule remédiation dont R-07 dépend vraiment. 2. Créer les 40 `UInputAction` (`ValueType` : `Digital` pour les 34 actions, `Axis1D` pour les 6 axes) et l'`UInputMappingContext` reprenant les 68 lignes de `DefaultInput.ini`. 3. Dans `PC`, enregistrer le contexte au `BeginPlay` via `UEnhancedInputLocalPlayerSubsystem::AddMappingContext`. 4. Remplacer les 41 nœuds `InputAction`/`InputAxisEvent` ; les 12 `InputKey` bruts continuent de fonctionner sous Enhanced Input et peuvent rester en l'état. 5. Basculer `DefaultPlayerInputClass` et `DefaultInputComponentClass` dans `DefaultInput.ini`. 6. **Passer les 34 commandes une par une manette et clavier en main.** C'est l'étape qui ne peut pas être automatisée, et c'est elle qui conditionne tout le reste. ### 10.6 Ce qui reste ouvert | Point | État | |---|---| | R-01 … R-06, R-08 … R-11 | ✅ clos | | R-07 (Enhanced Input) | ⏸️ non exécuté — décision et test manuel requis (§10.5) | | R-12 (contrôle de version) | ❗ **toujours ouvert et toujours prioritaire** — hors du périmètre demandé, mais 13 assets de plus ont été réécrits en place aujourd'hui | | R-13 … R-15 | ℹ️ points de vigilance, rien à exécuter | --- ## 11. Résumé exécutif 1. **Le portage 5.5 est fonctionnel de bout en bout** : compilation, cook (`0 erreur`), package, IoStore, stage et archive passent — `BUILD SUCCESSFUL`, `ExitCode=0`. 2. **Le VictoryPlugin a disparu.** Les 9 327 lignes et les 15 modules moteur qu'il tirait (PhysX, APEX, ApexDestruction, HeadMountedDisplay, Vorbis, AIModule, HTTP…) ont été remplacés par **128 lignes** dans le module `LifePlay` — `ULPVictoryCompat` — plus trois lignes de `[CoreRedirects]`. Les 11 points de dette 🔴/🟠/🟡 identifiés au §7.2 du document 4.27 sont **tous résolus**. 3. **Le contenu a été intégralement migré** : 8 563 assets resauvegardés au format UE5, avec deux passages de commandlet correctrice (`LPFixAssetRegistryNodes`, `LPFixEditableTextBoxFont`) pour les nœuds Blueprint que le moteur ne pouvait plus résoudre. 4. **Le risque a changé d'adresse.** Il ne porte plus sur le VictoryPlugin mais sur `Plugins/StreetMap`, fork custom de 4 900 lignes non rebasable. C'est lui qui portait le seul avertissement C++ du projet — un `C4996` annonçant que le code ne compilerait plus à la version suivante du moteur. **Corrigé le 2026-09-08 (R-01) : la compilation ne produit plus aucun avertissement.** 5. **La campagne R-01 à R-11 du 2026-09-08 a clos dix points sur onze** (§10). Le cook passe désormais à **0 erreur et 0 avertissement**, contre 0 erreur et 99 avertissements avant. Les 280 villes StreetMap ont été validées pour la première fois : 280/280 chargées, 0 échec (§10.4). 6. **Deux choses restent ouvertes.** R-07 (Enhanced Input) n'a pas été exécuté : le mode de défaillance est silencieux et total, et la validation ne peut se faire que manette en main (§10.5). Et le projet n'est **toujours sous aucun contrôle de version** (R-12) alors que 8 563 assets ont été resauvegardés en place, puis 13 de plus réécrits le 2026-09-08. C'est la première chose à traiter, avant toute nouvelle passe.