Store
Data model

How MUD models data

The MUD framework helps you to model your onchain state in a way that enables building applications with familiar tooling, like relational databases.

In your MUD config, you define data as a set of tables. Like relational databases, these tables have “columns” by way of two MUD concepts: a schema and a key. A schema is set of fields that map to Solidity types and a key is the list of fields that combine to form the table's primary key.

Defining tables

Let's say we're making a game where players can move around a map. The definition for a Position table might look something like:

mud.config.ts
import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  tables: {
    Position: {
      schema: {
        player: "address",
        x: "int32",
        y: "int32",
      },
      key: ["player"],
    },
  },
});

Translating the table definition above would look like this in a relational database:

playerxy
0x1234-51
0x567836

Because player is the key, we would have a unique/primary key constraint on player.

Let's add another table for terrain at a given position on the map. MUD allows for multiple fields in the key and, like databases, we call these composite keys.

mud.config.ts
import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  tables: {
    Position: {
      schema: {
        player: "address",
        x: "int32",
        y: "int32",
      },
      key: ["player"],
    },
    Terrain: {
      schema: {
        x: "int32",
        y: "int32",
        terrainType: "string",
      },
      key: ["x", "y"],
    },
  },
});

Similarly, the relational database representation of that table would look like:

xyterrainType
-10grass
01tree
10grass

Because we have a composite key of x and y, we would have a unique/primary key constraint on the tuple of (x, y).

Tables on chain

Solidity and the EVM have much more limited data structures, so how can we express a relational database onchain? MUD takes the concept of tables and does a few things with them:

Field types

Schema fields can use all of Solidity's static-length primitive types, arrays of those static-length primitive types, as well as string and bytes.

Key can only be used with fields that are defined as static-length Solidity primitive types.

Enums and user types are also supported and automatically map down to their Solidity primitive types.

The code and the rest of the documentation call some fields static and others dynamic. In MUD terminology static means static length (uint16, int32, bytes32, etc.) and dynamic means dynamic length (uint[], string, bytes, etc.).

More complex types like structs, string[], and bytes[] are not yet supported. We'll cover the reasons why in our encoding/decoding guide.