LifePlay-Revival/Docs/Migration/etat/U58/U1/U1-T4a-IMPL.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

17 KiB
Raw Blame History

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, /LPAnimCore s'ils sont montés (LPAnimCore a CanContainContent: 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) puis ScanPathsSynchronous(racines) (piège lp-commandlets), GetAssetsByPaths récursif, disque seulement ; filtre FAssetData::GetClass()->IsChildOf(UBlueprint) avant tout chargement ; tri par chemin ; -Limit après tri.
  • Chargement un par un (LoadObject<UBlueprint>) ; null = échec listé. Toutes les 50 : FinishAllCompilation() puis CollectGarbage(RF_NoFlags) (pratique du moteur, § 4).
  • Graphes : UBlueprint::GetAllGraphs (Function, Macro, Ubergraph, DelegateSignature, graphes d'interfaces, extensions, chacun avec GetAllChildrenGraphs) + UEdGraphNode::GetSubGraphs des nœuds (même paquet), dédoublonnés.
  • Relevé par nœud : classe du nœud (toujours) ; UK2Node_CallFunction et dérivés → fonction (déclaration d'origine par remontée GetSuperFunction) ; UK2Node_Variable hors UK2Node_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_Event hors CustomEvent → fonction (evenement) ; UK2Node_FunctionEntry → fonction (surcharge) si sa déclaration d'origine est native.
  • Lecture seule : aucun MarkPackageDirty, Modify, SavePackage, CompileBlueprint dans le code (vérifiable par grep). La résolution FMemberReference peut corriger un redirecteur en mémoire (MemberReference.cpp:384-391), sans marquer le paquet (aucun MarkPackageDirty dans MemberReference.cpp, grep vide).
  • Sorties : calls.json (membres[] : type fonction|propriete|noeud, classe, classe_cpp, module, entete, nom, usages, assets, premiers_assets ≤ 20, contextes, deprecie, depreciation[], message, non_resolus, + references_depreciees pour 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 = true pour que le code du processus soit celui de Main (§ 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)

  1. Espace de noms nommé LPAuditBlueprintCallsImpl au lieu d'anonyme : c'est le style réel des voisins (LPAnimCatalogImpl, LPAnimIdentifyImpl) et la règle lp-build (collision C2374) ; using namespace dans Main seulement.
  2. 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.
  3. 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é).
  4. -Root accepte , ou + comme séparateur (PowerShell coupe à la virgule sans guillemets).
  5. É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) ; CustomEvent ignoré. Les références BP comptées sont celles des appels, variables et délégués.
  6. Non couvert (limites, à décider) : Blueprints de niveau (ULevelScriptBlueprint dans les .umap : pas un asset de premier niveau, il faudrait charger les cartes) ; types portés par les broches, cible de DynamicCast, structure des Make/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.
  7. 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.
  8. 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) et MakeShared<FJsonValueObject>(TSharedRef) comme les voisins (compilent en 5.5 aujourd'hui) ; initialisation TArray<FString>{ TEXT(...) } ; conversion implicite TObjectPtr → const UEdGraphNode* dans les boucles (ObjectPtr.h:661 5.5) ; avertissements de masquage (C4456-4458) relus à la main, non prouvés. Attendu : LPAuditBlueprintCallsCommandlet.cpp + .gen.cpp compilés, lien de UnrealEditor-LPModTools.dll, aucun avertissement nouveau.
  • Racines : forme de MountPointExists (testée avec et sans / final) ; la ligne de journal racines : /Game, /ModdingExtra ; non montees (ignorees) : /LPAnimCore doit apparaître. /Game non 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 dans summary.txt — vérifier qu'aucune n'est une famille de Blueprint (plugin non chargé).
  • Durée et mémoire : 9 068 .uasset sous Content (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 dans calls.json avec non_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 par git status avant / 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é.