212 lines
16 KiB
Markdown
212 lines
16 KiB
Markdown
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` :
|
|
```csharp
|
|
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) :
|
|
```diff
|
|
"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`.
|