LifePlay-Revival/Docs/Migration/etat/U58/U4/U4-T4c-DIAG.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

16 KiB

Fiche U4-T4c — Niveau N3 — Modèle prévu opus xhigh | utilisé Opus 5.5 (claude-opus-5-5) — Agent lp-cart — Skills sk-protocol, ue-cpp-build, lp-commandlets, lp-paths (lp-build non préchargé, son SKILL.md a été lu directement)

U4-T4c — Pourquoi UBT 5.8 ne trouve pas LPAnimCore pour le projet autonome LPSandbox

Date : 2026-10-08. Moteur : UE 5.8.3 (D:\Game\Launcher\Engine\UE_5.8\Engine\Build\Build.version : 5.8.3, CompatibleChangelist 55116800). Projet testé : D:\Game\LifePlay-Sandbox-5.8\LPSandbox.uproject (worktree de l'addon, branche ue5.8). Builds lancés : 4 sur les 6 autorisés (E1 à E4). Aucun UnrealEditor ni UnrealBuildTool ne tournait avant chaque build (tasklist | grep -i -E "UnrealEditor|UnrealBuildTool" vide, contrôlé par le script avant chaque lancement).

1. Cause (établie par le code et par l'essai)

UBT ne cherche un .uplugin que dans les sous-dossiers d'un AdditionalPluginDirectories, jamais dans le dossier lui-même. "../LifePlay-master 5.8/Plugins/LPAnimCore" désigne le dossier du plugin ; UBT inspecte donc Binaries, Intermediate, Source, n'y trouve aucun .uplugin, et ignore LPAnimCore.uplugin, qui est à la racine de ce dossier.

Où ça se passe dans le code d'UBT 5.8 :

  1. ProjectDescriptor.cs:193-195 (UnrealBuildTool\Configuration\Descriptors\) : chaque entrée devient DirectoryReference.Combine(BaseDir, x). L'espace dans le chemin ne pose pas problème (voir E1 : aucun avertissement « AdditionalPluginDirectory ... not found », émis par Plugins.cs:379-382 si le dossier n'existe pas).
  2. RulesCompiler.cs:333-340 (Configuration\Rules\) : pour chaque dossier, Plugins.ReadAdditionalPlugins(...).
  3. Plugins.cs:376-384 (System\) : appelle ReadPluginsFromDirectory(AdditionalDirectory, "", PluginType.External) ; Plugins.cs:626-648 : appelle PluginsBase.EnumeratePlugins(Dir) pour Dir = le dossier donné (plus ses éventuels Platforms/*, Restricted/*, Unreal.cs GetExtensionDirs).
  4. Shared\EpicGames.Build\System\EnumeratePlugins.cs:81-106, EnumeratePluginsInternal :
    foreach (DirectoryItem ChildDirectory in ParentDirectory.EnumerateDirectories())   // l. 83
    {
        foreach (FileItem PluginFile in ChildDirectory.EnumerateFiles())                // l. 86
            if (PluginFile.HasExtension(".uplugin")) ...                                // l. 88
    
    Seuls les fichiers des sous-dossiers sont lus. Le commentaire le dit (l. 54 et 78) : « Plugins will be found in any subfolders of this directory. »
  5. UEBuildTarget.cs:5581 : NameToInfos = RulesAssembly.EnumeratePlugins() ne contient donc pas LPAnimCore. LPSandbox (trouvé dans Plugins/ du projet) est ajouté par SetupPlugins (l. 5667), puis sa dépendance déclarée LPAnimCore est demandée par AddPlugin (l. 5975, récursion) et la recherche échoue l. 5886 : throw new BuildException("Unable to find plugin '{0}' (referenced via {1}) ...").

Preuve par le journal (E1, -VeryVerbose, U4-T4c_E1-repro-VeryVerbose_20261008-182910_UBTLog.txt:49-50) :

 Found 1 Plugins:
  D:\Game\LifePlay-Sandbox-5.8\Plugins\LPSandbox\LPSandbox.uplugin

LPAnimCore n'apparaît pas dans la liste (ligne de trace émise par RulesCompiler.cs:372-373) ; l. 61 : Unable to find plugin 'LPAnimCore' (referenced via LPSandbox.uproject -> LPSandbox.uplugin). Code de sortie 6. Contrôle : il n'y a aucun autre .uplugin ni .ubtignore sous D:\Game\LifePlay-master 5.8\Plugins\LPAnimCore (find ... -name "*.uplugin" -o -name ".ubtignore" : seul le fichier racine).

Pourquoi l'erreur n'avait pas été vue : le moteur C++ (éditeur, FPluginManager) accepte, lui, un dossier de plugin donné directement. Runtime\Projects\Private\PluginManager.cpp:1178-1203 met le dossier lui-même dans DirectoriesToVisit et y lit les fichiers. UBT (C#) et l'éditeur (C++) ne se comportent donc pas pareil. Le jeu 5.8 compile parce que son LifePlay.uproject donne le dossier parent ../LifePlay-Sandbox-5.8/Plugins.

Pistes de la fiche écartées : l'espace dans le chemin (le dossier est bien trouvé, pas d'avertissement) ; le cache par nom PluginInfoCache (Plugins.cs:239, 674) n'est rempli qu'avec les plugins trouvés, il n'est pas en cause ; ProjectDescriptor.cs:277 (AddAdditionalPaths) ne sert qu'à la liste des dossiers racines, pas à trouver les plugins.

2. La version 5.5 a-t-elle le même défaut ?

  • Code : établi. UBT 5.5 a la même logique : UE_5.5\...\EpicGames.Build\System\EnumeratePlugins.cs:84-109 (sous-dossiers seulement, l. 86/89/91, même commentaire l. 56/81), UnrealBuildTool\System\Plugins.cs:373-381, System\RulesCompiler.cs:294-298, même exception UEBuildTarget.cs:4936. Avec "../LifePlay-master 5.5/Plugins/LPAnimCore", D:\Game\LifePlay-Sandbox\LPSandbox.uproject échoue de la même façon. C'est estimé (non compilé, interdit par la fiche), mais déduit d'un code identique.
  • Historique : le projet autonome 5.5 n'a jamais été recompilé depuis DC1. Établi.
    • git -C D:/Game/LifePlay-Sandbox log --format='%h %ci %s' -- LPSandbox.uproject : la dernière modification est 3e9c32f 2026-10-07 18:28:32 DC1, qui ajoute AdditionalPluginDirectories (git show 3e9c32f -- LPSandbox.uproject) et, dans LPSandbox.uplugin, la dépendance "Plugins": [{"Name": "LPAnimCore"}].
    • Derniers produits de build autonome 5.5 : Binaries\Win64\LPSandboxEditor.target et Intermediate\Build\BuildRules\LPSandboxModuleRules.dll datés du 2026-10-06 20:36. Le manifeste LPSandboxModuleRulesManifest.json (EngineVersion 5.5.4) ne contient ni LPAnimCore ni LPModTools (ajouté en DC2). find Intermediate Binaries Saved/Logs -newer LPSandbox.uproject ne renvoie rien.
    • DC1 n'a compilé que le jeu : Docs\Migration\etat\sandbox\DC1\DC1-BUILD.md:17 (Build.bat LifePlayEditor ... LifePlay.uproject). La phrase du commit DC1 « le projet autonome LPSandbox.uproject le trouve par AdditionalPluginDirectories » n'a donc jamais été vérifiée par un build.
    • LPSandbox.uproject 5.5 n'est pas modifié (git -C D:/Game/LifePlay-Sandbox status --porcelain : 0 ligne).

3. Correction proposée (testée en E2)

Différence avec l'état actuel du worktree 5.8 (à appliquer par-dessus la modification U4-T3 non commitée) :

 	"Plugins": [
 		{
 			"Name": "LPSandbox",
 			"Enabled": true
+		},
+		{
+			"Name": "McpAutomationBridge",
+			"Enabled": false
+		},
+		{
+			"Name": "ModdingExtra",
+			"Enabled": false
+		},
+		{
+			"Name": "StreetMap",
+			"Enabled": false
 		}
 	],
 	"AdditionalPluginDirectories": [
-		"../LifePlay-master 5.8/Plugins/LPAnimCore"
+		"../LifePlay-master 5.8/Plugins"
 	],

Fichier complet testé : U4-T4c_LPSandbox.uproject.essai2 (fins de ligne LF comme l'original, JSON validé par python -c "import json; json.load(...)").

Pourquoi ces trois désactivations sont nécessaires, et pas seulement prudentes (établi par le code) :

  • Un plugin trouvé par AdditionalPluginDirectories est de type External (Plugins.cs:383), donc LoadedFrom == Project (Plugins.cs:137-150). Il est actif par défaut sauf si son descripteur dit "EnabledByDefault": false (Plugins.cs:115-131). SetupPlugins ajoute tout plugin actif par défaut et non cité dans le projet (UEBuildTarget.cs:5674-5695, « Also synthesize references for plugins which are enabled by default »).
  • Dans D:\Game\LifePlay-master 5.8\Plugins : StreetMap.uplugin:13 "EnabledByDefault" : true ; McpAutomationBridge.uplugin:16 "EnabledByDefault": true ; ModdingExtra.uplugin ne précise rien, donc actif. Sans la liste de désactivation, les trois seraient compilés dans le projet sandbox. McpAutomationBridge est en plus désactivé dans le jeu 5.8 (LifePlay.uproject, "Enabled": false) et ses binaires datent encore de la 5.5 (Plugins\McpAutomationBridge\Binaries\Win64\UnrealEditor.modules, BuildId 37670630) : sa compilation en 5.8 n'a jamais été essayée.
  • Une référence "Enabled": false est ignorée avant toute recherche (UEBuildTarget.cs:5773-5777). Son nom entre dans ReferencedNames (l. 5661), ce qui bloque l'ajout par défaut. Une référence désactivée vers un plugin absent ne provoque donc pas d'erreur : c'est utile, car Plugins/McpAutomationBridge/ est ignoré par git dans le jeu et manque sur un clone neuf.

4. Résultat des essais

Essai État du .uproject Commande (Build.bat LPSandboxEditor Win64 Development -Project=... -WaitMutex -NoHotReloadFromIDE) Code Résultat
E1 départ (U4-T3) + -VeryVerbose 6 même échec ; « Found 1 Plugins » (LPSandbox seul)
E2 correction §3 + -Verbose 0 Result: Succeeded, 233,83 s, 32 actions
E3 départ restauré, horodatage d'origine (18:04:14) sans option 0 faux succès : Target is up to date, 0 action (voir §6)
E4 départ restauré, horodatage mis à l'heure actuelle sans option 6 Creating makefile for LPSandboxEditor (.uproject file is newer) puis même échec que le départ

Détail d'E2 (U4-T4c_E2-parentPlugins-disable3_20261008-183212.txt et ..._UBTLog.txt) :

  • Chaîne d'outils : Using Visual Studio 14.50.35739 toolchain (...\MSVC\14.50.35717) and Windows 10.0.22621.0 SDK.
  • Plugins trouvés (UBTLog l. 49-54) : 5 (LPSandbox, LPAnimCore, McpAutomationBridge, ModdingExtra, StreetMap). Plugins activés : Enabling plugin 'LPSandbox' (l. 76) et Enabling plugin 'LPAnimCore' (referenced via LPSandbox.uproject -> LPSandbox.uplugin) (l. 77). Aucune ligne Enabling plugin ne cite StreetMap, ModdingExtra ou McpAutomationBridge (grep -n -E "StreetMap|ModdingExtra|McpAutomationBridge" : seulement les lignes 52-54 et 61-65, liste des plugins et des Build.cs).
  • Modules compilés : LPAnimCore, LPAnimMeasure, LPSandboxApp, LPModTools (8 .cpp, [Adaptive Build] Excluded from LPModTools unity file: LPHairFromStaticMeshCommandlet.cpp), LPSandbox ; 6 DLL liées ; [32/32] WriteMetadata LPSandboxEditor.target.
  • Erreurs : 0. Avertissements du compilateur ou de l'éditeur de liens : 0. Commandes : grep -c -i -E "warning [A-Z]+[0-9]+" et grep -c -i -E "error [A-Z]+[0-9]+|: error" sur la sortie console donnent 0 et 0 ; grep -c -i -E "warning C[0-9]+|warning LNK" et "error C[0-9]+|error LNK|: error" sur le UBTLog donnent 0 et 0. UHT a tourné avec -WarningsAsErrors sans s'arrêter.

5. Effets de bord

  1. Les règles C# des trois autres plugins sont compilées. Leurs Build.cs entrent dans LPSandboxModuleRules.dll (UBTLog E2 l. 61-65), même si les plugins sont désactivés. Si l'un d'eux ne compile plus en C# (cas possible pour McpAutomationBridge, plugin local non suivi par git), le build sandbox échouera à l'étape des règles. En E2, il n'y a eu aucune erreur.
  2. Tout plugin ajouté plus tard dans LifePlay-master 5.8\Plugins sera actif par défaut dans la sandbox s'il ne précise pas EnabledByDefault: false (Plugins.cs:115-131), à moins d'être ajouté à la liste de désactivation.
  3. Où vont les sorties de LPAnimCore (établi par le code et constaté) : comme plugin External, ses binaires et intermédiaires vont dans le projet sandbox (UEBuildTarget.cs:5328-5335 et 5361-5364) : D:\Game\LifePlay-Sandbox-5.8\Binaries\Win64\UnrealEditor-LPAnimCore.dll et Intermediate\External\Build\Win64\...\LPAnimCore. Le code UHT généré irait dans le dossier du plugin, côté jeu (UEBuildTarget.cs:6879-6904), mais LPAnimCore n'a aucun type réfléchi (grep UCLASS|USTRUCT|UENUM|GENERATED_BODY sur sa Source : 0 fichier). Rien n'a été écrit dans le jeu 5.8 : la liste find "LifePlay-master 5.8/Plugins" "LifePlay-master 5.8/Binaries" -printf '%T@ %s %p' est identique avant E2 et après E4 (2445 entrées, diff vide).
  4. DLL de l'addon dans le dossier du plugin (piège connu lp-build/SKILL.md:94, incident AP7). Le build autonome crée D:\Game\LifePlay-Sandbox-5.8\Plugins\LPSandbox\Binaries\Win64\ (UnrealEditor-LPSandbox.dll, -LPAnimMeasure.dll, -LPModTools.dll et leurs .pdb, plus UnrealEditor.modules avec BuildId 55116800, le même que le jeu). Le jeu 5.8 compile ces modules dans son propre Binaries\Win64 (18:20-18:22). D'après le SKILL, l'éditeur du jeu chargera les DLL du dossier du plugin à la place des siennes. Elles viennent du même code source aujourd'hui, mais elles deviendront périmées dès que le jeu sera recompilé avec un LPSandbox modifié. Ce dossier a été créé par l'essai E2 et il est toujours là (je n'ai rien déplacé, la fiche l'interdit). La correction recréera ce dossier à chaque build autonome. À arbitrer : le déplacer vers D:\Game\LifePlay_Backup_5.5\U4\ avant le prochain lancement de l'éditeur du jeu 5.8, ou décider où vivent les DLL de l'addon.
  5. Dans l'éditeur sandbox, StreetMap et ModdingExtra seront chargés comme désactivés. Le Content est une jonction vers celui du jeu, donc les assets qui utilisent leurs classes se chargeront avec des avertissements. C'est déjà le cas avant DC1, où le projet autonome n'avait que LPSandbox (estimé, non lancé).

Autres corrections possibles (non testées, car elles touchent le jeu ou d'autres fichiers que le .uproject) :

  • B. Dossier parent dédié dans le jeu, par exemple Plugins/Shared/LPAnimCore (git mv dans le dépôt public). UBT descend dans Shared, qui n'a pas de .uplugin (EnumeratePlugins.cs:102-104), donc le jeu trouve toujours LPAnimCore. La sandbox pointerait sur ../LifePlay-master 5.8/Plugins/Shared. Avantages : aucun autre plugin exposé, pas de liste de désactivation. Coût : déplacement dans le jeu, recompilation de LPAnimCore, documentation.
  • C. Jonction NTFS dans le worktree, hors de son Plugins/, par exemple ExternalPlugins/LPAnimCore vers le plugin du jeu, avec "AdditionalPluginDirectories": ["ExternalPlugins"]. Elle ne doit pas être dans Plugins/ de l'addon : le jeu lit ../LifePlay-Sandbox-5.8/Plugins et verrait LPAnimCore deux fois. External l'emporte sur Project (Plugins.cs:34-55 et 280-300).

6. État final du .uproject et piège de restauration

  • Contenu remis exactement : sha256sum = f9a772e5f9fb8d13d92ef88483cf6ed7dc1f8f4220ee5d8118f5d4263c0198ad, identique à la copie de départ U4-T4c_LPSandbox.uproject.depart. git -C D:/Game/LifePlay-Sandbox-5.8 diff -- LPSandbox.uproject est identique octet pour octet au diff de départ (cmp de U4-T4c_uproject_diff_depart.txt et de U4-T4c_uproject_diff_final.txt, puis nouveau cmp après E4 : identiques). git status --porcelain du worktree donne 16 lignes, les mêmes qu'au départ.
  • Écart à signaler : l'horodatage n'est plus celui d'origine. Le fichier date de 2026-10-08 18:38:19 au lieu de 18:04:14,89. Raison (établie par E3) : UBT ne vérifie la validité de son makefile que par horodatage (System\TargetMakefile.cs:718-729, « .uproject file is newer », et 979-1031 pour les dépendances). Après une restauration qui garde l'horodatage d'origine (cp -p), le Makefile.bin d'E2 (Intermediate\Build\Win64\x64\LPSandboxEditor\Development\Makefile.bin, 18:32:40) était réutilisé. Le build du .uproject d'origine répondait alors Target is up to date, code 0 : un faux succès. J'ai mis l'horodatage à l'heure actuelle avec touch, sans changer le contenu. E4 retrouve l'échec de départ (code 6). Le Makefile.bin d'E2 reste sur disque mais il est ignoré tant que le .uproject est plus récent.
  • Produits de build laissés dans le worktree par E2 (autorisés par la fiche, rien d'autre n'a été supprimé ou déplacé) : Binaries\Win64 (7 fichiers, dont UnrealEditor-LPAnimCore.dll et UnrealEditor-LPSandboxApp.dll), Plugins\LPSandbox\Binaries\Win64 (voir §5.4), Intermediate\Build, Intermediate\External. Il y a 212 entrées nouvelles (comparaison des listes find avant et après, comm -13).

7. Fichiers produits (tous dans D:\Game\LifePlay-master 5.5\Docs\Migration\etat\U58\U4\)

U4-T4c-DIAG.md (ce livrable) ; U4-T4c_UBTLog_depart.txt et .json (journal UBT de l'échec U4-T4b, copiés avant toute relance) ; U4-T4c_LPSandbox.uproject.depart ; U4-T4c_LPSandbox.uproject.essai2 ; U4-T4c_uproject_diff_depart.txt et U4-T4c_uproject_diff_final.txt ; pour chaque essai, la sortie console et le UBTLog copié : U4-T4c_E1-repro-VeryVerbose_20261008-182910*.txt, U4-T4c_E2-parentPlugins-disable3_20261008-183212*.txt, U4-T4c_E3-depart-restaure-mtime-origine_20261008-183800*.txt, U4-T4c_E4-depart-restaure-mtime-actuel_20261008-183820*.txt.