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 :
ProjectDescriptor.cs:193-195(UnrealBuildTool\Configuration\Descriptors\) : chaque entrée devientDirectoryReference.Combine(BaseDir, x). L'espace dans le chemin ne pose pas problème (voir E1 : aucun avertissement « AdditionalPluginDirectory ... not found », émis parPlugins.cs:379-382si le dossier n'existe pas).RulesCompiler.cs:333-340(Configuration\Rules\) : pour chaque dossier,Plugins.ReadAdditionalPlugins(...).Plugins.cs:376-384(System\) : appelleReadPluginsFromDirectory(AdditionalDirectory, "", PluginType.External);Plugins.cs:626-648: appellePluginsBase.EnumeratePlugins(Dir)pourDir= le dossier donné (plus ses éventuelsPlatforms/*,Restricted/*,Unreal.csGetExtensionDirs).Shared\EpicGames.Build\System\EnumeratePlugins.cs:81-106,EnumeratePluginsInternal:
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. »foreach (DirectoryItem ChildDirectory in ParentDirectory.EnumerateDirectories()) // l. 83 { foreach (FileItem PluginFile in ChildDirectory.EnumerateFiles()) // l. 86 if (PluginFile.HasExtension(".uplugin")) ... // l. 88UEBuildTarget.cs:5581:NameToInfos = RulesAssembly.EnumeratePlugins()ne contient donc pas LPAnimCore. LPSandbox (trouvé dansPlugins/du projet) est ajouté parSetupPlugins(l. 5667), puis sa dépendance déclarée LPAnimCore est demandée parAddPlugin(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 exceptionUEBuildTarget.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 est3e9c32f 2026-10-07 18:28:32 DC1, qui ajouteAdditionalPluginDirectories(git show 3e9c32f -- LPSandbox.uproject) et, dansLPSandbox.uplugin, la dépendance"Plugins": [{"Name": "LPAnimCore"}].- Derniers produits de build autonome 5.5 :
Binaries\Win64\LPSandboxEditor.targetetIntermediate\Build\BuildRules\LPSandboxModuleRules.dlldatés du 2026-10-06 20:36. Le manifesteLPSandboxModuleRulesManifest.json(EngineVersion 5.5.4) ne contient ni LPAnimCore ni LPModTools (ajouté en DC2).find Intermediate Binaries Saved/Logs -newer LPSandbox.uprojectne 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.uproject5.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
AdditionalPluginDirectoriesest de typeExternal(Plugins.cs:383), doncLoadedFrom == Project(Plugins.cs:137-150). Il est actif par défaut sauf si son descripteur dit"EnabledByDefault": false(Plugins.cs:115-131).SetupPluginsajoute 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.upluginne 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": falseest ignorée avant toute recherche (UEBuildTarget.cs:5773-5777). Son nom entre dansReferencedNames(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, carPlugins/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) etEnabling plugin 'LPAnimCore' (referenced via LPSandbox.uproject -> LPSandbox.uplugin)(l. 77). Aucune ligneEnabling pluginne 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]+"etgrep -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-WarningsAsErrorssans s'arrêter.
5. Effets de bord
- Les règles C# des trois autres plugins sont compilées. Leurs
Build.csentrent dansLPSandboxModuleRules.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. - Tout plugin ajouté plus tard dans
LifePlay-master 5.8\Pluginssera actif par défaut dans la sandbox s'il ne précise pasEnabledByDefault: false(Plugins.cs:115-131), à moins d'être ajouté à la liste de désactivation. - 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-5335et5361-5364) :D:\Game\LifePlay-Sandbox-5.8\Binaries\Win64\UnrealEditor-LPAnimCore.dlletIntermediate\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_BODYsur saSource: 0 fichier). Rien n'a été écrit dans le jeu 5.8 : la listefind "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,diffvide). - DLL de l'addon dans le dossier du plugin (piège connu
lp-build/SKILL.md:94, incident AP7). Le build autonome créeD:\Game\LifePlay-Sandbox-5.8\Plugins\LPSandbox\Binaries\Win64\(UnrealEditor-LPSandbox.dll,-LPAnimMeasure.dll,-LPModTools.dllet leurs.pdb, plusUnrealEditor.modulesavec BuildId 55116800, le même que le jeu). Le jeu 5.8 compile ces modules dans son propreBinaries\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 versD:\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. - Dans l'éditeur sandbox, StreetMap et ModdingExtra seront chargés comme désactivés. Le
Contentest 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 dansShared, 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 exempleExternalPlugins/LPAnimCorevers le plugin du jeu, avec"AdditionalPluginDirectories": ["ExternalPlugins"]. Elle ne doit pas être dansPlugins/de l'addon : le jeu lit../LifePlay-Sandbox-5.8/Pluginset verrait LPAnimCore deux fois.Externall'emporte surProject(Plugins.cs:34-55et280-300).
6. État final du .uproject et piège de restauration
- Contenu remis exactement :
sha256sum=f9a772e5f9fb8d13d92ef88483cf6ed7dc1f8f4220ee5d8118f5d4263c0198ad, identique à la copie de départU4-T4c_LPSandbox.uproject.depart.git -C D:/Game/LifePlay-Sandbox-5.8 diff -- LPSandbox.uprojectest identique octet pour octet au diff de départ (cmpdeU4-T4c_uproject_diff_depart.txtet deU4-T4c_uproject_diff_final.txt, puis nouveaucmpaprès E4 : identiques).git status --porcelaindu 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 », et979-1031pour les dépendances). Après une restauration qui garde l'horodatage d'origine (cp -p), leMakefile.bind'E2 (Intermediate\Build\Win64\x64\LPSandboxEditor\Development\Makefile.bin, 18:32:40) était réutilisé. Le build du.uprojectd'origine répondait alorsTarget is up to date, code 0 : un faux succès. J'ai mis l'horodatage à l'heure actuelle avectouch, sans changer le contenu. E4 retrouve l'échec de départ (code 6). LeMakefile.bind'E2 reste sur disque mais il est ignoré tant que le.uprojectest 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, dontUnrealEditor-LPAnimCore.dlletUnrealEditor-LPSandboxApp.dll),Plugins\LPSandbox\Binaries\Win64(voir §5.4),Intermediate\Build,Intermediate\External. Il y a 212 entrées nouvelles (comparaison des listesfindavant 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.