Synvael/docs/adr/0006-base-game-on-modding-api.md

28 lines
2.2 KiB
Markdown

# 0006. Base game built on the modding API
- **Status:** Accepted
- **Date:** 2026-06-27
## Context
The engine exposes a Lua modding API. A modding API can be treated as a bolt-on layer over a separate, privileged engine path, or the engine's own content can be defined through the same API that mod authors use. The former tends to let the engine drift ahead of the API, leaving mod authors with second-class capabilities and no working reference.
The API is also exposed to two execution contexts — a client-side Lua VM and a server-side Lua VM — with different trust levels. Authoritative operations (world mutation, combat resolution) must not be invocable from the client VM.
## Decision
The base game is built on top of the modding API; the shipped content (blocks, items, entities, recipes, …) is defined through the same API mod authors use, so it doubles as reference material.
- Any new gameplay primitive must be reachable through the Lua API, not only through a Rust-internal path. Adding a Rust-side concept with no API surface breaks the dogfooding contract.
- The API and its bindings live in the `scripting` crate, which owns the `mlua` dependency, the API table registration, and the mod loader. Both `client` and `server` depend on it; `shared` does not.
- Authoritative APIs are defined once but **gated by execution context**: the client VM is restricted to read-only / UI / effects, while the server VM holds authority. One API surface, two contexts.
- `scripting` wraps `shared` types in newtypes rather than implementing `UserData` for them in `shared`, keeping the protocol/data crate free of `mlua`.
## Consequences
- Mod authors can read first-party content as a faithful example of what the API allows, because it uses no privileged path they lack.
- The API must stay stable and discoverable, since it is both the engine's and the modder's surface; engine internals must not leak through it.
- The client/server trust boundary is enforced at the API layer rather than re-checked ad hoc.
- A feature cannot be "added to the engine" and exposed to mods later as an afterthought — the API surface is part of the definition of done.
- Declarative content loading follows the same single-path rule; see [ADR-0007](0007-declarative-content-via-modding-api.md).