Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: initial system manifest #2923

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions e2e/packages/contracts/.mud/systems.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"systems": [
{
"sourcePath": "src/systems/CustomErrorsSystem.sol",
"namespace": "",
"name": "CustomErrorsSystem",
"systemId": "0x73790000000000000000000000000000437573746f6d4572726f727353797374"
},
{
"sourcePath": "src/systems/LibWrapperSystem.sol",
"namespace": "",
"name": "LibWrapperSystem",
"systemId": "0x737900000000000000000000000000004c69625772617070657253797374656d"
},
{
"sourcePath": "src/systems/NumberListSystem.sol",
"namespace": "",
"name": "NumberListSystem",
"systemId": "0x737900000000000000000000000000004e756d6265724c69737453797374656d"
},
{
"sourcePath": "src/systems/NumberSystem.sol",
"namespace": "",
"name": "NumberSystem",
"systemId": "0x737900000000000000000000000000004e756d62657253797374656d00000000"
},
{
"sourcePath": "src/systems/VectorSystem.sol",
"namespace": "",
"name": "VectorSystem",
"systemId": "0x73790000000000000000000000000000566563746f7253797374656d00000000"
}
]
}
28 changes: 28 additions & 0 deletions examples/minimal/packages/contracts/.mud/systems.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"systems": [
{
"sourcePath": "src/systems/ChatSystem.sol",
"namespace": "",
"name": "ChatSystem",
"systemId": "0x737900000000000000000000000000004368617453797374656d000000000000"
},
{
"sourcePath": "src/systems/IncrementSystem.sol",
"namespace": "",
"name": "IncrementSystem",
"systemId": "0x73790000000000000000000000000000696e6372656d656e7400000000000000"
},
{
"sourcePath": "src/systems/InventorySystem.sol",
"namespace": "",
"name": "InventorySystem",
"systemId": "0x73790000000000000000000000000000496e76656e746f727953797374656d00"
},
{
"sourcePath": "src/systems/StructSystem.sol",
"namespace": "",
"name": "StructSystem",
"systemId": "0x7379000000000000000000000000000053747275637453797374656d00000000"
}
]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"url": "https://github.com/latticexyz/mud.git"
},
"scripts": {
"all-codegen": "for dir in packages/store packages/world packages/world-modules packages/cli test/mock-game-contracts e2e/packages/contracts examples/*/packages/contracts templates/*/packages/contracts; do (cd \"$dir\" && pwd && pnpm build); done",
"all-build": "for dir in packages/store packages/world packages/world-modules packages/cli test/mock-game-contracts e2e/packages/contracts examples/*/packages/contracts templates/*/packages/contracts; do (cd \"$dir\" && pwd && pnpm build); done",
"all-install": "for dir in . docs e2e examples/* templates/*; do (cd \"$dir\" && pwd && pnpm install); done",
"bench": "pnpm run --recursive bench",
"build": "turbo run build",
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/scripts/generate-test-tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { tablegen } from "@latticexyz/store/codegen";
import { defineStore } from "@latticexyz/store";
import { getRemappings } from "@latticexyz/common/foundry";
import { fileURLToPath } from "node:url";
import path from "node:path";

const configPath = fileURLToPath(import.meta.url);

Expand Down Expand Up @@ -97,4 +98,4 @@ const config = defineStore({

const remappings = await getRemappings();

await tablegen({ configPath, config, remappings });
await tablegen({ rootDir: path.dirname(configPath), config, remappings });
13 changes: 7 additions & 6 deletions packages/cli/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from "node:path";
import { tablegen } from "@latticexyz/store/codegen";
import { worldgen } from "@latticexyz/world/node";
import { generateSystemManifest, worldgen } from "@latticexyz/world/node";
import { World as WorldConfig } from "@latticexyz/world";
import { forge, getRemappings } from "@latticexyz/common/foundry";
import { getExistingContracts } from "./utils/getExistingContracts";
Expand All @@ -10,16 +10,16 @@ type BuildOptions = {
foundryProfile?: string;
srcDir: string;
/**
* Path to `mud.config.ts`. We use this as the "project root" to resolve other relative paths.
* MUD project root directory where all other relative paths are resolved from.
*
* Defaults to finding the nearest `mud.config.ts`, looking in `process.cwd()` and moving up the directory tree.
* Defaults to the directory of the nearest `mud.config.ts`, looking in `process.cwd()` and moving up the directory tree.
*/
configPath: string;
rootDir: string;
config: WorldConfig;
};

export async function build({
configPath,
rootDir,
config,
srcDir,
foundryProfile = process.env.FOUNDRY_PROFILE,
Expand All @@ -28,8 +28,9 @@ export async function build({
const remappings = await getRemappings(foundryProfile);

await Promise.all([
tablegen({ configPath, config, remappings }),
tablegen({ rootDir, config, remappings }),
worldgen(config, getExistingContracts(srcDir), outPath),
generateSystemManifest({ rootDir, config }),
]);

await forge(["build"], { profile: foundryProfile });
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { CommandModule } from "yargs";
import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
import { World as WorldConfig } from "@latticexyz/world";

import { getSrcDirectory } from "@latticexyz/common/foundry";
import { build } from "../build";
import path from "node:path";

type Options = {
configPath?: string;
Expand All @@ -27,7 +27,7 @@ const commandModule: CommandModule<Options, Options> = {
const config = (await loadConfig(configPath)) as WorldConfig;
const srcDir = await getSrcDirectory();

await build({ configPath, config, srcDir, foundryProfile: opts.profile });
await build({ rootDir: path.dirname(configPath), config, srcDir, foundryProfile: opts.profile });

process.exit(0);
},
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/tablegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
import { Store as StoreConfig } from "@latticexyz/store";
import { tablegen } from "@latticexyz/store/codegen";
import { getRemappings } from "@latticexyz/common/foundry";
import path from "node:path";

type Options = {
configPath?: string;
Expand All @@ -24,7 +25,7 @@ const commandModule: CommandModule<Options, Options> = {
const config = (await loadConfig(configPath)) as StoreConfig;
const remappings = await getRemappings();

await tablegen({ configPath, config, remappings });
await tablegen({ rootDir: path.dirname(configPath), config, remappings });

process.exit(0);
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/runDeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {

// Run build
if (!opts.skipBuild) {
await build({ configPath, config: configV2, srcDir, foundryProfile: profile });
await build({ rootDir: path.dirname(configPath), config: configV2, srcDir, foundryProfile: profile });
}

const resolvedConfig = resolveConfig({ config, forgeSourceDir: srcDir, forgeOutDir: outDir });
Expand Down
2 changes: 1 addition & 1 deletion packages/config/src/deprecated/node/loadConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export async function loadConfig(configPath?: string): Promise<unknown> {
}

/** @deprecated */
export async function resolveConfigPath(configPath: string | undefined, toFileURL?: boolean) {
export async function resolveConfigPath(configPath?: string, toFileURL?: boolean) {
if (configPath === undefined) {
configPath = await getUserConfigPath();
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"build:abi": "forge build",
"build:abi-ts": "abi-ts",
"build:js": "tsup",
"build:mud": "tsx ./ts/scripts/tablegen.ts && tsx ./ts/scripts/generate-test-tables.ts",
"build:mud": "tsx ./ts/scripts/build.ts && tsx ./ts/scripts/generate-test-tables.ts",
"build:tightcoder": "tsx ./ts/scripts/generate-tightcoder.ts",
"clean": "pnpm run clean:abi && pnpm run clean:js && pnpm run clean:mud",
"clean:abi": "forge clean",
Expand Down
9 changes: 6 additions & 3 deletions packages/store/ts/codegen/tablegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { Store as StoreConfig } from "../config/v2/output";
import { storeToV1 } from "../config/v2/compat";

export type TablegenOptions = {
configPath: string;
/**
* MUD project root directory where all other relative paths are resolved from.
*/
rootDir: string;
config: StoreConfig;
remappings: [string, string][];
};

export async function tablegen({ configPath, config, remappings }: TablegenOptions) {
const outputDirectory = path.join(path.dirname(configPath), config.sourceDirectory, config.codegen.outputDirectory);
export async function tablegen({ rootDir, config, remappings }: TablegenOptions) {
const outputDirectory = path.join(rootDir, config.sourceDirectory, config.codegen.outputDirectory);
const configV1 = storeToV1(config);
const solidityUserTypes = loadAndExtractUserTypes(configV1.userTypes, outputDirectory, remappings);
const allTableOptions = getTableOptions(config, solidityUserTypes);
Expand Down
2 changes: 1 addition & 1 deletion packages/store/ts/config/v2/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export type Codegen = {

export type Store = {
/**
* Directory of contracts source (i.e. Solidity) relative to the MUD config.
* Directory of Solidity source relative to the MUD config.
* This is used to resolve other paths in the config, like codegen and user types.
*
* Defaults to `src` to match `foundry.toml`'s default. If you change this from the default, you may also need to configure foundry with the same source directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
import { getRemappings } from "@latticexyz/common/foundry";
import { tablegen } from "../codegen";
import { Store as StoreConfig } from "../config/v2/output";
import path from "node:path";

const configPath = await resolveConfigPath(undefined);
const config = (await loadConfig(configPath)) as StoreConfig;
const remappings = await getRemappings();

await tablegen({
configPath,
config,
remappings,
});
await tablegen({ rootDir: path.dirname(configPath), config, remappings });
3 changes: 2 additions & 1 deletion packages/store/ts/scripts/generate-test-tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getRemappings } from "@latticexyz/common/foundry";
import { tablegen } from "../codegen";
import { defineStore } from "../config/v2/store";
import { fileURLToPath } from "node:url";
import path from "node:path";

const configPath = fileURLToPath(import.meta.url);

Expand Down Expand Up @@ -53,4 +54,4 @@ const config = defineStore({

const remappings = await getRemappings();

await tablegen({ configPath, config, remappings });
await tablegen({ rootDir: path.dirname(configPath), config, remappings });
9 changes: 3 additions & 6 deletions packages/world-modules/ts/scripts/tablegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
import { getRemappings } from "@latticexyz/common/foundry";
import { Store as StoreConfig } from "@latticexyz/store";
import { tablegen } from "@latticexyz/store/codegen";
import path from "node:path";

const configPath = await resolveConfigPath(undefined);
const configPath = await resolveConfigPath();
const config = (await loadConfig(configPath)) as StoreConfig;
const remappings = await getRemappings();

await tablegen({
configPath,
config,
remappings,
});
await tablegen({ rootDir: path.dirname(configPath), config, remappings });
40 changes: 40 additions & 0 deletions packages/world/.mud/systems.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"systems": [
{
"sourcePath": "src/modules/init/RegistrationSystem.sol",
"namespace": "world",
"name": "RegistrationSystem",
"systemId": "0x7379776f726c64000000000000000000526567697374726174696f6e53797374"
},
{
"sourcePath": "src/modules/init/implementations/AccessManagementSystem.sol",
"namespace": "world",
"name": "AccessManagementSystem",
"systemId": "0x7379776f726c640000000000000000004163636573734d616e6167656d656e74"
},
{
"sourcePath": "src/modules/init/implementations/BalanceTransferSystem.sol",
"namespace": "world",
"name": "BalanceTransferSystem",
"systemId": "0x7379776f726c6400000000000000000042616c616e63655472616e7366657253"
},
{
"sourcePath": "src/modules/init/implementations/BatchCallSystem.sol",
"namespace": "world",
"name": "BatchCallSystem",
"systemId": "0x7379776f726c64000000000000000000426174636843616c6c53797374656d00"
},
{
"sourcePath": "src/modules/init/implementations/ModuleInstallationSystem.sol",
"namespace": "world",
"name": "ModuleInstallationSystem",
"systemId": "0x7379776f726c640000000000000000004d6f64756c65496e7374616c6c617469"
},
{
"sourcePath": "src/modules/init/implementations/WorldRegistrationSystem.sol",
"namespace": "world",
"name": "WorldRegistrationSystem",
"systemId": "0x7379776f726c64000000000000000000576f726c64526567697374726174696f"
}
]
}
2 changes: 1 addition & 1 deletion packages/world/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"build:abi": "forge build",
"build:abi-ts": "abi-ts",
"build:js": "tsup",
"build:mud": "tsx ./ts/scripts/tablegen.ts && tsx ./ts/scripts/worldgen.ts && tsx ./ts/scripts/generate-test-tables.ts",
"build:mud": "tsx ./ts/scripts/build.ts && tsx ./ts/scripts/generate-test-tables.ts",
"clean": "pnpm run clean:abi && pnpm run clean:js && pnpm run clean:mud",
"clean:abi": "forge clean",
"clean:js": "rimraf dist",
Expand Down
11 changes: 11 additions & 0 deletions packages/world/ts/config/v2/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,15 @@ export type World = Store & {
readonly deploy: Deploy;
/** Codegen config */
readonly codegen: Codegen;

/** @internal */
readonly internal: {
/**
* Whether or not the MUD project is using multiple namespaces.
* This is used to determine where to generate table libraries, find system contracts, etc.
* We use a separate boolean here because we may also populate a `namespaces` output key for single-namespace projects.
* @internal
*/
readonly multipleNamespaces: boolean;
};
};
7 changes: 5 additions & 2 deletions packages/world/ts/config/v2/world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ export type resolveWorld<world> = evaluate<

export function resolveWorld<const world extends WorldInput>(world: world): resolveWorld<world> {
const scope = extendedScope(world);
const namespaces = world.namespaces ?? {};
const multipleNamespaces = world.namespaces != null;

const resolvedNamespacedTables = Object.fromEntries(
Object.entries(namespaces)
Object.entries(world.namespaces ?? {})
.map(([namespaceKey, namespace]) =>
Object.entries(namespace.tables ?? {}).map(([tableKey, table]) => {
validateTable(table, scope);
Expand All @@ -94,6 +94,9 @@ export function resolveWorld<const world extends WorldInput>(world: world): reso
systems: resolveSystems(world.systems ?? CONFIG_DEFAULTS.systems),
excludeSystems: get(world, "excludeSystems"),
modules,
internal: {
multipleNamespaces,
},
},
CONFIG_DEFAULTS,
) as never;
Expand Down
35 changes: 25 additions & 10 deletions packages/world/ts/config/v2/worldWithShorthands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,32 @@ export function resolveWorldWithShorthands<world extends WorldWithShorthandsInpu
world: world,
): resolveWorldWithShorthands<world> {
const scope = extendedScope(world);
const tables = mapObject(world.tables ?? {}, (table) => {
return isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table;
});
const namespaces = mapObject(world.namespaces ?? {}, (namespace) => ({
...namespace,
tables: mapObject(namespace.tables ?? {}, (table) => {
return isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table;
}),
}));

const fullConfig = { ...world, tables, namespaces };
const fullConfig = {
...world,
...(world.tables
? {
tables: mapObject(world.tables, (table) =>
isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table,
),
}
: null),
...(world.namespaces
Copy link
Member Author

@holic holic Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous resolveWorldWithShorthands code was always setting the namespaces key, which kept the downstream resolveWorld function from determining if we're using namespaces or not.

This new logic conditionally sets the namespaces key only if it was already used.

? {
namespaces: mapObject(world.namespaces, (namespace) => ({
...namespace,
...(namespace.tables
? {
tables: mapObject(namespace.tables, (table) =>
isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table,
),
}
: null),
})),
}
: null),
};

validateWorld(fullConfig);

return resolveWorld(fullConfig) as never;
Expand Down
Loading
Loading