synvael/AGENTS.md

110 lines
5.1 KiB
Markdown

# 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.
- `<user-data-dir>/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 <crate>`
- 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 <crate>`
## 🚀 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): ...`).