Implement main game as a mod

This commit is contained in:
2026-09-24 23:49:34 -03:00
parent bb42dd662e
commit 6458bc0440
131 changed files with 1810 additions and 786 deletions
+30 -1
View File
@@ -1,5 +1,5 @@
// the json formats from MODS.md, and converting them to and from the engine's registry entries.
// the mod loader uses the from_json direction, tools/export_bworld_mod.ts the other one
// the mod loader uses the from_json direction, tests use both to check nothing is lost
import type { BlockRegistry, BlockStateDefinition, ItemRegistry } from "./everything_registry.ts";
export const FORMAT_VERSION = 1;
@@ -37,6 +37,15 @@ export interface BlockJson {
components?: Record<string, unknown>;
}
export interface OreJson {
id: string;
replaces: string;
min_y: number;
max_y: number;
scale: number;
threshold: number;
}
export interface ItemJson {
id: string;
texture: string;
@@ -82,6 +91,7 @@ export function block_to_json(block: BlockRegistry, has_item: boolean): BlockJso
if (block.interactive) json.interactive = true;
if (block.replaceable) json.replaceable = true;
if (block.states) json.states = block.states;
if (block.components) json.components = block.components;
return json;
}
@@ -102,6 +112,7 @@ export function block_from_json(json: BlockJson): { block: BlockRegistry; has_it
if (json.interactive) block.interactive = true;
if (json.replaceable) block.replaceable = true;
if (json.states) block.states = json.states;
if (json.components) block.components = json.components;
return { block, has_item: json.item ?? true };
}
@@ -114,6 +125,9 @@ export function item_to_json(id: string, item: ItemRegistry): ItemJson {
const json: ItemJson = { id, texture: item.texture_id };
if (item.tool_type !== undefined) json.tool = item.tool_type;
if (item.block_id !== undefined) json.places = item.block_id;
if (item.max_stack !== undefined) json.max_stack = item.max_stack;
if (item.lore !== undefined) json.lore = item.lore;
if (item.components) json.components = item.components;
return json;
}
@@ -121,6 +135,9 @@ export function item_from_json(json: ItemJson): ItemRegistry {
const item: ItemRegistry = { texture_id: json.texture };
if (json.tool !== undefined) item.tool_type = json.tool;
if (json.places !== undefined) item.block_id = json.places;
if (json.max_stack !== undefined) item.max_stack = json.max_stack;
if (json.lore !== undefined) item.lore = json.lore;
if (json.components) item.components = json.components;
return item;
}
@@ -303,6 +320,18 @@ export function validate_recipe(json: unknown): Problems {
return problems;
}
export function validate_ore(json: unknown): Problems {
if (!is_object(json)) return ["ore must be an object"];
const problems = [...validate_id(json.id, "id"), ...validate_id(json.replaces, "replaces")];
for (const key of ["min_y", "max_y", "scale", "threshold"]) {
if (typeof json[key] !== "number") problems.push(`${key} must be a number`);
}
if (typeof json.min_y === "number" && typeof json.max_y === "number" && json.min_y > json.max_y) {
problems.push("min_y must not be above max_y");
}
return problems;
}
function validate_id(value: unknown, field: string): Problems {
return typeof value === "string" && ID_PATTERN.test(value) ? [] : [`${field} must be an id like "my_mod:thing"`];
}