Nsight Graphics Analyzer
Luna5ama/Alpha-Piscium
Drive NVIDIA Nsight Graphics 2026.1+ from the command line for GPU performance analysis, frame capture, frame trace inspection, draw-call inspection, NVTX/D3DPERF stage timing, replay metadata…
A skill your agent uses when modelling designer-authored game data in C++ and loading it: data assets, data tables, curve tables, soft references and asset streaming.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-data-assets-tables --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ue-data-assets-tables .claude/skills/ue-data-assets-tables && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "ue-data-assets-tables" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tables into .claude/skills/ue-data-assets-tables/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-data-assets-tables", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tablesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-data-assets-tables --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/ue-data-assets-tables .agents/skills/ue-data-assets-tables && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "ue-data-assets-tables" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tables into .agents/skills/ue-data-assets-tables/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-data-assets-tables", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-data-assets-tables --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/ue-data-assets-tables .cursor/skills/ue-data-assets-tables && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "ue-data-assets-tables" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tables into .cursor/skills/ue-data-assets-tables/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-data-assets-tables", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/quodsoler/unreal-engine-skills.git --path skills/ue-data-assets-tables--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-data-assets-tables --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/ue-data-assets-tables .gemini/skills/ue-data-assets-tables && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "ue-data-assets-tables" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tables into .gemini/skills/ue-data-assets-tables/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-data-assets-tables", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install quodsoler/unreal-engine-skills ue-data-assets-tablesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/ue-data-assets-tables .github/skills/ue-data-assets-tables && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "ue-data-assets-tables" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tables into .github/skills/ue-data-assets-tables/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-data-assets-tables", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-data-assets-tables --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/ue-data-assets-tables .opencode/skills/ue-data-assets-tables && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "ue-data-assets-tables" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-data-assets-tables into .opencode/skills/ue-data-assets-tables/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-data-assets-tables", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
ue-data-assets-tablesA skill your agent uses when modelling designer-authored game data in C++ and loading it: data assets, data tables, curve tables, soft references and asset streaming.
Ue Data Assets Tables is an agent skill from quodsoler/unreal-engine-skills. Use when modelling designer-authored game data in C++ and loading it: data assets, data tables, curve tables, soft references and asset streaming. Also use when the user mentions 'UDataAsset', 'UPrimaryDataAsset', 'UDataTable', 'FTableRowBase', 'FindRow', 'FDataTableRowHandle', 'TSoftObjectPtr', 'TSoftClassPtr', 'FSoftObjectPath', 'UAssetManager', 'LoadPrimaryAsset', 'FStreamableManager', 'RequestAsyncLoad', 'asset bundles', 'PrimaryAssetTypesToScan', 'IAssetRegistry', 'CSV import', or 'hard vs soft reference'…
Its SKILL.md is about 7.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/asset-loading-patterns.md` and `references/data-driven-design.md`).
It sits in Documents & Office, covering CSV and tabular files. It works with C++. The repository describes itself as: Unreal Engine C++ skills for AI coding agents. 27 skills covering gameplay, rendering, networking, animation, and more. Works with Claude Code, Cursor, Windsurf, and any agent… The licence is MIT.
Read from SKILL.md and the folder at commit f3742d7. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are cpp and ini).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Ue Data Assets Tables loads about 7.5k tokens when it runs, and up to ~14k if it reads all its reference files. Until then it costs about 171 tokens; SKILL.md has 1,992 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from quodsoler/unreal-engine-skills at commit f3742d7, republished under its MIT licence (© quodsoler). 1,992 words, ~7,486 tokens.
.claude/skills/ue-data-assets-tables/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.Target engine: UE 5.8. APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
This skill covers designer-authored game data and the loading paths that bring it into memory: UDataAsset/UPrimaryDataAsset, UDataTable/UCurveTable, soft references, FStreamableManager, UAssetManager primary assets and cook rules, IAssetRegistry queries, the DataRegistry plugin and UDeveloperSettings. Build.cs modules: Engine and CoreUObject for data assets, tables and soft pointers; AssetRegistry for registry queries; DeveloperSettings for settings classes; DataRegistry for data registries. Deep dives live in asset loading patterns and data-driven design patterns.
Read .agents/ue-project-context.md if it exists (module names, conventions, enabled plugins, custom UAssetManager subclass, registered primary asset types). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
| Request is about… | Go to |
|---|---|
| Picking a container for game data | Choosing a Data Container |
UDataAsset, UPrimaryDataAsset, asset bundles | Data Assets |
Row structs, CSV/JSON import, FindRow | Data Tables |
| Curves, table composition | Curve Tables and Composite Tables |
TSoftObjectPtr, FSoftObjectPath, memory budget | References: Hard vs Soft |
| Async loading, handles, priorities | Async Loading |
FPrimaryAssetId, scanning, bundle states | Asset Manager |
Cooking, chunking, PrimaryAssetTypesToScan | Cook Rules |
| Finding assets without loading them | Asset Registry Queries |
| Sharing rows across sources at runtime | Data Registry |
| Project-wide tunables in Project Settings | Project Settings |
| Need | Use | Header |
|---|---|---|
| Per-object config, editor-authored, one asset per entry | UDataAsset | Engine/DataAsset.h |
| Same, plus load/unload by id and cook rules | UPrimaryDataAsset | Engine/DataAsset.h |
| Flat rows of identical shape, spreadsheet authored | UDataTable + FTableRowBase | Engine/DataTable.h |
| Rows merged from several tables (DLC, overrides) | UCompositeDataTable | Engine/CompositeDataTable.h |
| Float curves keyed by row name | UCurveTable, FCurveTableRowHandle | Engine/CurveTable.h |
| One row id resolved across many sources at runtime | UDataRegistrySubsystem | DataRegistrySubsystem.h |
| Project-wide tunables in Project Settings | UDeveloperSettings | Engine/DeveloperSettings.h |
UDataAsset supports Blueprint subclasses and inheritance; UDataTable rows do not. UDataTable gives lookup by row name out of the box; data assets need an Asset Manager scan or an Asset Registry query to be discoverable.
UDataAsset is a plain UObject you can instantiate from the Content Browser. UPrimaryDataAsset adds GetPrimaryAssetId() so UAssetManager can scan, load and unload it by id.
// MyWeaponDefinition.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "MyWeaponDefinition.generated.h"
class UTexture2D; class USkeletalMesh; // TSoftObjectPtr<T> needs T declared
UCLASS(BlueprintType)
class MYGAME_API UMyWeaponDefinition : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
FText WeaponName;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
float FireRate = 1.f;
/** Written into the Asset Registry so it can be filtered without loading. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon", AssetRegistrySearchable)
FName WeaponClassTag;
/** Bundles group soft references so the Asset Manager can load a subset. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Art", meta = (AssetBundles = "UI"))
TSoftObjectPtr<UTexture2D> Icon;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Art", meta = (AssetBundles = "Game"))
TSoftObjectPtr<USkeletalMesh> WorldMesh;
};GetPrimaryAssetId() rules (Engine/DataAsset.h:36-53):
virtual FPrimaryAssetId GetPrimaryAssetId() const override;.UpdateAssetBundleData() scans meta=(AssetBundles="Name") on the class and fills the AssetBundleData UPROPERTY during PreSave. Bundle names are free-form; meta=(AssetBundles="Client,Server") puts one property in two bundles.UDataAsset has no primary asset id and loads only through whoever references it.Every row struct derives FTableRowBase (Engine/DataTable.h:33) and uses GENERATED_BODY().
// MyItemTableRow.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataTable.h"
#include "MyItemTableRow.generated.h"
class UStaticMesh;
USTRUCT(BlueprintType)
struct FMyItemTableRow : public FTableRowBase
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
FText DisplayName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
int32 MaxStack = 1;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
TSoftObjectPtr<UStaticMesh> PreviewMesh;
/** Called after CSV/JSON import. Not editor-only. */
virtual void OnPostDataImport(const UDataTable* InDataTable, const FName InRowName, TArray<FString>& OutCollectedImportProblems) override;
/** Called for every row whenever the owning table is modified. Not editor-only. */
virtual void OnDataTableChanged(const UDataTable* InDataTable, const FName InRowName) override;
};FTableRowBase::IsDataValid(FDataValidationContext& Context) const is the third hook and is wrapped in #if WITH_EDITOR (Engine/DataTable.h:60-68); guard any override the same way and include Misc/DataValidation.h.
UPROPERTY(EditDefaultsOnly, Category = "Data")
TObjectPtr<UDataTable> ItemTable;
// FindRow<T>(FName, const TCHAR*|const FString&, bool bWarnIfRowMissing = true) -> T* or nullptr.
const FMyItemTableRow* Row = ItemTable->FindRow<FMyItemTableRow>(RowName, TEXT("LookupItem"));
TArray<FMyItemTableRow*> AllRows;
ItemTable->GetAllRows<FMyItemTableRow>(TEXT("GetAllItems"), AllRows);
TArray<FName> RowNames = ItemTable->GetRowNames();
ItemTable->ForeachRow<FMyItemTableRow>(TEXT("Foreach"),
[](const FName& Key, const FMyItemTableRow& Value)
{
// Key is the row name, Value the typed row.
});
// GetRowMap() is the raw TMap<FName, uint8*>; use it only for generic/reflection code.
const int32 NumRows = ItemTable->GetRowMap().Num();FDataTableRowHandle is the UPROPERTY-friendly reference (table plus row name) designers pick in the editor:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
FDataTableRowHandle StartingItemHandle; // IsNull() when nothing is picked
const FMyItemTableRow* Starting = StartingItemHandle.GetRow<FMyItemTableRow>(TEXT("StartingItem"));FMyItemTableRow NewRow;
NewRow.MaxStack = 5;
ItemTable->AddRow(FName(TEXT("RuntimeSword")), NewRow); // In memory only, not saved to disk.
ItemTable->RemoveRow(FName(TEXT("ObsoleteItem")));
ItemTable->HandleDataTableChanged(); // Fires the per-row OnDataTableChanged hooks.
// RowStruct must already be set. Available in all build configurations.
TArray<FString> Problems = ItemTable->CreateTableFromCSVString(CsvContent);
TArray<FString> JsonProblems = ItemTable->CreateTableFromJSONString(JsonContent);GetTableAsCSV(), GetTableAsJSON() and GetTableAsString() sit inside #if WITH_EDITOR (Engine/DataTable.h:318-345) — they do not exist in a cooked build. bStripFromClientBuilds on the table asset makes NeedsLoadForClient() return false, so server-only tables never ship to clients (Engine/DataTable.h:117,149).
UDataTableFunctionLibrary (Kismet/DataTableFunctionLibrary.h) exposes tables to Blueprint: GetDataTableRowFromName, DoesDataTableRowExist, GetDataTableRowNames, GetDataTableColumnNames, GetDataTableColumnAsString, GetDataTableRowStruct, EvaluateCurveTableRow, GetCurveTableRowNames, plus the editor-scripting FillDataTableFromCSVString / FillDataTableFromCSVFile.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Scaling")
FCurveTableRowHandle DamageCurve;
float ScaledDamage = DamageCurve.Eval(CharacterLevel, TEXT("ScaleDamage"));
// Or take the curve once for repeated sampling.
const FRealCurve* Curve = DamageCurve.GetCurve(TEXT("ScaleDamage"));FCurveTableRowHandle also offers GetRichCurve(), GetSimpleCurve(), IsNull() and Eval(float XValue, float* YValue, const FString& ContextString), which reports whether the lookup succeeded.
UCompositeDataTable merges its ParentTables array into one row map; later tables override earlier ones by row name. Use it for base game plus DLC or per-platform overrides. AppendParentTables(), RemoveParentTables() and GetParentTables() manage the stack; AddRow and RemoveRow are overridden as no-ops (Engine/CompositeDataTable.h:43-47, CompositeDataTable.cpp:191-204), so edit the parent tables instead.
| Form | Loads target when owner loads | Use for |
|---|---|---|
TObjectPtr<UStaticMesh> | Yes | Always-needed, small, or already resident assets |
TSubclassOf<AActor> | Yes (the class) | Classes spawned constantly |
TSoftObjectPtr<UStaticMesh> | No | Art, audio, VFX referenced by data |
TSoftClassPtr<AActor> | No | Blueprint classes chosen by data |
FSoftObjectPath | No | Untyped paths in generic systems |
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Art")
TSoftObjectPtr<UStaticMesh> MeshSoft;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Spawning")
TSoftClassPtr<AActor> SpawnableSoft; // LoadSynchronous() returns UClass*
const FSoftObjectPath MeshPath = MeshSoft.ToSoftObjectPath();
// State checks, no loading.
const bool bNoPathSet = MeshSoft.IsNull();
const bool bInMemory = MeshSoft.IsValid(); // path set AND target resolved in memory
const bool bLoadPending = MeshSoft.IsPending(); // path set, target not in memory yet
UStaticMesh* Resident = MeshSoft.Get(); // nullptr unless already loaded
// Blocking resolution. Avoid on the game thread outside loading screens.
UStaticMesh* Mesh = MeshSoft.LoadSynchronous();
UObject* Loaded = MeshPath.TryLoad(); // nullptr if missing, does not assert
UObject* Existing = MeshPath.ResolveObject(); // in-memory only, never loadsA hard reference inside a UPrimaryDataAsset pulls its whole dependency chain into memory as soon as the definition loads — the single biggest cause of runaway memory in data-driven projects. Default to soft references for content, hard references for values and small structs.
FStreamableManager (Engine/StreamableManager.h) is owned by the Asset Manager; reach it with UAssetManager::GetStreamableManager() and never construct your own in game code.
RequestAsyncLoad has two forms. The classic form takes the paths, a delegate, then TAsyncLoadPriority Priority, bool bManageActiveHandle, bool bStartStalled, FString DebugName. The params form takes a single FStreamableAsyncLoadParams&&.
// AMyPickupActor members: the handle owns the load, so it must not be a local.
TSharedPtr<FStreamableHandle> LoadHandle;
UPROPERTY(EditDefaultsOnly, Category = "Art")
TSoftObjectPtr<UStaticMesh> MeshSoft;
UPROPERTY(VisibleAnywhere, Category = "Art")
TObjectPtr<UStaticMeshComponent> MeshComponent;
void AMyPickupActor::BeginLoadMesh()
{
FStreamableManager& SM = UAssetManager::GetStreamableManager();
LoadHandle = SM.RequestAsyncLoad(
MeshSoft.ToSoftObjectPath(),
FStreamableDelegate::CreateUObject(this, &AMyPickupActor::OnMeshLoaded),
FStreamableManager::AsyncLoadHighPriority,
/*bManageActiveHandle=*/false,
/*bStartStalled=*/false,
TEXT("Pickup mesh"));
}
void AMyPickupActor::OnMeshLoaded()
{
if (UStaticMesh* Mesh = MeshSoft.Get())
{
MeshComponent->SetStaticMesh(Mesh); // Component now holds a hard reference.
}
LoadHandle.Reset();
}Params form, when you need the cancel/update delegates or JIT trickling:
FStreamableAsyncLoadParams Params;
Params.TargetsToStream = { IconSoft.ToSoftObjectPath(), MeshSoft.ToSoftObjectPath() };
Params.Priority = FStreamableManager::AsyncLoadHighPriority;
Params.bUseJustInTimeAsyncLoader = true;
Params.OnComplete = FStreamableDelegateWithHandle::CreateWeakLambda(this,
[this](TSharedPtr<FStreamableHandle> Handle)
{
// Both targets resolved.
});
LoadHandle = SM.RequestAsyncLoad(MoveTemp(Params), TEXT("Pickup bundle"));RequestSyncLoad(TargetsToStream, bManageActiveHandle = false, DebugName = FString()) blocks until done — loading screens and one-time init only.
FStreamableHandle member | Meaning |
|---|---|
IsActive() | Request exists and has not been released or cancelled |
HasLoadCompleted() | Every target finished (the delegate may not have run yet) |
IsLoadingInProgress() | Still streaming |
WasCanceled() / HasError() | Cancelled by you / one or more targets failed |
GetLoadProgress() | 0.0 to 1.0 |
GetLoadedAsset() / GetLoadedAsset<T>() | First target; GetLoadedAssets(TArray<T*>&) for all |
WaitUntilComplete(float Timeout = 0.f, bool bStartStalledHandles = true) | Blocks the caller, returns EAsyncPackageState::Type |
BindCompleteDelegate / BindCancelDelegate / BindUpdateDelegate | Attach callbacks after the request was made |
CancelHandle() | Stops the load; the complete delegate never fires |
ReleaseHandle() | Drops the streaming reference so the assets can be collected |
The handle is the reference. Assets loaded through RequestAsyncLoad stay alive only while a TSharedPtr<FStreamableHandle> to that request survives (or bManageActiveHandle was true). Dropping every pointer before completion does not cancel: the manager holds the handle until the completion delegate has run, then releases it (Engine/StreamableManager.h:316-320), so the assets are collectable at the next GC unless something else hard-references them.
Delegate factories: FStreamableDelegate::CreateUObject(this, &UMyLoader::Fn) (safe, checks the object), CreateWeakLambda(this, Lambda) (safe, drops if the owner died), CreateLambda(Lambda) (unsafe with a captured this).
UE_ENABLE_STREAMABLE_JIT_ASYNC_LOADING (Engine/StreamableManager.h:20) defaults to 0 and gates the just-in-time async loader at compile time. s.StreamableEnableJITAsyncLoading enables it for requests that opt in through bUseJustInTimeAsyncLoader; s.StreamableEnableJITAsyncLoadingGlobally forces it for every request. JIT trickles requests to the async loader instead of queueing them all at once, which keeps prioritisation and cancellation responsive under load. FStreamableHandle::IsUsingJustInTimeAsyncLoader() reports the resolved state.
More patterns — batching, combined handles, progress, cancellation — in asset loading patterns.
UAssetManager is the global singleton registered through [/Script/Engine.Engine] AssetManagerClassName. Subclass it to override StartInitialLoading() and PostInitialAssetScan().
UAssetManager& AM = UAssetManager::Get(); // Engine/AssetManager.h:97
TArray<FPrimaryAssetId> WeaponIds;
AM.GetPrimaryAssetIdList(FPrimaryAssetType(TEXT("MyWeaponDefinition")), WeaponIds);
const FPrimaryAssetId WeaponId(FPrimaryAssetType(TEXT("MyWeaponDefinition")), FName(TEXT("DA_Sword")));
TSharedPtr<FStreamableHandle> Handle = AM.LoadPrimaryAsset(
WeaponId,
TArray<FName>{ TEXT("Game") },
FStreamableDelegate::CreateUObject(this, &UMyItemSubsystem::OnWeaponLoaded));
UMyWeaponDefinition* Def = AM.GetPrimaryAssetObject<UMyWeaponDefinition>(WeaponId);
AM.ChangeBundleStateForPrimaryAssets(
{ WeaponId },
TArray<FName>{ TEXT("Game") }, // AddBundles
TArray<FName>{ TEXT("UI") }); // RemoveBundles
const int32 NumUnloaded = AM.UnloadPrimaryAsset(WeaponId);Signatures (Engine/AssetManager.h:333,340):
virtual TSharedPtr<FStreamableHandle> LoadPrimaryAsset(
const FPrimaryAssetId& AssetToLoad,
const TArray<FName>& LoadBundles = TArray<FName>(),
FStreamableDelegate DelegateToCall = FStreamableDelegate(),
TAsyncLoadPriority Priority = FStreamableManager::DefaultAsyncLoadPriority,
UE::FSourceLocation Location = UE::FSourceLocation::Current());
virtual TSharedPtr<FStreamableHandle> LoadPrimaryAsset(
const FPrimaryAssetId& AssetToLoad,
const TArray<FName>& LoadBundles,
FAssetManagerLoadParams&& LoadParams,
UE::FSourceLocation Location = UE::FSourceLocation::Current());LoadPrimaryAssets (plural), LoadPrimaryAssetsWithType, ChangeBundleStateForPrimaryAssets and ChangeBundleStateForMatchingPrimaryAssets all come in the same pair of shapes. Location is filled in by the compiler — never pass it. Prefer the FAssetManagerLoadParams overload for new code; it carries OnComplete, OnCancel (both FStreamableDelegateWithHandle), OnUpdate and Priority.
Unlike raw streamable requests, primary assets stay loaded until you unload them: you do not have to keep the returned handle alive, only to poll or wait on it.
ScanPathsForPrimaryAssets(FPrimaryAssetType, const TArray<FString>& Paths, UClass* BaseClass, bool bHasBlueprintClasses, bool bIsEditorOnly = false, bool bForceSynchronousScan = true) registers types from code when config-driven scanning is not enough. AddDynamicAsset(const FPrimaryAssetId&, const FSoftObjectPath&, const FAssetBundleData&) registers a runtime-generated primary asset.
; DefaultGame.ini
[/Script/Engine.AssetManagerSettings]
+PrimaryAssetTypesToScan=(PrimaryAssetType="MyWeaponDefinition",AssetBaseClass="/Script/MyGame.MyWeaponDefinition",bHasBlueprintClasses=False,bIsEditorOnly=False,Directories=((Path="/Game/Data/Weapons")),Rules=(Priority=1,ChunkId=-1,bApplyRecursively=True,CookRule=AlwaysCook))FPrimaryAssetTypeInfo fields (Engine/AssetManagerTypes.h:131): PrimaryAssetType, AssetBaseClass, bHasBlueprintClasses, bIsEditorOnly, Directories, SpecificAssets, Rules. FPrimaryAssetRules (Engine/AssetManagerTypes.h:66): Priority, ChunkId, bApplyRecursively, CookRule.
EPrimaryAssetCookRule (Engine/AssetManagerTypes.h:28):
| Value | Meaning |
|---|---|
Unknown | Cooks in development and production only if something references it |
NeverCook | Never cooked; a dependency on it is an error |
ProductionNeverCook | Cooks in development if referenced, never in production |
DevelopmentAlwaysProductionNeverCook | Always cooked in development, never in production |
DevelopmentAlwaysProductionUnknownCook | Always in development; production only if referenced |
AlwaysCook | Always cooked in both |
UAssetManagerSettings (config = Game, defaultconfig) also exposes DirectoriesToExclude, PrimaryAssetRules, CustomPrimaryAssetRules and bOnlyCookProductionAssets — turn the last one on for shipping branches so ProductionNeverCook assets error instead of leaking into the build.
An asset reachable neither from a scanned primary asset nor from a hard reference is not cooked. A soft reference alone does not pull an asset into the cook; give it a primary asset type or a UPrimaryAssetLabel.
IAssetRegistry reads asset metadata without loading the assets.
#include "AssetRegistry/ARFilter.h"
#include "AssetRegistry/AssetData.h"
#include "AssetRegistry/IAssetRegistry.h"
IAssetRegistry& AR = IAssetRegistry::GetChecked(); // AssetRegistry/IAssetRegistry.h:272
FARFilter Filter;
Filter.PackagePaths.Add(FName(TEXT("/Game/Data/Weapons")));
Filter.bRecursivePaths = true;
Filter.ClassPaths.Add(FTopLevelAssetPath(TEXT("/Script/MyGame"), TEXT("MyWeaponDefinition")));
Filter.bRecursiveClasses = true;
TArray<FAssetData> Found;
AR.GetAssets(Filter, Found);
// Direct call; the class argument is FTopLevelAssetPath, never FName.
AR.GetAssetsByClass(FTopLevelAssetPath(TEXT("/Script/MyGame"), TEXT("MyWeaponDefinition")), Found, /*bSearchSubClasses=*/true);
for (const FAssetData& Data : Found)
{
const FTopLevelAssetPath ClassPath = Data.AssetClassPath; // Data.AssetName for the short name.
FString TagValue;
Data.GetTagValue(FName(TEXT("WeaponClassTag")), TagValue); // Registry read, still no load.
UObject* Asset = Data.GetAsset(); // This one does load.
}IAssetRegistry::Get() returns a pointer that can be null before the module is up; GetChecked() asserts instead, and FAssetRegistryModule::GetRegistry() is the module-level equivalent. AssetRegistrySearchable on a UPROPERTY writes that property into the registry so FARFilter::TagsAndValues and GetAssetsByTagValues can filter on it without loading. Use ScanPathsSynchronous() when assets may not have been discovered yet.
DataRegistry (Beta in 5.8; plugin off by default, module DataRegistry) resolves one FDataRegistryId against a chain of sources — data tables, curve tables or custom ones — so gameplay code asks for an item by id without knowing which table or DLC provides it.
#include "DataRegistryId.h"
#include "DataRegistrySubsystem.h"
UDataRegistrySubsystem* Registry = UDataRegistrySubsystem::Get();
const FDataRegistryId ItemId(FName(TEXT("ItemRegistry")), FName(TEXT("Sword")));
// Cached read: non-null only if the source is already resident.
const FMyItemTableRow* Row = Registry->GetCachedItem<FMyItemTableRow>(ItemId);
// Otherwise request it, then re-query the cache in the callback.
Registry->AcquireItem(ItemId, FDataRegistryItemAcquiredCallback::CreateWeakLambda(this,
[ItemId](const FDataRegistryAcquireResult& Result)
{
const FMyItemTableRow* Acquired =
UDataRegistrySubsystem::Get()->GetCachedItem<FMyItemTableRow>(ItemId);
}));UDataRegistrySource_DataTable points a registry at a TSoftObjectPtr<UDataTable> SourceTable with FDataRegistrySource_DataTableRules (bPrecacheTable, CachedTableKeepSeconds); UDataRegistrySource_CurveTable does the same for curves. Registry assets are configured through UDataRegistrySettings.
UDeveloperSettings (module DeveloperSettings) auto-registers a class in Project Settings and reads from an ini section named after the class.
Declare the class UCLASS(config = Game, defaultconfig, meta = (DisplayName = "My Game")) deriving UDeveloperSettings, mark each field UPROPERTY(config, EditAnywhere, Category = "Economy"), and read it with GetDefault<UMyGameSettings>(). config = Game plus defaultconfig writes to DefaultGame.ini under [/Script/MyGame.MyGameSettings]; override GetContainerName(), GetCategoryName() or GetSectionName() to place the page. Use this for a handful of global tunables and data assets for anything designers iterate on per entry — the full class, with includes and the Build.cs dependency, is in data-driven design patterns.
| Do not emit | Use in 5.8 | Source |
|---|---|---|
TAssetPtr<T>, TAssetSubclassOf<T> | TSoftObjectPtr<T>, TSoftClassPtr<T> | Absent from 5.8 headers; UObject/SoftObjectPtr.h:173,795 |
FStringAssetReference | FSoftObjectPath | Absent from 5.8 headers; UObject/SoftObjectPath.h |
UAssetManager::IsValid(), GetIfValid() | IsInitialized(), GetIfInitialized() | UE_DEPRECATED(5.3) in Engine/AssetManager.h:91,99 |
OnAssetStateChangeCompleted(...) override | NotifyOnAssetStateChangeCompleted | UE_DEPRECATED(5.6) in Engine/AssetManager.h:1035 |
LoadAssetListInternal(...) | LoadAssetList(...) taking FAssetManagerLoadParams | UE_DEPRECATED(5.6) in Engine/AssetManager.h:1072 |
ShouldSetManager(Manager, Source, Target, ...) | ShouldSetManager(UE::AssetRegistry::FShouldSetManagerContext&) | UE_DEPRECATED(5.6) in Engine/AssetManager.h:1082 |
UpdateManagementDatabase(bool) | UpdateManagementDatabase(EUpdateManagementDatabaseFlags) | UE_DEPRECATED(5.6) in Engine/AssetManager.h:924 |
BuildChunkMap(PackagesToUpdateChunksFor) | the 3-argument BuildChunkMap | UE_DEPRECATED(5.6) in Engine/AssetManager.h:1129 |
FAssetData::AssetClass (short name) | FAssetData::AssetClassPath (FTopLevelAssetPath) | UE_DEPRECATED(5.1) in AssetRegistry/AssetData.h:198 |
GetAssetsByClass(FName ClassName, ...) | GetAssetsByClass(FTopLevelAssetPath, ...) | AssetRegistry/IAssetRegistry.h:335 |
UCurveTable::GetCurves() returning an array | GetCurves(TAdderReserverRef<FRichCurveEditInfoConst>) | UE_DEPRECATED(5.6) in Engine/CurveTable.h:106 |
UDataTable::RowStructName | GetRowStruct() at runtime; RowStructPathName is WITH_EDITORONLY_DATA | RowStructName_DEPRECATED in Engine/DataTable.h:168; GetRowStruct() at :110 |
GENERATED_USTRUCT_BODY() in row structs | GENERATED_BODY() | Both compile; only one is current house style |
"AssetManager" in a Build.cs dependency list | "Engine" | No such module; Engine/Classes/Engine/AssetManager.h |
Letting the streamable handle die: loaded assets are referenced by the handle, not by the soft pointer. Store TSharedPtr<FStreamableHandle> as a member until a hard reference (component, TObjectPtr, array) owns the asset, then reset it.
Hard-referencing content from a data asset: TObjectPtr<UNiagaraSystem> in a UPrimaryDataAsset loads the effect with the definition. Use TSoftObjectPtr plus an asset bundle.
LoadSynchronous() in Tick or on gameplay-critical paths: it stalls the game thread whenever the asset is not already resident. Start one async load and act in the callback.
Passing FName to GetAssetsByClass: 5.8 takes FTopLevelAssetPath(TEXT("/Script/Module"), TEXT("ClassName")). A short class name will not compile.
Forgetting PrimaryAssetTypesToScan: without a registered type, GetPrimaryAssetIdList returns nothing and LoadPrimaryAsset silently does nothing. Register the type in DefaultGame.ini or call ScanPathsForPrimaryAssets.
Capturing this in a bare CreateLambda: the callback can fire after the object is gone. Use CreateUObject or CreateWeakLambda(this, Lambda).
Calling GetTableAsCSV() at runtime: it is WITH_EDITOR only and will not link in a cooked build. Serialise the rows yourself instead. Likewise, renaming or removing a row-struct property makes existing rows lose that column on the next import — export the table to CSV before changing the struct, then re-import.
ue-cpp-foundations — UPROPERTY/USTRUCT specifiers, TObjectPtr, UObject lifecycle, the subsystem tableue-async-threading — general async idioms (UE::Tasks, Async, FTSTicker) beyond streamable loadingue-serialization-savegames — persisting soft object paths and primary asset ids across sessionsue-game-features — shipping data assets inside plugins and game feature asset scanningue-gameplay-abilities — ability and effect definitions that consume these data assetsue-world-level-streaming — level streaming, World Partition and Data Layersue-module-build-system — adding AssetRegistry, DeveloperSettings and plugin modules to Build.csue-audio-system — UAudioComponent, MetaSounds, submixes, attenuation and concurrencyue-blueprint-cpp-interop — exposing C++ to Blueprint: UFUNCTION/UPROPERTY meta keys, latent actions and async nodesue-editor-tools — detail customizations, editor utility widgets, UToolMenus and editor subsystemsue-gameplay-tags-messaging — native and ini gameplay tags, containers, queries and the async message systemue-materials-rendering — material instances, parameter collections, render targets and post processue-procedural-generation — PCG graphs, procedural and dynamic meshes, instancing and splinesue-ui-umg-slate — UMG widgets, Slate, Common UI and MVVM© quodsoler, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (references) in skills/ue-data-assets-tables of quodsoler/unreal-engine-skills.
Open the folder on GitHubat commit f3742d7
Ue Data Assets Tables next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Ue Data Assets Tables this skillquodsoler/unreal-engine-skills | 362 | — | ~7.5k | Automated safety check: Pass | MIT | |
| Nsight Graphics AnalyzerLuna5ama/Alpha-Piscium | 156 | — | ~4.7k | Automated safety check: Pass | GPL-3.0 | |
| Data ReportZJU-REAL/Easel | 3.4k | — | ~479 | Automated safety check: Pass | Apache-2.0 | |
| Data Table Managern8n-io/n8n | 207k | — | ~2.3k | Automated safety check: Pass | Custom licence | |
| Instrument Data To Allotropeaws-samples/amazon-bedrock-agents-healthcare-lifesciences | 274 | 2 repos | ~2.7k | Automated safety check: Pass | Apache-2.0 | |
| Abuse Hunternexu-io/harness-engineering-guide | 664 | — | ~1.9k | Automated safety check: Pass | MIT |
Luna5ama/Alpha-Piscium
Drive NVIDIA Nsight Graphics 2026.1+ from the command line for GPU performance analysis, frame capture, frame trace inspection, draw-call inspection, NVTX/D3DPERF stage timing, replay metadata…
ZJU-REAL/Easel
把 CSV、Excel 或 JSON 数据生成包含 KPI、图表和洞察的完整可视化报告页。当用户说“数据报告、CSV/Excel 转报告、做 KPI 看板、生成可视化报告页”时使用。单张图表用 chart-visualization;信息图或 GIF 动画图表用 infographic。
n8n-io/n8n
Load before calling data-tables or parse-file. An agent skill from n8n-io/n8n.
aws-samples/amazon-bedrock-agents-healthcare-lifesciences
Convert laboratory instrument output files (PDF, CSV, Excel, TXT) to Allotrope Simple Model (ASM) JSON format or flattened 2D CSV.
nexu-io/harness-engineering-guide
Detect and investigate bulk registration abuse on SaaS platforms.
TracecatHQ/tracecat
Turns a vague, high-level stakeholder ask into a structured set of intelligence requirements for a CTI team, complete with Essential Elements of Information, collection guidance, success criteria…
quodsoler/unreal-engine-skills
Unreal Engine C++ guidance for AActor and UActorComponent: lifecycle hooks, spawning, component creation and attachment, ticking, interfaces and composition.
quodsoler/unreal-engine-skills
Guides Unreal Engine C++ AI work across AI controllers, behavior trees, blackboards, perception, navmesh pathfinding, EQS and Smart Objects.
quodsoler/unreal-engine-skills
Reference for writing and debugging Unreal Engine 5.8 animation C++: AnimInstance and proxy, montages, notifies, curves, blend spaces, state machines, linked layers and root motion.
quodsoler/unreal-engine-skills
Picks and applies the right Unreal Engine C++ concurrency API, from UE::Tasks and FPipe to ParallelFor, FRunnable, locks and timers, with game-thread safety rules.
quodsoler/unreal-engine-skills
A skill your agent uses when playing, mixing or debugging sound in Unreal Engine — one-shot SFX, looping ambience, music, dialogue or procedural audio.
quodsoler/unreal-engine-skills
Reference for exposing Unreal Engine C++ to Blueprint and calling Blueprint from C++, covering UFUNCTION and UPROPERTY specifiers, latent and async nodes, and interfaces.
Works with
Categories
A skill your agent uses when modelling designer-authored game data in C++ and loading it: data assets, data tables, curve tables, soft references and asset streaming. Ue Data Assets Tables is an agent skill from quodsoler/unreal-engine-skills. Use when modelling designer-authored game data in C++ and loading it: data assets, data tables, curve tables, soft references and asset streaming.
Ue Data Assets Tables fits situations like: modelling designer-authored game data in C++ and loading it: data assets; soft references and asset streaming; the user mentions UDataAsset; UPrimaryDataAsset.
Run `npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a claude-code`. Or copy the skill folder (skills/ue-data-assets-tables in quodsoler/unreal-engine-skills) into .claude/skills/ue-data-assets-tables in your project. Claude Code loads it when a task matches its description.
Run `npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a codex`. Or copy the skill folder (skills/ue-data-assets-tables in quodsoler/unreal-engine-skills) into .agents/skills/ue-data-assets-tables in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add quodsoler/unreal-engine-skills --skill ue-data-assets-tables -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ue-data-assets-tables, .gemini/skills/ue-data-assets-tables, .github/skills/ue-data-assets-tables and .opencode/skills/ue-data-assets-tables in your project.
SKILL.md names no scripts, command-line tools or credentials: Ue Data Assets Tables is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Ue Data Assets Tables is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.5k tokens (SKILL.md is roughly 30k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 6.8k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Ue Data Assets Tables: Nsight Graphics Analyzer (Luna5ama/Alpha-Piscium, 156 stars), Data Report (ZJU-REAL/Easel, 3.4k stars), Data Table Manager (n8n-io/n8n, 207k stars) and Instrument Data To Allotrope (aws-samples/amazon-bedrock-agents-healthcare-lifesciences, 274 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
quodsoler (a GitHub user) maintains it in quodsoler/unreal-engine-skills, which has 362 GitHub stars. The repository holds 31 skills in this directory. The repository was last updated on September 28, 2026.
Source: quodsoler/unreal-engine-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.