Server authority
This commit is contained in:
@@ -4,7 +4,7 @@ Status: **draft, format_version 1**. Nothing here is implemented yet, see [Imple
|
||||
|
||||
Mods add blocks, items, textures, recipes, world generation, game logic and GUIs to bworld. A mod is installed **on the
|
||||
server**. Players who join download its client code, data and textures from the server automatically, so they don't
|
||||
install anything themselves. Single player works the same way, with a server running inside the browser.
|
||||
install anything themselves. bworld is always played on a server; there is no single player mode.
|
||||
|
||||
This borrows from Minecraft Bedrock add-ons: data lives in JSON, blocks get behavior from named custom components, and
|
||||
scripts use before/after events. Bedrock servers also push resource packs to joining players, and their server scripts
|
||||
@@ -27,7 +27,6 @@ too, since the client is already a web page.
|
||||
- [Mod channels](#mod-channels)
|
||||
- [World generation](#world-generation)
|
||||
- [Delivery to clients](#delivery-to-clients)
|
||||
- [Single player](#single-player)
|
||||
- [Security](#security)
|
||||
- [Example mod](#example-mod)
|
||||
- [Implementation plan](#implementation-plan)
|
||||
@@ -256,9 +255,8 @@ export function setup(ctx: ServerContext) {
|
||||
}
|
||||
```
|
||||
|
||||
Server scripts run in the game server worker. They get the mod API and standard JavaScript, and **no Deno, Node or DOM
|
||||
APIs**. That lets the same script run on a dedicated server and in the browser for [single player](#single-player). They
|
||||
have no file or network access; persistent state goes through `ctx.storage`.
|
||||
Server scripts run in the game server worker with **no Deno permissions** (see [Security](#security)). They get the mod
|
||||
API and standard JavaScript, but no file, network or subprocess access; persistent state goes through `ctx.storage`.
|
||||
|
||||
```ts
|
||||
interface ServerContext {
|
||||
@@ -750,20 +748,6 @@ client server
|
||||
- The `protocol` in `hello` is the game's protocol version. A mismatch is rejected before any mod code is downloaded.
|
||||
- Leaving a server reloads the page, so one server's mod code never stays loaded while playing on another.
|
||||
|
||||
## Single player
|
||||
|
||||
Single player runs the same game server inside the browser, like Minecraft's integrated server:
|
||||
|
||||
- The game server core (world, inventories, tile data, mod server scripts) is written against a small host interface for
|
||||
**transport** and **storage**, with no Deno or DOM APIs.
|
||||
- On a dedicated server, the host is `server/main.ts`: WebSocket transport, files for storage. The core runs in a Deno
|
||||
worker.
|
||||
- In single player, the host is the page: `postMessage` transport, IndexedDB for storage. The core runs in a web worker,
|
||||
and `server.js` bundles are loaded from `server_mods/`, which the local build serves only to this page.
|
||||
|
||||
The client uses the same protocol either way, so a mod written and tested in single player behaves the same on a
|
||||
dedicated server.
|
||||
|
||||
## Security
|
||||
|
||||
**Client scripts.** Mod client code runs in the game page with the page's full access. How much that matters depends on
|
||||
@@ -900,16 +884,17 @@ class SmelterStats implements ModScreen {
|
||||
|
||||
## Implementation plan
|
||||
|
||||
None of this exists yet. Each step keeps the game working:
|
||||
Steps 1–3 are done; the mod steps (4 onwards) aren't started. 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. Pull world state, chunks, tile data and player inventories into an
|
||||
environment-free module behind a transport and storage interface. Run it in a Deno worker from `server/main.ts`.
|
||||
and have the server generate terrain. Move world state, chunks, tile data and player inventories into a game server
|
||||
module that runs in a Deno worker, with `server/main.ts` handling HTTP, WebSockets and files.
|
||||
2. **Server authority.** Change the protocol from "here's the block I changed" to intents (`break_block`, `place_block`,
|
||||
`interact`, `select_slot`, `container_click`). The client keeps showing breaks and places immediately and accepts
|
||||
corrections. Move inventories, drops and `/give` to the server. Replace `GuiChest` / `GuiFurnace` with server-synced
|
||||
containers.
|
||||
3. **Integrated server.** Run the same core in a web worker for single player, with IndexedDB storage.
|
||||
3. **Server only.** Remove the offline fallback in `client/main.ts`, which currently starts a local game when it can't
|
||||
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/`.
|
||||
|
||||
Reference in New Issue
Block a user