Data Driven Gameplay Elements

Driving gameplay elements using externally stored data.

Choose your operating system:

Windows

macOS

Linux

Data driven gameplay helps mitigate the amount of work and complexity involved, as well as providing the ability to visualize and parameterize data creation and progression, for games that have an extended lifetime well beyond that of a typical boxed game, and require constant tweaking and balancing of data based on player feedback.

The ability to move data out to Microsoft Excel or other spreadsheet documents that can be maintained using proven tools and then imported to automatically take effect in the game. DataTables and CurveTables can be imported into Unreal Engine through Excel documents. These Excel documents are .xlsm (macro enabled Excel documents) that have macro based export buttons to enable easily exporting to the intermediate data format, comma separated variables (.csv).

These documents all reside in a single location to help make data easy to find and modify. You can download a sample .xlsm file by Right-clicking > Save as to download:

Data Tables

DataTables, as the name implies, is a table of miscellaneous but related data grouped in a meaningful and useful way, where the data fields can be any valid UObject property, including asset references. Before a designer can import a CSV file into a DataTable, a programmer has to create the row container telling the engine how to interpret the data.

These tables consist of column names that have a 1:1 mapping to a given code based UStruct and its variables, which must inherit from FTableRowBase to be recognized by the importer. The first column is expected to be named Name and contains the names by which each row is accessed for use in game.

Subsequent columns have a variable name for a heading and below, in the same column, the data for that row/column intersection. Given this format, a single row maps 1:1 directly to the structure inherited from FTableRowBase.

Example

As an example, here is a definition for level up experience data and the CSV document that supplies the data to the game:

/** Structure that defines a level up table entry */
USTRUCT(BlueprintType)
struct FLevelUpData : public FTableRowBase
{
    GENERATED_USTRUCT_BODY()

public:

    FLevelUpData()
    : XPtoLvl(0)
    , AdditionalHP(0)
    {}

    /** The 'Name' column is the same as the XP Level */

    /** XP to get to the given level from the previous level */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=LevelUp)
    int32 XPtoLvl;

    /** Extra HitPoints gained at this level */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=LevelUp)
    int32 AdditionalHP;

    /** Icon to use for Achivement */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=LevelUp)
    TSoftObjectPtr<UTexture> AchievementIcon;
};

CSV Document:

Name,XPtoLvl,AdditionalHP,AchievementIcon
1,0,0,"Texture2d'/Game/Textures/AchievementIcon1'"
2,1000,9,"Texture2d'/Game/Textures/AchievementIcon2'"
3,1000,10,"Texture2D'/Game/Textures/AchievementIcon3'"
4,1500,12,"Texture2D'/Game/Textures/AchievementIcon4'"
5,2000,14,"Texture2D'/Game/Textures/AchievementIcon5'"

The double quotes around the asset type are important for the property importing pipeline. Without them, the text is imported as Texture2d.

Data Table Importing Process

Follow the steps below to Import a CSV file:

  1. Save your file out of Excel or another spreadsheet software with the .csv extension.

  2. Open Unreal Editor, and click on Import in the Content Browser.

  3. Navigate and select the CSV file you want to import as a DataTable. You can choose from the following Import As options:

  • DataTable

  • CurveTable

  • Float Curve

  • Vector Curve

  • Linear Color Curve

    ImportAs.png

  1. You can choose the DataTable Row Type from the drop down list.

    DataRowType.png

  2. Additional Import Options are available to use:

    ImportOptions.png

    Import Option

    Description

    Ignore Extra fields

    Set to true to ignore extra fiels in the import data, if false it will warn about them

    Ignore Missing Fields

    Set to true to ignore any fields that are expected but missing, if false it will warn about them

    Import Key Field

    Explicit field in import data to use as key. If this is empty it uses Name for .JSON and the field field found for .CSV

  3. This creates a DataTable object in the current directory of the Content Browser.

    datatableobject.png

  4. You can view the contents of the DataTable in the editor by Double-clicking on the object. You can update the object by Right-clicking on the object and selecting Reimport from the menu. Note that the original file path is used when reimporting the object. Here is the view of the data just after importing:

Data Curves

Data Curves work in a similar manner to DataTables, however they only support floating point types. As with DataTables, the first column is named "Name" and contains the names by which each row is accessed for use in game. Each column heading after the first stores the X-axis variable for a curve to be plotted. The data under this heading is the Y-axis value for the given row. Given this format, a single row corresponds to a curve that code can access and interpolate data along.

Example

Here is an example table for damage progression:

0

1

2

3

Melee_Damage

15

20

25

30

Melee_KnockBack

1

2

4

8

Melee_KnockBackAngle

10

45

60

65

Melee_StunTime

0

1

5

7

Curve Tables

Curve Tables are useful for defining two dimensional numeric data. You can edit Simple Curves and Rich Curves in the Curve Data Table Editor. When creating a Curve Table, you can open the editor to edit curves in the table or curve view without needing to go back to the external program you created them with.

You can create Curve Tables in the Content Browser by navigating to the Miscellaneous section.

Curve Table Importing Process

Follow the steps below to Import a CSV file:

  1. Save your file out of Excel or another spreadsheet software with the .csv extension.

  2. Open Unreal Editor, and click on Import in the Content Browser.

  3. Navigate and select the CSV file you want to import as a Curve Table. You can choose from the following Import As options:

  • DataTable

  • CurveTable

  • Float Curve

  • Vector Curve

  • Linear Color Curve

    ImportAs.png

  1. Choose the Curve Table Type from the drop down list. Once selected, you will be prompted to choose your interpolation type between Constant, Linear, or Cubic.

    Interpolation Type

    Description

    Constant

    Values in Y Will not be interpolated between datapoints in X. They will clamp to the previous-known value of X.

    Linear

    Values in Y will be linrearly interpolated between datapoints in X.

    Cubic

    Values in Y will be cubic interpolated between datapoints in X.

  2. This creates a Curve Table object in the current directory of the Content Browser.

    ![curve-table-content-browser](CurveTableContentBrowser.png)

  3. You can double-click your Curve Table to open the Curve Table editor.

    ![curve-table-editor-view](ViewCurveTable.png)

  4. To see your Curve Table data in graph form, click the graph button.

    ![curve-table-graph-view](CurveGraphView.png)

  5. The Curve Table View allows multiple curves to be displayed.

    ![multi-curve-display](MultiCurveDisplay.png)(w:600)

  6. You can Rename and Delete curves by right-clicking on a curve.

    ![Renaming Curves](renaming-curves.gif)(w:600)

Data Hookup

Hooking up data from these tables is quite easy. From a programmer's perspective, all you must do is place a Blueprint-exposed variable of either FDataTableRowHandle or FCurveTableRowHandle, depending on if you want a DataTable or CurveTable, respectively. From a content provider's point of view, this will expose a data field with two subfields:

Subfield

Description

DataTable/CurveTable

this is the content reference to the table that holds the data.

RowName

this is the name in the first column of the row you wish to get data from.

Data Usage (C++ Programmers Only)

Once you have the data hooked up, using the data is quite simple. The handle structures provide helper functions FindRow() and GetCurve() that provide you a way to retrieve either a struct or curve filled with data. In the case of a FCurveTableRowHandle, an FRichCurve pointer is returned. The FDataTableRowHandle, however, allows you to specify a structure in the template function call. This structure can be the final structure or any of its parents in the inheritance hierarchy.

One final note is that all structures and curves returned should not be cached further than the local scope of a function. This is to ensure that if the table is refreshed via re-import, the data changes take effect immediately and that no invalid pointers are accessed.

In the above DataTable example, the asset that is referenced is a lazy loaded asset (TSoftObjectPtr handles this). If the Asset field type was set to UTexture, all of the assets would be loaded whenever the DataTable was loaded.