Config

MUD config

The mud.config.ts file is where a MUD project begins. It defines the resources (namespaces, tables, systems, and modules) used by your app and how MUD should codegen and deploy them. Its output is strongly typed for better type safety and developer experience in the form of hinting, inference, and autocomplete.

By default, the MUD config assumes your project is using only a single namespace. This is a great starting place for simple apps and worlds, where you're not yet thinking about extendability.

Once you're building a more complex app or on top of an existing world, you may want to take advantage of multiple namespaces. This enables more complex and composable behavior, including access control around data and functionality. Even MUD itself takes advantage of several namespaces for its core resources.

Single namespace

import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  namespace: "mud",
  enums: {
    TerrainType: ["None", "TallGrass", "Boulder"],
  },
  tables: {
    Counter: {
      schema: {
        value: "uint32",
      },
      key: [],
    },
    Tasks: {
      schema: {
        id: "bytes32",
        createdAt: "uint256",
        completedAt: "uint256",
        description: "string",
      },
      key: ["id"],
    },
  },
  systems: {
    IncrementSystem: {
      name: "increment",
      openAccess: true,
    },
  },
  excludeSystems: ["System3", "System2"],
});

Multiple namespaces

Starting with version 2.1 you can put multiple namespaces in the same config file, you create a namespaces record and within it a record for every namespace. For example:

Sample mud.config.ts files

A namespace

This is an extremely simple configuration file with a single namespace that contains a single table. The systems are defined implicitly, as all the contracts under src/namespaces/app that match *System.sol.

mud.config.ts
import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  namespaces: {
    app: {
      tables: {
        Tasks: {
          schema: {
            id: "bytes32",
            createdAt: "uint256",
            completedAt: "uint256",
            description: "string",
          },
          key: ["id"],
        },
      },
    },
  },
});

Source files

  • src/namespaces/app/systems - systems that belong to the app namespace.

Note that this is a convention, any *System.sol under src/namespaces/<namespace> is interpreted as a system in that namespace.

Generated files

  • src/namespaces/app/codegen/tables/Tasks.sol - the generated code for app__Tasks table.
  • src/namespaces/app/codegen/index.sol - a single file that imports all the table definitions of the namespace (in this case, only Tasks.sol).
  • src/codegen/world/I*System.sol - interfaces for all the systems.
  • src/codegen/world/IWorld.sol - the IWorld interface that inherits from all the I*System.sol files.

A namespace with an explicit system definition

By default Systems are publicly accessible. In this configuration, we explicitly specify TestSystem so we can specify that access to it is limited to authorized addresses.

mud.config.ts
import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  namespaces: {
    app: {
      tables: {
        Tasks: {
          schema: {
            id: "bytes32",
            createdAt: "uint256",
            completedAt: "uint256",
            description: "string",
          },
          key: ["id"],
        },
      },
      systems: {
        TestSystem: {
          openAccess: false,
        },
      },
    },
  },
});

Source files

  • src/namespaces/app/systems/RootSystem.sol - The system specified in mud.config.ts.
  • src/namespaces/app/systems - systems that belong to the app namespace.

Note that this is a convention, any *System.sol under src/namespaces/<namespace> is interpreted as a system in that namespace.

Generated files

  • src/namespaces/app/codegen/tables/Tasks.sol - the generated code for app__Tasks.
  • src/namespaces/app/codegen/index.sol - a single file that imports all the table definitions (in this case, only Tasks.sol).
  • src/codegen/world/I*System.sol - interfaces for all the systems, including IRootSystem.sol
  • src/codegen/world/IWorld.sol - the IWorld interface that inherits from all the I*System.sol files.

Two namespaces

In this example there are two namespaces, app and config. Each namespace contains a single table: app__Tasks and config__Configuration.

mud.config.ts
import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  namespaces: {
    app: {
      tables: {
        Tasks: {
          schema: {
            id: "bytes32",
            createdAt: "uint256",
            completedAt: "uint256",
            description: "string",
          },
          key: ["id"],
        },
      },
    },
    config: {
      tables: {
        Configuration: {
          schema: {
            deployer: "address",
            tokenAddress: "address",
            ipAddress: "bytes4",
            url: "string",
          },
          key: [],
        },
      },
    },
  },
});

Source files

  • src/namespaces/app/systems - systems that belong to the app namespace.
  • src/namespaces/config/systems - systems that belong to the config namespace.

Note that this is a convention, any *System.sol under src/namespaces/<namespace> is interpreted as a system in that namespace.

Generated files

  • src/namespaces/app/codegen/tables/Tasks.sol - the generated code for app__Tasks table.
  • src/namespaces/app/codegen/index.sol - a single file that imports all the table definitions of the namespace (in this case, only Tasks.sol).
  • src/namespaces/config/systems - systems that belong to the config namespace.
  • src/namespaces/config/codegen/tables/Tasks.sol - the generated code for config__Configuration table.
  • src/namespaces/config/codegen/index.sol - a single file that imports all the table definitions of the namespace (in this case, only Configuration.sol).
  • src/codegen/world/I*System.sol - interfaces for all the systems.
  • src/codegen/world/IWorld.sol - the IWorld interface that inherits from all the I*System.sol files.

Enumerations

mud.config.ts
import { defineWorld } from "@latticexyz/world";
 
export default defineWorld({
  enums: {
    Direction: ["Up", "Down", "Left", "Right"],
    MapDirection: ["North", "East", "South", "West"],
  },
  namespaces: {
    app: {
      tables: {
        Heading: {
          schema: {
            id: "bytes32",
            direction: "Direction",
            name: "string",
          },
          key: ["id"],
        },
        MapCursor: {
          schema: {
            id: "bytes32",
            direction: "MapDirection",
            name: "string",
          },
          key: ["id"],
        },
      },
    },
  },
});

Source files

  • src/namespaces/app/systems - systems that belong to the app namespace.

Note that this is a convention, any *System.sol under src/namespaces/<namespace> is interpreted as a system in that namespace.

Generated files

  • src/namespaces/app/codegen/tables/Heading.sol - the generated code for app__Heading table.
  • src/namespaces/app/codegen/tables/MapCursor.sol - the generated code for app__MapCursor table.
  • src/namespaces/app/codegen/index.sol - a single file that imports all the table definitions of the namespace (in this case, Heading.sol and MapCursor.sol).
  • src/codegn/common.sol - the enumerations in the config file.
  • src/codegen/world/I*.sol - interfaces for all the systems.
  • src/codegen/world/IWorld.sol - the IWorld interface that inherits from all the I*System.sol files.