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
+19 -11
View File
@@ -79,7 +79,8 @@ refers to exists (and that it depends on the mods those come from), and typechec
`common/mod_api/`, which scripts import as `bworld/server`, `bworld/client` and `bworld/worldgen`. Folders in `mods/`
starting with `_` or `.` are ignored.
The game can't load mods yet; see the [Implementation plan](#implementation-plan).
`deno task build` builds every mod in `mods/` and fails if any has errors; `deno task server` then loads them. What
works so far is listed in the [Implementation plan](#implementation-plan).
## Mod layout
@@ -1039,8 +1040,8 @@ Worlds saved before the move must load afterwards with nothing changed:
Each phase ends with every test passing and the game playable.
**Phase 0: safety net.** Do this first, before any other mod work. Started: `deno task test` runs `tests/`, which so far
checks `mods/bworld` against the game and the mod tools.
**Phase 0: safety net.** Do this first, before any other mod work. Started: `deno task test` runs `tests/`, which covers
loading mods (the base game and the template), their scripts and worldgen, saves, and the mod tools.
- Move the test scripts used while building steps 1–3 into the repo as `deno test` files under `tests/`: server logic
(breaking, placing, crafting, chest, furnace, saves), client and server terrain agreement, click prediction, and the
@@ -1051,13 +1052,13 @@ checks `mods/bworld` against the game and the mod tools.
- Save a world from the current code with chests, a running furnace and some player inventories as
`tests/fixtures/world_v2.json`, with a test that loads it and checks everything is where it was.
**Phase 1: data** (after steps 4 and 5).
**Phase 1: data** (after steps 4 and 5). _Done._
- Create `mods/bworld` with its manifest and credits, and move the 62 textures there. Rename the breaking cracks to
`engine:break_0`–`8` and the fallback to `engine:missing`.
- Generate the block, item and recipe JSON with a script that reads the current registries, instead of writing it by
hand. Hand-copying 18 blocks' fields is how typos get in. Done: `deno task export-bworld` writes them, and
`tests/bworld_mod_test.ts` fails if they drift from the game.
hand. Hand-copying 18 blocks' fields is how typos get in. They were generated this way, checked equal to the
TypeScript definitions, and those were then deleted.
- The loader registers the recipes and `server/game/crafting.ts` matches against them. Behaviors stay in
`server/game/blocks.ts`, still keyed by block id, for now.
- Delete `common/blocks/` and `common/items/`.
@@ -1106,7 +1107,8 @@ checks `mods/bworld` against the game and the mod tools.
## Implementation plan
Steps 1–3 are done; the mod steps (4 onwards) aren't started. Each step keeps the game working:
Steps 1–4 are done and 5, 6 and 9 mostly, enough that a mod made from the template loads and runs. Each step keeps the
game working:
1. **Game server core.** Move `client/generation.ts` to `common/` (it already only needs constants and the rng package)
and have the server generate terrain. Move world state, chunks, tile data and player inventories into a game server
@@ -1119,16 +1121,22 @@ Steps 1–3 are done; the mod steps (4 onwards) aren't started. Each step keeps
reach a server, and show a connection error instead.
4. **Mod loader and build.** Discover mods, check manifests, sort by dependencies, turn JSON into registry entries,
build the combined atlas (textures are currently all named `bworld:<file>`), bundle scripts per side, and write
hashed output to `build/mods/` and `server_mods/`.
hashed output to `build/mods/` and `server_mods/`. _Done._
5. **Delivery.** Split `welcome` into `welcome` / `ready` / `join`. Clients download, verify and run mods before
joining. Add the confirm screen for cross-origin servers and CORS headers on the server.
joining. Add the confirm screen for cross-origin servers and CORS headers on the server. _Partly done:_ `welcome`
lists the mods and clients download and run them before creating the world, but the server doesn't wait for `ready`
(its messages just queue up meanwhile), hashes aren't checked, and there's no confirm screen or CORS yet.
6. **Server scripts.** Components, events, commands, system, storage and `ctx.recipes`. Move `FURNACE_RECIPES` and
`FUEL_VALUES` into the recipe registry.
`FUEL_VALUES` into the recipe registry. _Mostly done_ (`server/game/mod_runtime.ts`). Not yet: `on_click` (clients
don't report left clicks on blocks), item `on_use` (there's no item use action), `world.get_state` / `set_state`
(block states aren't synced or saved), and `Container.on_change`. `ctx.containers`, `ctx.ui` and `ctx.net` throw
until steps 7 and 8, and so do the client's `ctx.ui`, `ctx.hud`, `ctx.input` and `ctx.net`.
7. **GUIs.** Forms, then container screens (rebuild chest and furnace with them), then custom screens, the `Graphics`
API (built on the existing renderer and debug UI widgets) and the HUD.
8. **Mod channels** and keybinds.
9. **Worldgen mods.** Worldgen URLs and mod ores go into the chunk worker `init` message. Workers must finish importing
before generating anything.
before generating anything. _Done for features and ores._ `register_terrain` throws until phase 3 moves the base
terrain out of the engine.
Steps 1–3 are engine work every multiplayer feature needs, with or without mods. Mods could start with data only (step 4
plus data in step 5) before scripts exist.