38 lines
1.3 KiB
TypeScript
38 lines
1.3 KiB
TypeScript
// imports mods' worldgen scripts and collects what they register. used by client chunk workers and the game server
|
|
import type { WorldgenContext } from "$/common/mod_api/worldgen.ts";
|
|
import type { OreJson } from "$/common/mod_data.ts";
|
|
import type { WorldgenSetup } from "./generation.ts";
|
|
import { ModLoadError } from "./mod_loader.ts";
|
|
|
|
export async function load_worldgen(scripts: { mod: string; url: string }[], ores: OreJson[]): Promise<WorldgenSetup> {
|
|
const setup: WorldgenSetup = { ores, features: [] };
|
|
|
|
for (const { mod, url } of scripts) {
|
|
const ctx: WorldgenContext = {
|
|
register_feature(id, generate) {
|
|
if (!id.startsWith(`${mod}:`)) {
|
|
throw new ModLoadError(mod, `feature ${id} must be in the namespace "${mod}"`);
|
|
}
|
|
if (setup.features.some((f) => f.id === id)) {
|
|
throw new ModLoadError(mod, `feature ${id} is registered twice`);
|
|
}
|
|
setup.features.push({ id, generate });
|
|
},
|
|
register_terrain(id) {
|
|
throw new ModLoadError(
|
|
mod,
|
|
`can't register terrain ${id}: the base terrain is still built into the engine (phase 3 in MODS.md)`,
|
|
);
|
|
},
|
|
};
|
|
|
|
const module = await import(url);
|
|
if (typeof module.setup !== "function") {
|
|
throw new ModLoadError(mod, "the worldgen script doesn't export a setup function");
|
|
}
|
|
await module.setup(ctx);
|
|
}
|
|
|
|
return setup;
|
|
}
|