LifePlay-Revival/Docs/Architecture/VictoryPlugin_Architecture.md
edujiro5972 1122e17fa6 L0 : etat initial du projet 5.5 avant toute correction
Instantane de reference de la reprise de migration (2026-09-29).
Contient GI.uasset tel que trouve (copie UE4 identique a 4.27,
MD5 F4550DA5DC05FC005400CDCA2FC123C9). Ajouts de ce commit :
.gitattributes (aucune conversion de fin de ligne), regles .gitignore
CHG-001, Tools/ (Snapshot, Restore, AssetHeaders), empreintes L0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:56:10 +02:00

44 KiB
Raw Blame History

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

graph TD
  subgraph Projet["Projet LifePlay (UE 5.5)"]
    LP["LifePlay<br/>Runtime · 251 l."]
    LPET["LifePlayEditorTools<br/>Editor · 791 l."]
    BP["Content/BPs + UI<br/>(Blueprints)"]
    MODS["Content/Modules<br/>(DSL .lpscene/.lpaction/…)"]
  end

  subgraph Compat["Couche de compatibilité"]
    VC["ULPVictoryCompat<br/>2 nœuds · 128 l."]
    AR2["ULPAssetRegistryHelpers<br/>1 nœud pur"]
    CR["[CoreRedirects]<br/>DefaultEngine.ini"]
  end

  subgraph Plugins["Plugins locaux"]
    MEX["ModdingExtra<br/>Runtime · PreLoadingScreen · 7 nœuds"]
    SMR["StreetMapRuntime<br/>Runtime (fork Vinfamy)"]
    SMI["StreetMapImporting<br/>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

// 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.

[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.

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

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 {
    <<enumeration>>
    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.

graph LR
  GI["BPs/GI<br/>Game Instance"]
  EXT["UI/ExtImg"]
  FACE["UI/FaceTexture"]
  MENU["UI/MainMenu"]
  INV["UI/Inventory"]

  LOAD["Victory_LoadTexture2D_FromFile<br/>UTexture2D depuis un fichier disque"]
  CLIP["Victory_SaveStringToOSClipboard<br/>copie presse-papiers OS"]

  IW["ImageWrapper<br/>(module moteur)"]
  APPC["ApplicationCore<br/>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

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.

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<FAssetRegistryTag>&) → 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.