17 KiB
Fiche U1-T4a — Niveau N3 — Modèle prévu opus-xhigh | utilisé Opus 5.5 (claude-opus-5-5) — Agent lp-impl — Skills sk-protocol, ue-cpp-build, lp-build, lp-ue-compat (préchargés) ; lp-commandlets, lp-paths (invoqués : outil Skill disponible ; ue-cpp-build déjà préchargé, non réinvoqué)
U1-T4a — commandlet LPAuditBlueprintCalls (addon privé, lecture seule) — IMPL, non compilé
Statut : écrit, non compilé, non exécuté (interdit par la fiche : éditeur ouvert). Toute affirmation « compile » reste à établir par la fiche N0 suivante. Légende : établi = lu dans les sources (fichier:ligne) ; estimé = déduit ; incertain = à vérifier à la compilation ou à l'exécution.
1. Fichiers touchés (dépôt addon D:\Game\LifePlay-Sandbox, aucun commit)
| Fichier | Action |
|---|---|
Plugins/LPSandbox/Source/LPModTools/LPAuditBlueprintCallsCommandlet.h |
créé (51 lignes) |
Plugins/LPSandbox/Source/LPModTools/LPAuditBlueprintCallsCommandlet.cpp |
créé (~980 lignes, ASCII, fins de ligne LF comme les voisins) |
Plugins/LPSandbox/Source/LPModTools/LPModTools.Build.cs |
2 dépendances privées ajoutées (diff § 2) |
D:\Game\LifePlay-master 5.5\Docs\Migration\etat\U58\U1\U1-T4a-IMPL.md |
ce livrable (etat/ ignoré par git : .gitignore:74) |
git -C D:\Game\LifePlay-Sandbox status --porcelain après travail : M LPModTools.Build.cs, ?? …Commandlet.cpp,
?? …Commandlet.h, ?? Tools/claude/ (déjà présent avant la fiche). Jeu : M Docs/Migration/27_Plan_Migration_UE58.md
non modifié par moi (seulement lu) — présent au moment du contrôle, à attribuer à l'orchestrateur. Rien d'inclus de
LifePlay ni LifePlayEditorTools ; aucun correctif de compatibilité UE4 touché.
2. Diff du Build.cs
@@ -38,7 +38,12 @@ public class LPModTools : ModuleRules
"SkeletalMeshUtilitiesCommon",
"SkeletalMeshDescription",
- "AnimationCore"
+ "AnimationCore",
+ // LPAuditBlueprintCalls (lot U1, fiche U1-T4a) : noeuds K2 des graphes Blueprint et FBlueprintMetadata
+ "BlueprintGraph",
+ // LPAuditBlueprintCalls : K2Node_CallFunction.h et K2Node_Event.h incluent KismetCompilerMisc.h
+ // (module KismetCompiler, dependance privee de BlueprintGraph, donc non transmise)
+ "KismetCompiler"
});
Justification (établi) : K2Node_CallFunction.h:15 et K2Node_Event.h:16 incluent KismetCompilerMisc.h
(Editor/KismetCompiler/Public) ; BlueprintGraph.Build.cs ne cite KismetCompiler qu'en privé. Même paire que
LifePlayEditorTools.Build.cs du jeu. UMGEditor, Kismet, AnimGraph non ajoutés : non nécessaires
(WidgetBlueprint / AnimBlueprint traités par la base UBlueprint et GetAllGraphs ; aucun FBlueprintEditorUtils,
FKismetEditorUtilities ni type d'AnimGraph utilisé).
3. Comportement
- Usage :
UnrealEditor-Cmd.exe <projet> -run=LPAuditBlueprintCalls [-Root=/Game[,/Autre]] [-Out=<dossier>] [-Limit=N]. Défaut des racines :/Game,/ModdingExtra,/LPAnimCores'ils sont montés (LPAnimCore aCanContainContent: false→ ignoré et signalé ; ModdingExtra monté,Content/vide → 0 asset attendu). Racine donnée mais non montée → erreur, code 1. Sortie par défaut<projet>/Saved/Audit/BlueprintCalls/(ignoré par git). - Registre :
SearchAllAssets(true)puisScanPathsSynchronous(racines)(piège lp-commandlets),GetAssetsByPathsrécursif, disque seulement ; filtreFAssetData::GetClass()->IsChildOf(UBlueprint)avant tout chargement ; tri par chemin ;-Limitaprès tri. - Chargement un par un (
LoadObject<UBlueprint>) ;null= échec listé. Toutes les 50 :FinishAllCompilation()puisCollectGarbage(RF_NoFlags)(pratique du moteur, § 4). - Graphes :
UBlueprint::GetAllGraphs(Function, Macro, Ubergraph, DelegateSignature, graphes d'interfaces, extensions, chacun avecGetAllChildrenGraphs) +UEdGraphNode::GetSubGraphsdes nœuds (même paquet), dédoublonnés. - Relevé par nœud : classe du nœud (toujours) ;
UK2Node_CallFunctionet dérivés → fonction (déclaration d'origine par remontéeGetSuperFunction) ;UK2Node_VariablehorsUK2Node_StructOperation→ propriété (get/set) ;UK2Node_BaseMCDelegate(Add/Remove/Clear/Call/Assign) → propriété délégué ;ComponentBoundEvent/ActorBoundEvent→ propriété délégué ;UK2Node_EventhorsCustomEvent→ fonction (evenement) ;UK2Node_FunctionEntry→ fonction (surcharge) si sa déclaration d'origine est native. - Lecture seule : aucun
MarkPackageDirty,Modify,SavePackage,CompileBlueprintdans le code (vérifiable pargrep). La résolutionFMemberReferencepeut corriger un redirecteur en mémoire (MemberReference.cpp:384-391), sans marquer le paquet (aucunMarkPackageDirtydansMemberReference.cpp,grepvide). - Sorties :
calls.json(membres[]:typefonction|propriete|noeud,classe,classe_cpp,module,entete,nom,usages,assets,premiers_assets≤ 20,contextes,deprecie,depreciation[],message,non_resolus, +references_deprecieespour les nœuds), tri type/module/classe/nom ;node_classes.json;per_asset.csv(asset,classe,etat,graphes,noeuds,appels_natifs,references_natives,references_bp,non_resolus) ;summary.txt(totaux, classes d'assets, membres dépréciés utilisés, usages par module, échecs, 500 premières références non résolues, code de retour). - Code : 0 si tout est chargé et écrit ; 1 si un échec de chargement, aucune racine, aucun Blueprint ou une écriture
impossible.
UseCommandletResultAsExitCode = truepour que le code du processus soit celui deMain(§ 4).
4. Choix d'API (sources 5.5.4 D:\Game\Launcher\Engine\UE_5.5\Engine\Source, recoupées en 5.8.3)
| API | 5.5 (établi) | 5.8 (établi) |
|---|---|---|
UBlueprint::GetAllGraphs |
Runtime/Engine/Classes/Engine/Blueprint.h:1123, impl. Private/Blueprint.cpp:1855-1925 |
Blueprint.h:1107 |
sous-graphes AnimGraph enregistrés dans SubGraphs |
Editor/AnimGraph/Private/AnimGraphNode_StateMachineBase.cpp:159, AnimStateNode.cpp:137, AnimStateTransitionNode.cpp:149 |
— |
UEdGraph::GetAllChildrenGraphs |
Runtime/Engine/Classes/EdGraph/EdGraph.h:205, Private/EdGraph/EdGraph.cpp:321 |
— |
UEdGraphNode::GetSubGraphs / IsDeprecated / HasDeprecatedReference |
EdGraphNode.h:687 / 853 / 856 ; IsDeprecated = CLASS_Deprecated (EdGraphNode.cpp:616-619), surchargé par K2Node_SpawnActor.h:39 |
EdGraphNode.h:697 / 870 / 873 |
UK2Node_CallFunction::FunctionReference / GetTargetFunction |
Editor/BlueprintGraph/Classes/K2Node_CallFunction.h:75 / 155 (impl. .cpp:1375) |
:71 / :150 (UE_API) |
UK2Node_Variable::VariableReference / GetPropertyForVariable |
K2Node_Variable.h:56 / 166 |
:58 / :168 |
UK2Node_StructOperation : UK2Node_Variable (Make/Break exclus) |
K2Node_StructOperation.h:29 |
même ligne |
UK2Node_BaseMCDelegate::DelegateReference / GetProperty |
K2Node_BaseMCDelegate.h:22 / 51 (public : macro GENERATED_BODY_LEGACY finit par public:, Intermediate/…/K2Node_BaseMCDelegate.generated.h:41-46) |
:22 / :51 (inline) |
UK2Node_ComponentBoundEvent DelegatePropertyName / DelegateOwnerClass / GetTargetDelegateProperty |
K2Node_ComponentBoundEvent.h:36 / 40 / 73 |
mêmes lignes |
UK2Node_ActorBoundEvent idem |
K2Node_ActorBoundEvent.h:35 / 39 / 77 |
mêmes lignes |
UK2Node_Event::EventReference / FindEventSignatureFunction |
K2Node_Event.h:53 / 121 (impl. .cpp:340) |
mêmes lignes |
UK2Node_FunctionTerminator::FunctionReference / FindSignatureFunction |
K2Node_FunctionTerminator.h:32 / 59 (impl. .cpp:195) |
mêmes lignes |
FMemberReference GetMemberName / GetMemberParentClass / GetMemberParentPackage / IsSelfContext / IsLocalScope |
Runtime/Engine/Classes/Engine/MemberReference.h:203 / 221 / 226 / 240 / 246 |
mêmes lignes |
| surcharge Blueprint → super-fonction = fonction surchargée | Editor/KismetCompiler/Private/KismetCompiler.cpp:2291 ; UFunction::GetSuperFunction Class.h:2030 |
Class.h:2680 |
FBlueprintMetadata::MD_DeprecatedFunction / MD_DeprecatedProperty / MD_DeprecationMessage |
EdGraphSchema_K2.h:139 / 142 / 145 |
:143 / 146 / 149 |
CPF_Deprecated, CLASS_Deprecated |
CoreUObject/Public/UObject/ObjectMacros.h:431, :250 |
:463, :269 |
UField::FindMetaData (WITH_METADATA = WITH_EDITORONLY_DATA, Core/Public/Misc/CoreMiscDefines.h:32) |
Class.h:234-235 |
Class.h:272-273 |
FField::FindMetaData / GetOwnerStruct / GetOwnerUObject |
Field.h:777-778 / 657 / 636 |
Field.h:937-938 / 811 / 790 |
UField::GetOwnerClass, UStruct::GetPrefixCPP, UObjectBaseUtility::GetPackage |
Class.h:180, Class.h:590 (+3234), UObjectBaseUtility.h:477 |
Class.h:218, 781 (+4330), UObjectBaseUtility.h:504 |
IAssetRegistry::GetAssetsByPaths / ScanPathsSynchronous / SearchAllAssets |
AssetRegistry/Public/AssetRegistry/IAssetRegistry.h:238 / 655 / 666 |
:324 / 793 / 809 |
FAssetData::PackageName / AssetClassPath / GetObjectPathString / GetClass |
CoreUObject/Public/AssetRegistry/AssetData.h:180 / 189 / 342 / 456 |
:190 / 203 / 352 / 466 |
FPackageName::MountPointExists (racines enregistrées avec / final, ex. /Game/ PackageName.cpp:454) |
Misc/PackageName.h:348, impl. PackageName.cpp:421-425 |
PackageName.h:356-358 (3 surcharges, const FString& exacte) |
CollectGarbage(RF_NoFlags) précédé de FAssetCompilingManager::FinishAllCompilation |
UObjectGlobals.h:881 ; pratique : Editor/UnrealEd/Private/Commandlets/BaseIteratePackagesCommandlet.cpp:917-928 ; AssetCompilingManager.h:46 / 71 |
UObjectGlobals.h:952 ; AssetCompilingManager.h:44 / 69 |
SearchAllAssets(true) avant requête en commandlet |
CompileAllBlueprintsCommandlet.cpp:181 |
— |
UseCommandletResultAsExitCode (défaut false : le moteur force 1 si une erreur a été journalisée) |
Engine/Classes/Commandlets/Commandlet.h:96, Private/Commandlets/Commandlet.cpp:27, Launch/Private/LaunchEngineLoop.cpp:4256-4262 |
Commandlet.h:96, LaunchEngineLoop.cpp:4217-4218 |
LoadObject |
UObjectGlobals.h:1990 (const TCHAR*) |
UObjectGlobals.h:2175 (FStringView, const TCHAR* converti) |
FJsonObject::Set*Field |
Json/Public/Dom/JsonObject.h:181-182 (clés FString) |
JsonObject.h:142, 153-160, 199, 210-211, 226-227 (clés FStringView : TEXT() et FString acceptés) ; aucune itération des clés (piège R2 évité) |
divers : FName::LexicalLess, TArray::FilterByPredicate, FEngineVersion::Current, FParse::Value |
NameTypes.h:737, Array.h:1208, EngineVersion.h:40, Parse.h:59 / 70 |
NameTypes.h:826, Array.h:1737 ([[nodiscard]], résultat utilisé), EngineVersion.h:40, Parse.h:60 / 71 |
Garde de version : aucune. Toutes les API utilisées existent avec la même forme d'appel en 5.5 et 5.8 (tableau) ;
pas de ENGINE_MINOR_VERSION ni UE_VERSION_OLDER_THAN nécessaire (estimé, à confirmer par un build 5.8 en U4).
5. Écarts à la SPEC (fiche § 4–5)
- Espace de noms nommé
LPAuditBlueprintCallsImplau lieu d'anonyme : c'est le style réel des voisins (LPAnimCatalogImpl,LPAnimIdentifyImpl) et la règlelp-build(collision C2374) ;using namespacedansMainseulement. - Champs en plus :
calls.json(classe_cpp,contextes,depreciation[],message,non_resolus,references_depreciees),per_asset.csv(classe,etat,references_natives,references_bp,non_resolus),summary.txt(membres dépréciés utilisés, usages par module, 500 premières références non résolues, classes d'assets non chargées). Les champs demandés sont tous présents. - Code 1 aussi si aucune racine montée, aucun Blueprint trouvé, ou écriture impossible (zéro résultat = échec,
sk-protocol) ;UseCommandletResultAsExitCode = true(sans quoi une erreur de compilation au chargement d'un Blueprint du jeu forcerait 1 même si tout est chargé). -Rootaccepte,ou+comme séparateur (PowerShell coupe à la virgule sans guillemets).- Événements et fonctions surchargées dont la déclaration d'origine n'est pas native : non comptés comme
« références BP » (ce sont des définitions du jeu) ;
CustomEventignoré. Les références BP comptées sont celles des appels, variables et délégués. - Non couvert (limites, à décider) : Blueprints de niveau (
ULevelScriptBlueprintdans les.umap: pas un asset de premier niveau, il faudrait charger les cartes) ; types portés par les broches, cible deDynamicCast, structure desMake/Break, fabriques des nœuds asynchrones (UK2Node_BaseAsyncTask),CreateDelegate, nœuds Property Access, liaisons de propriétés UMG et d'AnimGraph : classe du nœud seulement. Contenu des macros moteur (StandardMacros, hors racines) non parcouru. - Compilation au chargement laissée au moteur (chargement par défaut, comme l'éditeur) :
LOAD_DisableCompileOnLoadécarté car non récursif (ObjectMacros.h:80: « dependencies will still compile on load »), état mixte. FinishAllCompilation()appelé sans condition avant chaque GC (le moteur le conditionne àFApp::CanEverRender(),BaseIteratePackagesCommandlet.cpp:917) : estimé sans effet de bord, plus sûr pour le GC.
6. Points incertains à vérifier (compilation N0, exécution)
- Compilation (incertain) :
SetObjectField(…, TSharedRef)etMakeShared<FJsonValueObject>(TSharedRef)comme les voisins (compilent en 5.5 aujourd'hui) ; initialisationTArray<FString>{ TEXT(...) }; conversion impliciteTObjectPtr → const UEdGraphNode*dans les boucles (ObjectPtr.h:6615.5) ; avertissements de masquage (C4456-4458) relus à la main, non prouvés. Attendu :LPAuditBlueprintCallsCommandlet.cpp+.gen.cppcompilés, lien deUnrealEditor-LPModTools.dll, aucun avertissement nouveau. - Racines : forme de
MountPointExists(testée avec et sans/final) ; la ligne de journalracines : /Game, /ModdingExtra ; non montees (ignorees) : /LPAnimCoredoit apparaître./Gamenon monté = défaut. - Classes d'assets :
GetClass()sans résolution ; les classes non chargées (souvent des classes Blueprint d'instances) sont comptées à part danssummary.txt— vérifier qu'aucune n'est une famille de Blueprint (plugin non chargé). - Durée et mémoire : 9 068
.uassetsousContent(find Content -name "*.uasset" | wc -l) ; nombre de Blueprints inconnu ; chaque Blueprint charge ses dépendances dures. Commencer par-Limit=20. - Sémantique :
appels_natifs= nœuds d'appel vers une fonction native ; une référence non résolue dont le parent est natif apparaît danscalls.jsonavecnon_resolus> 0 (clé = classe du parent, pas la classe déclarante). - Lecture seule : le moteur peut écrire hors dépôts (DDC
D:/DDC,Saved/,Intermediate/ignorés) ; à contrôler pargit statusavant / après (3 dépôts).
7. Commandes pour la fiche suivante (N0, éditeur fermé, une seule compilation)
Avant : éditeur Unreal fermé ; Makefile.bin à déplacer seulement si un test sans addon a eu lieu depuis le dernier
build (lp-build) ; noter les dates de Binaries\Win64\UnrealEditor-LPModTools.dll (jeu) et de
D:\Game\LifePlay-Sandbox\Plugins\LPSandbox\Binaries\Win64 ; relever les 3 git status.
cd 'D:\Game\LifePlay-master 5.5'
git status --porcelain > "$env:TEMP\U1T4a_jeu_avant.txt"
git -C 'Content\Modules' status --porcelain > "$env:TEMP\U1T4a_modules_avant.txt"
git -C 'D:\Game\LifePlay-Sandbox' status --porcelain > "$env:TEMP\U1T4a_addon_avant.txt"
$UE='D:\Game\Launcher\Engine\UE_5.5\Engine'; $Proj='D:\Game\LifePlay-master 5.5\LifePlay.uproject'
& "$UE\Build\BatchFiles\Build.bat" LifePlayEditor Win64 Development -Project="$Proj" -WaitMutex *> 'Saved\Logs\portage\U1-T4a_build.log'; "code=$LASTEXITCODE"
# preuves : code 0, ligne « Using Visual Studio … 14.38 », Compile LPAuditBlueprintCallsCommandlet.cpp, lien UnrealEditor-LPModTools.dll, 0 avertissement nouveau
.\Tools\RunCommandlet.ps1 -Lot U1 -Commandlet LPAuditBlueprintCalls -Args '-Limit=20 -Out=Saved/Audit/BlueprintCalls_essai'
.\Tools\RunCommandlet.ps1 -Lot U1 -Commandlet LPAuditBlueprintCalls
# preuve de chargement du nouveau code : lignes LogLPAuditBlueprintCalls « racines : … » et « AUDIT blueprints … -> <dossier> »
# sorties : Saved\Audit\BlueprintCalls\{calls.json,node_classes.json,per_asset.csv,summary.txt}
git status --porcelain | Compare-Object (Get-Content "$env:TEMP\U1T4a_jeu_avant.txt")
git -C 'Content\Modules' status --porcelain | Compare-Object (Get-Content "$env:TEMP\U1T4a_modules_avant.txt")
git -C 'D:\Game\LifePlay-Sandbox' status --porcelain | Compare-Object (Get-Content "$env:TEMP\U1T4a_addon_avant.txt")
Contrôles de cohérence suggérés (sk-recount) : lignes de per_asset.csv − 1 = « traites » de summary.txt ;
somme noeuds du CSV = « noeuds » du résumé = somme noeuds de node_classes.json ; etat=echec = échecs listés.
8. Handoff
Suite : lp-builder (N0) doit compiler LifePlayEditor 5.5 éditeur fermé puis lancer -Limit=20 puis tout /Game
(commandes § 7), état : code écrit dans l'addon (3 fichiers, non commités), jamais compilé ni exécuté.