Skip to content

Data Tables vs Data Assets

When the same numbers are copied into ten Blueprint defaults, the problem is not a missing cast. The data has outgrown the actor that happens to use it.

The one-minute version

  • A Data Table is many rows with the same struct shape. Use it when you want a spreadsheet-like list: level XP, item stats, enemy tuning rows, dialogue lines.
  • A Data Asset is one authored asset object that holds data. Use it when each item/enemy/ability wants its own editable asset with references, inheritance, or designer-friendly grouping.
  • Data Tables need a row struct. The row name is the stable key you use to find a row.
  • Data Assets are assets, not spawned actors. Referencing a Data Asset gives you authored data, not a live world object.
  • Move data out of Blueprint defaults when the same values must be shared, searched, tuned, localized, balanced, or reused by more than one class.
  • Do not move everything into data on day one. Start when duplication or tuning pain is real.

The problem they solve

Blueprint class defaults are fine for one actor:

BP_BasicEnemy
    MaxHealth = 50
    WalkSpeed = 300
    Damage = 10

They become painful when you have many entries:

BP_Slime, BP_Bat, BP_Golem, BP_Skeleton...
Each class has copied health, speed, XP, loot, icon, sound, and display name.

Now balancing the game means opening many Blueprints and hoping copied values stay consistent. Data Tables and Data Assets move those values into content assets that gameplay can read.

Data Tables

A Data Table is a list of rows. Every row has the same struct type.

Struct FEnemyTuningRow
    DisplayName (Text)
    MaxHealth (Float)
    Damage (Float)
    WalkSpeed (Float)
    XPReward (Integer)
    LootTableId (Name)

DataTable DT_EnemyTuning
    RowName: Slime
    RowName: Bat
    RowName: Golem

Use a Data Table when:

  • you have many entries with the same fields;
  • designers want spreadsheet-style editing or CSV import/export;
  • rows are looked up by stable row name;
  • the data is mostly plain values and asset references;
  • one graph can say "load row for this enemy ID."

The beginner rule: if you can imagine the data as rows and columns, a Data Table is probably a candidate.

Data Assets

A Data Asset is an asset instance that holds variables. Instead of one table with many rows, you make one asset per thing or per data package.

DA_FireballAbility
    DisplayName = Fireball
    Icon = T_FireballIcon
    ManaCost = 25
    Cooldown = 1.2
    ImpactEffect = NS_FireImpact

DA_IceBoltAbility
    DisplayName = Ice Bolt
    Icon = T_IceIcon
    ManaCost = 10
    Cooldown = 0.6
    ImpactEffect = NS_IceImpact

Use Data Assets when:

  • each entry benefits from being its own asset in the Content Browser;
  • entries need rich asset references such as meshes, sounds, materials, or Niagara systems;
  • you want inheritance or data-only Blueprint variants;
  • designers pick an asset reference directly on an actor/component;
  • the data is more "one authored object" than "one spreadsheet row."

Data Assets are often easier for beginners because you can click an asset, edit named fields, and assign that asset to a Blueprint variable.

Row names and keys

Data Tables are only pleasant when row names are stable:

ItemId = Potion_Small
Get Data Table Row(DT_Items, RowName = ItemId)

Do not use display text as the row key. Display text can be localized, changed, or made prettier. Use a stable Name, enum, or Gameplay Tag as the gameplay identifier, then store display text as data.

Data Assets often use the asset reference itself as the ID:

CurrentAbilityData = DA_FireballAbility

That is clear for small projects. For larger projects, you may still give the asset an internal ID or use Primary Data Assets and the Asset Manager. That is past the month-one boundary, but the concept is the same: stable data identity separate from live actors.

When they fail

Symptom Likely cause Fix shape
Data Table row lookup fails Wrong row name, table not assigned, or struct mismatch. Print row name, branch on success, and keep IDs stable.
Row fields are missing after struct change The table was built from an older struct shape or needs reimport/review. Update the struct/table together and inspect defaults.
Data Asset reference is None The actor/component variable was never assigned. Mark it instance editable or set a default asset on the class.
Changing data does not affect live actors The actor copied values at BeginPlay and never reread them. Decide whether data is read once or refreshed deliberately.
Multiplayer clients disagree Only one machine changed local runtime state. Replicate gameplay state; treat data assets/tables as shared definitions, not events.

Failure should be explicit in your graph:

Get Data Table Row
-> Branch Row Found
   true: apply row values
   false: Print "Missing item row: ItemId"

What they do not do

  • They do not spawn actors or widgets.
  • They do not save player progress by themselves.
  • They do not replace variables; they feed variables with better authored defaults or definitions.
  • They do not make live object references durable across levels.
  • They do not enforce balance rules. Your gameplay still decides how values are used.
  • They do not replicate runtime changes. Data is definition; replicated state is still state.

The pattern everyone actually uses

For item pickup data:

Struct FItemRow
    DisplayName
    Icon
    MaxStack
    Weight

DT_Items:
    Potion_Small
    Key_Bronze
    Ammo_Light

BP_Pickup:
    ItemId = Potion_Small

BeginPlay or OnInteract:
-> Get Data Table Row DT_Items by ItemId
-> if found:
       add item to inventory using row values
   else:
       print missing row

For abilities:

BP_AbilityComponent:
    EquippedAbilities = Array of Ability Data Asset references

Input CastAbility
-> get selected ability data asset
-> read cost/cooldown/icon/effect class
-> run ability behavior owned by component/character

The data says what the ability is. The component or character still owns the runtime behavior.

Lookalikes - which one do I want?

Tool Use when Watch out
Blueprint defaults One class has simple values and no duplication pain yet. Copying the same values into many classes gets stale.
Struct Several fields should travel as one value. It is not a database by itself.
Data Table Many rows share one struct shape. Row names and struct changes need care.
Data Asset One authored asset should hold a reusable data package. It is not a spawned actor.
SaveGame Player progress must survive quitting. SaveGame stores player data, not shared design definitions.
Game Instance Runtime values must survive Open Level. It is not persistent after quitting unless you save.

Rule of thumb: table for many same-shaped rows, asset for one rich authored definition, SaveGame for player progress.

Going deeper