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
.
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 theapp
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 forapp__Tasks
table.src/namespaces/app/codegen/index.sol
- a single file that imports all the table definitions of the namespace (in this case, onlyTasks.sol
).src/codegen/world/I*System.sol
- interfaces for all the systems.src/codegen/world/IWorld.sol
- theIWorld
interface that inherits from all theI*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.
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 inmud.config.ts
.src/namespaces/app/systems
- systems that belong to theapp
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 forapp__Tasks
.src/namespaces/app/codegen/index.sol
- a single file that imports all the table definitions (in this case, onlyTasks.sol
).src/codegen/world/I*System.sol
- interfaces for all the systems, includingIRootSystem.sol
src/codegen/world/IWorld.sol
- theIWorld
interface that inherits from all theI*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
.
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 theapp
namespace.src/namespaces/config/systems
- systems that belong to theconfig
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 forapp__Tasks
table.src/namespaces/app/codegen/index.sol
- a single file that imports all the table definitions of the namespace (in this case, onlyTasks.sol
).src/namespaces/config/systems
- systems that belong to theconfig
namespace.src/namespaces/config/codegen/tables/Tasks.sol
- the generated code forconfig__Configuration
table.src/namespaces/config/codegen/index.sol
- a single file that imports all the table definitions of the namespace (in this case, onlyConfiguration.sol
).src/codegen/world/I*System.sol
- interfaces for all the systems.src/codegen/world/IWorld.sol
- theIWorld
interface that inherits from all theI*System.sol
files.
Enumerations
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 theapp
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 forapp__Heading
table.src/namespaces/app/codegen/tables/MapCursor.sol
- the generated code forapp__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
andMapCursor.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
- theIWorld
interface that inherits from all theI*System.sol
files.