6.7 KiB
Project notes for agents
Project overview
Station is a persistent-world, RPG-style station simulation inspired by Space Station 13, with singleplayer and multiplayer. It is built in Rust (edition 2024) with Bevy 0.19 (ECS), bevy_replicon + renet (networking), Rune (scripting), rsn (data files) and Tiled (maps). Project documentation: README.md.
Agent rules
- Never push changes unless explicitly told to.
- After changing files, run
cargo fmt --all. Do not override project formatting configuration or invoke a formatter directly on individual files. - Use conventional commits with the types
feat,fix,refactor,perf,test,docs,ci,buildandchore, scoped by crate or area where useful (feat(server): ...,ci(gitea): ...). Use!and aBREAKING CHANGE:footer for breaking API, save-format or protocol changes. - End commit messages with a co-author trailer appropriate to the agent and
product. For example:
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>. - Inform the user about commits and other Git changes, including commit messages.
- Commit changes after each step unless the user says not to or a
.NOCOMMITfile exists in the repository root.- Changes affecting compilation or tests may only be committed after
cargo clippy --workspace --all-targets -- -D warningsandcargo nextest run --workspacepass. - Documentation, CI, editor, and deployment configuration changes do not require code checks; validate workflow YAML syntax.
- Check the current branch before every commit.
- Changes affecting compilation or tests may only be committed after
- Commit formatting-only changes separately when formatting reformats code unrelated to the functional changes.
- Add user-visible changes to the
Unreleasedsection ofCHANGELOG.md(Keep a Changelog format).
Repository structure
crates/game_core/: shared data definitions (data.rs), ECS components, grid helpers, Tiled loader (map.rs) and network protocol (protocol.rs).crates/game_server/: authoritative simulation, Rune engine (scripting.rs), persistence, and thegame-serverdedicated server binary. Integration tests live incrates/game_server/tests/.crates/game_client/: thegamebinary: rendering, UI and input; embeds the server for singleplayer and hosting.assets/data/: item, recipe, building and skill definitions (.rsn).assets/scripts/: Rune scripts (.rn), referenced as"module::function".assets/maps/,assets/tilesets/,assets/sprites/: Tiled maps and art.xtask/: project automation (cargo xtask packbuilds and archives the client and server intodist/).tools/gen_placeholder_assets.py: regenerates placeholder art and the example map (generated output is committed)..github/workflows/,.gitea/workflows/: CI for GitHub and Gitea..config/nextest.toml: test runner configuration.
Keep README.md (run instructions, controls, data formats, script API, Tiled
conventions) in sync with API, configuration, and behavior changes.
Architecture and constraints
- The server is authoritative. Clients only send protocol events (
Login,SetMoveDir,Interact,Craft, ...) and render replicated state; never mutate game state from client code. Singleplayer runs the same server plugin in-process, so behavior must not depend on the mode. - Game rules belong in data files or Rune scripts where possible; Rust code provides generic mechanics. Data references and script hooks are validated at load time.
- Protocol registration order in
game_core::protocolmust match between client and server; changing it breaks compatibility. - Rune scripts stage changes in
ScriptState; they are applied after the script returns, and a failing script has no effect. Ctx methods need#[rune::function(keep)]; script-facing numbers are integers. - Save files (
persistence.rs,SAVE_VERSION) are the source of truth for an existing world; the Tiled map only seeds new worlds. Changing saved types requires a version bump or a compatible migration. - Characters are identified by name only (no authentication); renet uses unsecure authentication. Do not treat client input as trusted.
- Replicon builds its systems in
Plugin::finish; headless tests must callapp.finish(); app.cleanup();and update the app once more per round trip. - Release builds of the client on Windows use the
windowssubsystem (no console output).
Commands
cargo fmt --all
cargo build --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo nextest run --workspace
Run binaries with cargo run (client; --host, --connect) and
cargo run -p game_server --bin game-server. Build a distributable archive
with cargo xtask pack (add --target x86_64-pc-windows-gnu to cross-build
for Windows; needs MinGW). Files shipped next to the binaries are listed in
EXTRA_FILES in xtask/src/main.rs. Running the client requires a Vulkan or
GL capable GPU or a software driver such as lavapipe.
Conventions
- Write comments for why, not what: invariants, non-obvious constraints, workarounds (with the reason or a link), and units/timebases where the type doesn't say. Never restate what the code does.
- Before committing, review every comment in your diff (
git diff): delete those that restate the code or describe the change itself (e.g. "now uses X instead of Y"; that belongs in the commit message), and shorten the rest to one line where possible. - Comment only code that needs clarification; keep comments short.
- Follow the repository's formatting, lint, error-handling, logging, and dependency-management conventions.
- Prefer existing helpers and patterns; keep changes focused and surface failures explicitly.
- Preserve existing line endings when editing files that use non-default line endings.
- Do not add tests in locations the project's normal test commands do not discover.
Code reviews
For reviews of commits, branches, diffs, or specific files, report every finding as an entry in a list with this shape:
- Location:
file:line(use a range such asfile:120-146when the finding spans several lines) - Category: one of
Blocking,FYI, orNit(use another category, such asQuestion, only when none of those fit) - Comment: the concrete issue or risk and, when claiming a defect, its failure scenario rather than only an abstract concern
Order findings by severity, with Blocking first. Use Blocking for defects,
unbounded resource use, or policy violations that must change before merge;
use FYI for design consequences and risks worth a conscious decision; use
Nit for style and cleanliness. Verify findings against the code and run the
relevant lint and test commands before reporting them. Say when a finding is a
possibility rather than a confirmed defect.