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 key schema and a value schema. Each one has a set of fields that map to Solidity types.

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
export default mudConfig({
  tables: {
    Position: {
      keySchema: {
        player: "address",
      },
      valueSchema: {
        x: "int32",
        y: "int32",
      },
    },
  },
});

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

playerxy
0x1234-51
0x567836

Because player in part of the key schema, 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 keys in the key schema and, like databases, we call these composite keys.

mud.config.ts
export default mudConfig({
  tables: {
    Position: {
      keySchema: {
        player: "address",
      },
      valueSchema: {
        x: "int32",
        y: "int32",
      },
    },
    Terrain: {
      keySchema: {
        x: "int32",
        y: "int32",
      },
      valueSchema: {
        terrainType: "string",
      },
    },
  },
});

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

Key schema fields can use all of Solidity's static-length primitive types like uint256, address, bool.

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

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

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