Skip to content

Commit

Permalink
feat: system libraries (#3374)
Browse files Browse the repository at this point in the history
Co-authored-by: alvarius <[email protected]>
  • Loading branch information
vdrg and alvrs authored Nov 26, 2024
1 parent 275c867 commit 09536b0
Show file tree
Hide file tree
Showing 33 changed files with 1,494 additions and 26 deletions.
6 changes: 6 additions & 0 deletions .changeset/tough-laws-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@latticexyz/store": patch
"@latticexyz/world": patch
---

Adds an experimental feature to automatically generate Solidity libraries from systems, making it easier to perform calls between systems.
37 changes: 37 additions & 0 deletions docs/pages/world/systems.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,43 @@ If your `System` needs run both from the root namespace and from other namespace

</details>

#### System Libraries

<Callout type="warning" emoji="⚠️">
This is an experimental feature and is not recommended for production use yet. Its API is expected to change in the
future.
</Callout>

By setting the `generateSystemLibraries` codegen setting to true in your MUD config, the `worldgen` CLI will automatically generate a Solidity library for each system in your project. This feature simplifies inter-system communication by providing a convenient way of calling functions between systems.

Each generated library defines and exports a custom user-defined type that includes all the functions defined in the corresponding system. Internally, these system libraries utilize the World's `call` and `callFrom` methods to execute the actual system contracts.

```solidity filename="MySystem.sol"
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;
import { System } from "@latticexyz/world/src/System.sol";
// Library generated for MoveSystem,
import { moveSystem } from "./codegen/systems/MoveSystemLib.sol";
contract MySystem is System {
function someAction(uint256 x, uint256 y) external {
// All functions defined in the MoveSystem system are available globally for the exported `moveSystem` value
moveSystem.move(x, y);
// You can also use delegations (if they exist) by using `callFrom`
moveSystem.callFrom(_msgSender()).move(x, y);
// If MySystem is a root system, you need to use `callAsRoot`
moveSystem.callAsRoot().move(x, y);
// If MySystem is a root system, it can call other systems on behalf of any address with `callAsRootFrom`
moveSystem.callAsRootFrom(_msgSender()).move(x, y);
}
}
```

## Registering systems

For a `System` to be callable from a `World` it has to be [registered](https://github.com/latticexyz/mud/blob/main/packages/world/src/modules/init/implementations/WorldRegistrationSystem.sol#L115-L178).
Expand Down
3 changes: 3 additions & 0 deletions packages/store/ts/codegen/tablegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { uniqueBy } from "@latticexyz/common/utils";
import { getUserTypes } from "./getUserTypes";
import { getUserTypesFilename } from "./getUserTypesFilename";
import { getTableOptions } from "./getTableOptions";
import debug from "debug";

export type TablegenOptions = {
/**
Expand Down Expand Up @@ -65,4 +66,6 @@ export async function tablegen({ rootDir, config }: TablegenOptions) {
}
}),
);

debug("Generated tables");
}
2 changes: 2 additions & 0 deletions packages/world/ts/config/v2/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export type MODULE_DEFAULTS = typeof MODULE_DEFAULTS;
export const CODEGEN_DEFAULTS = {
worldInterfaceName: "IWorld",
worldgenDirectory: "world",
systemLibrariesDirectory: "systems",
generateSystemLibraries: false,
worldImportPath: "@latticexyz/world/src",
} as const satisfies CodegenInput;

Expand Down
4 changes: 4 additions & 0 deletions packages/world/ts/config/v2/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ export type Codegen = {
readonly worldInterfaceName: string;
/** Directory to output system and world interfaces of `worldgen` (Default "world") */
readonly worldgenDirectory: string;
/** Directory to output system libraries (Default "libraries") */
readonly systemLibrariesDirectory: string;
/** Generate libraries for each system (Default false) */
readonly generateSystemLibraries: boolean;
/**
* @internal
* Absolute import path for a package import or starting with `.` for an import relative to project root dir.
Expand Down
16 changes: 12 additions & 4 deletions packages/world/ts/config/v2/world.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ describe("defineWorld", () => {
Example: {
label: "Example",
type: "table",
namespaceLabel: "",
namespace: "",
namespaceLabel: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand All @@ -164,8 +164,8 @@ describe("defineWorld", () => {
Example: {
label: "Example",
type: "table",
namespaceLabel: "",
namespace: "",
namespaceLabel: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand All @@ -189,6 +189,8 @@ describe("defineWorld", () => {
indexFilename: "index.sol",
worldInterfaceName: "IWorld",
worldgenDirectory: "world",
systemLibrariesDirectory: "systems",
generateSystemLibraries: false,
worldImportPath: "@latticexyz/world/src",
},
systems: {},
Expand Down Expand Up @@ -242,6 +244,8 @@ describe("defineWorld", () => {
} & {
readonly worldInterfaceName: "IWorld"
readonly worldgenDirectory: "world"
readonly systemLibrariesDirectory: "systems"
readonly generateSystemLibraries: false
readonly worldImportPath: "@latticexyz/world/src"
}
readonly sourceDirectory: "src"
Expand Down Expand Up @@ -326,8 +330,8 @@ describe("defineWorld", () => {
Example: {
label: "Example",
type: "table",
namespaceLabel: "root",
namespace: "",
namespaceLabel: "root",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand All @@ -347,8 +351,8 @@ describe("defineWorld", () => {
root__Example: {
label: "Example",
type: "table",
namespaceLabel: "root",
namespace: "",
namespaceLabel: "root",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand All @@ -372,6 +376,8 @@ describe("defineWorld", () => {
indexFilename: "index.sol",
worldInterfaceName: "IWorld",
worldgenDirectory: "world",
systemLibrariesDirectory: "systems",
generateSystemLibraries: false,
worldImportPath: "@latticexyz/world/src",
},
systems: {},
Expand Down Expand Up @@ -425,6 +431,8 @@ describe("defineWorld", () => {
} & {
readonly worldInterfaceName: "IWorld"
readonly worldgenDirectory: "world"
readonly systemLibrariesDirectory: "systems"
readonly generateSystemLibraries: false
readonly worldImportPath: "@latticexyz/world/src"
}
readonly sourceDirectory: "src"
Expand Down
1 change: 1 addition & 0 deletions packages/world/ts/node/render-solidity/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./renderSystemInterface";
export * from "./renderSystemLibrary";
export * from "./renderWorldInterface";
export * from "./types";
export * from "./worldgen";
Loading

0 comments on commit 09536b0

Please sign in to comment.