From eb7a297f3e735c593159cdc9632f4cecb249e561 Mon Sep 17 00:00:00 2001 From: Serkyo Date: Sun, 28 Jun 2026 03:33:07 +0200 Subject: [PATCH] docs(workspace): replace unicode ellipsis with ascii in docs --- AGENTS.md | 14 +++++++------- docs/adr/0001-record-architecture-decisions.md | 4 ++-- docs/adr/0006-base-game-on-modding-api.md | 2 +- .../0007-declarative-content-via-modding-api.md | 2 +- docs/adr/template.md | 2 +- docs/packs.md | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fd49eda..b0aafae 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ World is procedurally generated. Voxel edge length is 0.5 m, so the player occup Documentation is layered by altitude; keep content at the layer it belongs to so no single file accretes everything. - **This file (`AGENTS.md`)**: cross-cutting engineering conventions and architecture invariants, i.e. the rules that apply regardless of which feature is being touched. There is a finite set of these, so this file should grow slowly. Subsystem-specific specs do **not** belong here. -- **[`docs/`](docs/) + Rust module docs (`//!`, `///`)**: per-subsystem technical implementation docs. How an individual system (meshing, networking, worldgen, …) is built. Prefer module docs next to the code; promote to a `docs/.md` note when the design spans multiple files. +- **[`docs/`](docs/) + Rust module docs (`//!`, `///`)**: per-subsystem technical implementation docs. How an individual system (meshing, networking, worldgen, ...) is built. Prefer module docs next to the code; promote to a `docs/.md` note when the design spans multiple files. - **[`docs/adr/`](docs/adr/)**: Architecture Decision Records capturing the *why* behind significant, hard-to-reverse choices, one append-only file per decision. See [`docs/README.md`](docs/README.md) for the full scheme and [`docs/adr/0001-record-architecture-decisions.md`](docs/adr/0001-record-architecture-decisions.md) for the practice. The canonical game-*design* specification (intent, world rules, gameplay behaviour) is maintained separately and is not part of this repository; this repo documents how that design is implemented. @@ -36,7 +36,7 @@ The game exposes a Lua modding API, and **the base game itself is built on top o This has hard implications when adding features: -- Any new gameplay primitive (a new block type, item, entity, ability, …) needs to be reachable through the Lua API, not just a Rust-only path. If you add a Rust-side concept without an API surface, you've broken the dogfooding contract. +- Any new gameplay primitive (a new block type, item, entity, ability, ...) needs to be reachable through the Lua API, not just a Rust-only path. If you add a Rust-side concept without an API surface, you've broken the dogfooding contract. - Prefer extending the API and then *using* it from the engine over adding a parallel Rust-only entry point. - Keep the API stable and discoverable, since mod authors will be reading it. Avoid leaking engine internals through it. - The API and its bindings live in the **`scripting`** crate. It owns the `mlua` dependency, the API table registration, and the mod loader. Both `client` and `server` depend on it; `shared` does **not**, since `shared` stays the lean protocol/data layer. @@ -63,7 +63,7 @@ Three distinct locations, do not mix them: Two distinct, orthogonal systems; keep them separate, do not collapse them into one "pack" concept. **Resource packs** are client-side asset overlays (textures, sounds, models, fonts, language files; no logic). **Data packs** are declarative content definitions (JSON/TOML/RON): blocks, items, recipes, loot tables, biomes, tags. -The load-bearing rule: **do not build a parallel registration system.** The data-pack loader reads the declarative files and calls the same Lua API the engine and Lua mods use, giving one source of truth (`data/blocks/stone.json` → loader → `blocks.register{ … }`). Each schema is a stable contract; version it deliberately. The decision is recorded in [ADR-0007](docs/adr/0007-declarative-content-via-modding-api.md). +The load-bearing rule: **do not build a parallel registration system.** The data-pack loader reads the declarative files and calls the same Lua API the engine and Lua mods use, giving one source of truth (`data/blocks/stone.json` → loader → `blocks.register{ ... }`). Each schema is a stable contract; version it deliberately. The decision is recorded in [ADR-0007](docs/adr/0007-declarative-content-via-modding-api.md). Full subsystem detail (load order, repo and user-data layout, resolution semantics) lives in [`docs/packs.md`](docs/packs.md). @@ -83,7 +83,7 @@ Keep commits scoped to a single concept. Do not batch multiple unrelated changes The game is **multithreaded by design**: single-threaded would not meet the perf budget for voxel meshing, worldgen, rendering, networking, and simulation running together. Code should assume multiple threads and design data ownership accordingly: - Prefer message-passing (channels: `crossbeam-channel`, `flume`, or `std::sync::mpsc`) and per-thread ownership over shared mutable state. -- When sharing is unavoidable, use the right primitive for the access pattern: `Arc>` for low-contention shared state, `Arc>` for read-heavy, atomics (`AtomicU32`, `AtomicBool`, …) for counters and flags, lock-free structures (`crossbeam`, `dashmap`) for hot paths. Avoid wrapping large hot data in a single `Mutex` "just in case", which is how you accidentally serialise the whole engine. +- When sharing is unavoidable, use the right primitive for the access pattern: `Arc>` for low-contention shared state, `Arc>` for read-heavy, atomics (`AtomicU32`, `AtomicBool`, ...) for counters and flags, lock-free structures (`crossbeam`, `dashmap`) for hot paths. Avoid wrapping large hot data in a single `Mutex` "just in case", which is how you accidentally serialise the whole engine. - Worldgen and chunk meshing are the obvious parallelism wins. A thread pool (e.g. `rayon`, or a hand-rolled one) feeding meshing/generation jobs is expected. - Vulkan command-buffer recording can be parallelised too, but Vulkan **queues** are not free-threaded: only one thread submits to a given queue at a time. Plan ownership of `vk::Queue` accordingly. - The Lua VMs (one per execution context: client, server) are **not** thread-safe in `mlua`'s default config; treat each VM as owned by a single thread, and dispatch work to/from it via channels. @@ -122,7 +122,7 @@ The game is **multithreaded by design**: single-threaded would not meet the perf ## Content IDs & namespacing -All registered content (blocks, items, recipes, biomes, entities, …) is identified by a **namespaced string** of the form `"namespace:id"`. The full rationale is in [ADR-0005](docs/adr/0005-namespaced-content-ids.md). +All registered content (blocks, items, recipes, biomes, entities, ...) is identified by a **namespaced string** of the form `"namespace:id"`. The full rationale is in [ADR-0005](docs/adr/0005-namespaced-content-ids.md). - **Engine's reserved namespace:** `core:`. All first-party content registered by the base game uses it (`"core:stone"`, `"core:iron_sword"`). Mods pick their own short namespace (`"mymod:weird_dirt"`). - **Strict form required.** A bare ID with no `:` is an **error at registration / parse time**, not silently coerced to `core:`. Same rule everywhere: engine scripts, data packs, Lua mods, recipe references, save files. No exceptions; the symmetry is the point. @@ -159,7 +159,7 @@ Format: [optional footer(s)] ``` -- **Type** (required, exactly one): `feat` (new feature), `fix` (bug fix), `refactor` (no behaviour change), `perf`, `docs`, `test`, `chore` (build/tooling/deps), `build`, `ci`. Breaking changes append `!` before the colon: `feat(scripting)!: …`. +- **Type** (required, exactly one): `feat` (new feature), `fix` (bug fix), `refactor` (no behaviour change), `perf`, `docs`, `test`, `chore` (build/tooling/deps), `build`, `ci`. Breaking changes append `!` before the colon: `feat(scripting)!: ...`. - **Scope** (required): the crate the change primarily affects, one of `client`, `server`, `renderer`, `shared`, `scripting`. For changes that genuinely span the whole workspace (e.g. workspace-level Cargo config, repo-wide `.gitattributes`), use `workspace`. For changes confined to non-Rust assets, use `assets`. Avoid omitting the scope, and avoid inventing per-commit scopes. - **Subject:** imperative mood ("add", not "added" / "adds"), lowercase, no trailing period, ≤ ~72 chars. - **Body:** keep commit messages short and simple, usually subject only, no body. The exception is `fix(...)` commits for non-trivial bugs, where a body explaining the root cause and why the fix works is valuable. Don't pad routine `feat`/`refactor`/`chore`/`docs` commits with bodies. @@ -177,7 +177,7 @@ feat(server)!: change tick rate from 20 to 30 Hz If a single commit truly touches multiple crates and can't be reasonably split, that's a signal to split it. Only fall back to `workspace` scope when the change is intrinsically workspace-wide. -**Do not add any AI assistant as a co-author on commits.** No `Co-Authored-By: …` trailers for assistants, no "Generated with …" footers. Commits are authored by the human running the work. +**Do not add any AI assistant as a co-author on commits.** No `Co-Authored-By: ...` trailers for assistants, no "Generated with ..." footers. Commits are authored by the human running the work. ## Common commands diff --git a/docs/adr/0001-record-architecture-decisions.md b/docs/adr/0001-record-architecture-decisions.md index a80e794..842269f 100644 --- a/docs/adr/0001-record-architecture-decisions.md +++ b/docs/adr/0001-record-architecture-decisions.md @@ -13,8 +13,8 @@ A durable, low-ceremony place is required to record *why* significant choices we Architecture Decision Records (ADRs), in the lightweight format popularised by Michael Nygard, are used to capture significant, hard-to-reverse decisions. -- Each ADR is a single Markdown file in `docs/adr/`, numbered sequentially (`0001-…`, `0002-…`). -- Each record carries a status (`Proposed`, `Accepted`, `Deprecated`, or `Superseded by …`) and a date. +- Each ADR is a single Markdown file in `docs/adr/`, numbered sequentially (`0001-...`, `0002-...`). +- Each record carries a status (`Proposed`, `Accepted`, `Deprecated`, or `Superseded by ...`) and a date. - Records are **append-only**: once accepted, an ADR is not edited to reflect a later change of mind. A new ADR is written instead and the old one is marked `Superseded`. - New records are started from [`template.md`](template.md). diff --git a/docs/adr/0006-base-game-on-modding-api.md b/docs/adr/0006-base-game-on-modding-api.md index 92fbf5f..1cf6980 100644 --- a/docs/adr/0006-base-game-on-modding-api.md +++ b/docs/adr/0006-base-game-on-modding-api.md @@ -11,7 +11,7 @@ The API is also exposed to two execution contexts, a client-side Lua VM and a se ## 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. +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. diff --git a/docs/adr/0007-declarative-content-via-modding-api.md b/docs/adr/0007-declarative-content-via-modding-api.md index a13d398..20e4d1c 100644 --- a/docs/adr/0007-declarative-content-via-modding-api.md +++ b/docs/adr/0007-declarative-content-via-modding-api.md @@ -11,7 +11,7 @@ This decision concerns **data packs** (declarative content). It is distinct from ## Decision -The data-pack loader reads the declarative files and **calls the same Lua API** the engine and Lua mods use. There is one registration path: `data/blocks/stone.json` → loader → `blocks.register{ id = "stone", … }`. No parallel registration system is built. The loader belongs in `scripting` (or a sibling crate if it grows). First-party content may use either JSON or Lua, whichever fits. +The data-pack loader reads the declarative files and **calls the same Lua API** the engine and Lua mods use. There is one registration path: `data/blocks/stone.json` → loader → `blocks.register{ id = "stone", ... }`. No parallel registration system is built. The loader belongs in `scripting` (or a sibling crate if it grows). First-party content may use either JSON or Lua, whichever fits. Each data-pack schema is treated as a stable contract, versioned as deliberately as the Lua API. diff --git a/docs/adr/template.md b/docs/adr/template.md index 079d0bc..44a87b7 100644 --- a/docs/adr/template.md +++ b/docs/adr/template.md @@ -9,7 +9,7 @@ The forces at play: the technical situation, the constraints, and the problem th ## Decision -The choice that was made, stated in the active, present tense ("The engine uses …", "Worldgen seeds from …"). One decision per record. +The choice that was made, stated in the active, present tense ("The engine uses ...", "Worldgen seeds from ..."). One decision per record. ## Consequences diff --git a/docs/packs.md b/docs/packs.md index df4fb98..bbcaf83 100644 --- a/docs/packs.md +++ b/docs/packs.md @@ -15,7 +15,7 @@ Declarative content definitions in JSON (or TOML/RON, TBD): blocks, items, recip No parallel registration system is built. The loader reads the declarative files and calls the same Lua API the engine and Lua mods use. One source of truth: ``` -data/blocks/stone.json → loader → blocks.register{ id = "stone", … } +data/blocks/stone.json → loader → blocks.register{ id = "stone", ... } ``` The loader belongs in `scripting` (or a sibling crate if it grows). Engine first-party content may use either JSON or Lua, whichever fits. Every data-pack schema is a stable contract, the same as the Lua API, version it deliberately. @@ -36,7 +36,7 @@ base game (assets/scripts + assets/data) ``` /assets/ data/ # base-game declarative content - blocks/ items/ recipes/ … + blocks/ items/ recipes/ ... scripts/ # base-game Lua (behavior) textures/ models/ sounds/ icons/ shaders/ # base-game assets ```