# AGENTS.md **CRITICAL:** This file contains the engineering context for AI coding agents. ## 🚨 Absolute Rules (Never Break These) / Do Not - **DO NOT** bypass the Lua scripting layer for gameplay logic. - **DO NOT** use `unwrap()` or `expect()` outside `main` or tests. - **DO NOT** use `println!`; use `tracing`. - **DO NOT** introduce non-deterministic logic into worldgen (no `thread_rng`, no `HashMap` iteration). - **DO NOT** build parallel registration systems or duplicate registries. ## 📖 What to Read - **Read `AGENTS.md` (this file)** first for every task. - **Read `DEVELOPMENT.md`** before making any architectural or cross-cutting changes. - **Read subsystem docs (`docs/` and rustdoc)** only for the specific crates you are modifying. ## ✅ Before Changing Code - Does this require updates to documentation or ADRs (`docs/adr/`)? - Which crate does this belong to? (Maintain strict boundaries). - Is this a new gameplay feature? If so, it must be exposed via the Lua API. ## 🛠️ Modification Priorities 1. **Implement the feature in Lua** if possible, using existing APIs. 2. **Extend the Lua API** if it lacks the required capability. 3. **Modify Rust internals** only as a last resort to support the Lua API. Avoid bypassing the scripting layer entirely for gameplay features. ## 🏗️ Code Style & Edits - Prefer modifying existing systems over creating new abstractions. - Avoid duplicate registries, parallel APIs, unnecessary traits, and premature generic abstractions. - Keep changes local to the relevant module unless the architecture requires otherwise. ## ❓ When Unsure If an implementation conflicts with these rules, **prefer preserving the architecture over minimizing code changes.** ## 📦 Architectural Dependency Rules - `shared` stays lean and dependency-light (no `mlua`, no rendering). - `scripting` depends on `shared`, but `shared` does **not** depend on `scripting`. - `client` and `server` depend on `shared`, `scripting`, and `net`. - `client` depends on `renderer`, but `server` does not. - **Do not** put simulation logic in `client`. ## 🔍 File Location Hints - `/assets/scripts/`: Shipped base game Lua scripts. - `/mods/`: In-repo example mods/test fixtures. - `/mods/`: Player-installed mods (resolved at runtime). - `crates/client/`: Windowing, input, presentation. - `crates/server/`: Authoritative simulation. - `crates/shared/`: Core types, network protocols. - `crates/scripting/`: Lua API bindings. - `crates/renderer/`: Vulkan graphics. - `crates/net/`: QUIC networking. ## ⚙️ Basic Verification Commands - Check compilation: `cargo check -p ` - Lint code: `cargo clippy --all-targets --all-features -- -D warnings` - Format Rust: `cargo fmt --all -- --check` - Format Lua: `stylua .` and `selene .` - Run tests: `cargo test -p ` ## 🚀 Quick Start Task Checklist - [ ] Review "What to Read" and "Before Changing Code". - [ ] Check modification priorities (Lua vs Rust). - [ ] Make edits following code style guidelines. - [ ] Run basic verification commands. - [ ] Commit using Conventional Commits. --- ### Additional Subsystem Context **Concurrency & State** - **Multithreaded:** Prefer message-passing and per-thread ownership over shared mutable state. Avoid large `Mutex` wrappers. - **Vulkan queues:** Not free-threaded. - **Lua VMs:** Not thread-safe. Treat each VM as owned by a single thread. **Determinism** - **Worldgen:** Strictly seed-deterministic. Use fixed RNG algorithms (`wyrand`, `xoshiro`). Never use `rand::thread_rng()`. Do not rely on `HashMap` iteration order (use `BTreeMap` or `IndexMap`). - **Simulation:** Server-authoritative but not lockstep. Platform-specific math and floats are permitted outside of worldgen. **Logging & Error Handling** - **Logging:** Use `tracing` and spans (`#[tracing::instrument]`). No `println!`. - **Libraries (`shared`, `renderer`, `scripting`):** Use `thiserror`. - **Binaries (`client`, `server`):** Use `anyhow`. **Testing Expectations** - Test pure algorithmic logic, correctness traps (e.g. integer overflow, div_euclid), and determinism (worldgen). - I/O and GPU code are tested via integration/visual verification. - Ensure new tests run successfully and do not break existing ones. **Linting** - The workspace uses strict lints (including banning `unwrap`, `expect`, `print`). - Prefer `#[expect(...)]` over `#[allow(...)]`. Suppress narrowly and justify non-obvious suppressions. Never suppress `correctness` lints. **Documentation Style** - Formal, objective tone. No "we" or "you". - All public/internal struct fields need `///` docs. - Functions require `# Errors`, `# Panics`, and `# Safety` sections in that order. **Branching Strategy** - **Development branch:** `dev`. - **Releases branch:** `main`. - **Large features:** Feature branch off `dev` (e.g., `feat/new-worldgen`). **General Coding Standards** - **Content IDs:** Strict `"namespace:id"` format (e.g. `"core:stone"`). Interned to handles at runtime. - **Coordinate system:** +Y up, right-handed. 1 unit = 1 block (0.5m). - **Paths:** Linux/Windows only. Use `std::path::Path` and `directories` crate. No hard-coded `/home`. - **Commits:** Conventional Commits with crate scope (e.g., `feat(scripting): ...`).