Language and style
- English only — code, comments, commits, docs.
- Framework code (everything outside
Gatherer/) is structured with---@annotations andvolvox.*namespacing — match it. - Gatherer core files are predominantly globals, mixed indentation, and terse names (
scan,avoid,Fishi,Spore). Copy the indentation character and block style of the nearest enclosing function in the same file. Do not reformat existing lines. - New Gatherer-internal helpers are named
Gatherer<Thing>.
Commits
Use Conventional Commits with a scope:Changelog
CHANGELOG.md follows Keep a Changelog 1.1.0 and is updated for every change. Entries stay under ## [Unreleased] until a release is explicitly cut, using the standard categories: Added, Changed, Deprecated, Removed, Fixed, Security.
Every released version uses the heading ## [X.Y.Z] — Release Name - YYYY-MM-DD. Choose a short, unique gathering pun tied to the release’s standout theme.
Releases
Releases are cut withscripts/changelog-release.sh:
Determine the bump level
Scan
[Unreleased] entries: any BREAKING: / [breaking] → major; else any ### Added entries → minor; else → patch. An explicitly requested level or version wins.Run the script
Verification checklist
Since there is no runtime harness, every change must:- Pass the static tooling:
selene . && stylua --check . && biome check . - Not break the load order (
loadorder.json) — a file may only reference symbols defined by files above it. - Preserve
volvox.*contracts. - For logic changes: identify the specific in-game trigger (bot state, object type, or user action) and the observable outcome (log message, state transition) that confirms the change works.
.png?fit=max&auto=format&n=yZatCT6YQ7S22QWv&q=85&s=bb502db827d4362d1268445c3b70d21d)