Skip to main content

Core Concepts of FactsDB

Understanding the following five concepts is the key to mastering FactsDB. They form the foundation of how data is structured, instanced, and used at runtime.

1. The Fact

A Fact is the smallest, most fundamental unit of data in the system. It's simply a piece of named information that has a value.

  • Identifier: A unique Gameplay Tag (specifically, an FFactTag).
  • Value: Any data type Unreal Engine supports, from a simple bool or float to a complex FTransform or a custom user-defined struct.
Example FactsData Type
Fact.Player.Stat.Healthfloat
Fact.Weapon.Ammo.Currentint32
Fact.State.IsCrouchingbool
Fact.AI.Target.LastKnownLocationFVector

Think of a Fact as a single variable, but with a globally unique and hierarchical name.

2. The Schema

A Schema is a blueprint or a template for a collection of related Facts. It defines the "shape" of a set of data. For every Fact, the Schema specifies:

  • Its Tag (its unique name).
  • Its Data Type.
  • Its Default Value.
  • Metadata, such as whether it's Read-Only or if it should be Replicated over the network.

Schemas are defined in UDataTables and are identified by a unique Gameplay Tag (an FFactSchemaTag).

Analogy: Schemas are like Blueprint Classes

A Schema is to FactsDB what a Blueprint Class is to Unreal Engine. It defines the variables and their default values, but it's not a live object in the world. It's the template from which live objects are created.

Schemas can also inherit from a parent Schema. For example, you could have a Schema.Enemy.Base and then a Schema.Enemy.Goblin that inherits from it, adding or overriding specific Facts.

3. The Context

A Context is the live, runtime instance of a Schema. It's the actual container in the game world that holds the current values of all the Facts defined by its Schema.

Each Context is uniquely identified by a FFactContextID, which is composed of two parts:

  1. Prefix (FFactContextPrefix): A Gameplay Tag defining the type of the context (e.g., Context.Player, Context.Enemy.Goblin).
  2. Instance Name (FName): A unique name for this specific instance (e.g., Player_0, Goblin_Instance_42) or if left as default, a unique name will be created.
Analogy: Contexts are like Actors in the Level

If a Schema is the Blueprint Class, then a Context is the Actor you've placed in the level. It's a unique, live object with its own state, based on the template provided by the Schema.

4. The Facts Component (UFactsComponent)

The Facts Component is the bridge that connects an Actor in your world to a FactsDB Context. You add this component to your Actors (or Pawns, Characters, etc.) to give them a set of Facts.

The component's two most important properties are:

  • Schema Used: This is where you assign the Schema (FFactSchemaTag) that this component will use as its template.
  • Context ID: This is where you define the unique runtime ID for this component's data.

When the game starts, the UFactsComponent will:

  1. Read the assigned Schema Used.
  2. Initialize all the Facts defined in that Schema with their default values.
  3. Register itself with the UFactRuntimeSubsystem using its Context ID, making its data accessible to the rest of the game.

5. The Query

A Query is a reusable, data-driven logical question you can ask about the state of one or more Facts. Queries allow you to decouple your game logic from the raw data.

Instead of writing this in your Blueprint: ![Spaghetti Blueprint Check](image here)

You can define a Query named Query.Player.CanReloadWeapon in a data asset. The query's logic might look like this: ((Fact.Weapon.Ammo.Current < Fact.Weapon.Ammo.Max) AND (Fact.Player.Ammo.Reserve > 0))

Then, in your Blueprint, you simply use the Evaluate Query node. This makes your logic cleaner, more readable, and allows designers to tweak the conditions for "being able to reload" without ever touching the Blueprint graph.

Summary Flow

Here is how the concepts fit together:

  1. Design-Time: You define Facts inside DataTables, which are grouped into a Schema. You also define logical Queries in a Query Definition asset.
  2. Setup: You add a UFactsComponent to an Actor and assign it a Schema.
  3. Runtime: At runtime, the component becomes a unique Context. Other game systems can now Read/Write Facts in this Context or Evaluate Queries against it to make decisions.

With these core concepts in mind, you are ready to start using the system.

Next Up: Basic Workflow: Creating a Schema