80 lines
5.3 KiB
Markdown
80 lines
5.3 KiB
Markdown
# The Settled Reach
|
|
|
|
A top-down immersive sim — occlusion-based detective game with combat elements, set in an original science fiction universe. Single-character perspective, asymmetric information as core mechanic, Rimworld-style storyteller. Godot 4 client + Rust/bevy_ecs simulation server via subprocess/IPC.
|
|
|
|
**Official Title:** The Settled Reach
|
|
**Repository name:** settled-reach
|
|
**Version source of truth:** `project.yaml` (root `version` field, scheme: `0.1.{sprint_number}`)
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
client/ # Godot 4 client
|
|
server/ # Rust/bevy_ecs simulation server
|
|
tooling/ # Build tools, scripts, asset pipelines
|
|
tests/ # Integration and end-to-end tests
|
|
docs/ # Architecture, design, briefings, sprints, workshops
|
|
db/ # Schema + seed data (connectors moved to tooling/db/)
|
|
.claude/ # Agents, skills, rules
|
|
decisions/ # Decision domain files (D-NNN confirmed, Q-NNN open, R-NNN rejected)
|
|
```
|
|
|
|
Full annotated tree: `.claude/rules/project-structure.md`
|
|
|
|
## DevOps
|
|
|
|
See [docs/DEVOPS.md](docs/DEVOPS.md) for build, test, lint, and CI procedures. All development operations go through the top-level `Makefile` — run `make` for a summary of targets.
|
|
|
|
## Agent Instructions
|
|
|
|
### Team boundaries
|
|
|
|
**Your team identity is `$WORKTREE_TEAM`.** All work must stay within the current working directory.
|
|
|
|
- All file paths are relative to the current working directory (e.g. `server/src/bridge/types.rs`).
|
|
- **Do NOT navigate to parent or sibling directories** (`../`, `../client/`, etc.) unless explicitly instructed. Do NOT use absolute paths to reach other team directories.
|
|
- **Do NOT write auto-memory files for other teams.** If `$WORKTREE_TEAM` is `server`, do not write to memory paths containing `client`, `main`, etc.
|
|
- For context: each team has its own directory via git worktrees, sharing a parent directory (`settled-reach/`). The `.git` file points to a shared git directory — do not follow it to determine your working root.
|
|
- **Exception — stale git lock files:** If a `git` command fails with `index.lock: File exists`, you may remove the lock file for **your own team only** (e.g. `main/.git/worktrees/$WORKTREE_TEAM/index.lock`). Never touch lock files belonging to other teams.
|
|
- **Never chain git commands** in a single Bash call (e.g. `git add ... && git commit ...`). The shared `.git` directory means concurrent index access from the same terminal creates `index.lock` collisions. Always run `git add` and `git commit` as **separate sequential Bash calls**.
|
|
|
|
### Database
|
|
|
|
The ticketing database (`settledreach.db`) lives in the **parent directory** shared across all worktrees — it is not tracked in git. A backup is committed to `docs/backups/settledreach.db.backup` via main only.
|
|
|
|
### Before starting work
|
|
1. Read your sprint briefing at `docs/sprints/sprint-N/{team}.md` for current tasks
|
|
2. Use `tooling/db/ticket show <id>` for full ticket details
|
|
3. Read the relevant `decisions/*.md` domain file(s) referenced in the briefing
|
|
4. Background context: `docs/briefings/{your-name}.md`, `docs/discussions/`
|
|
|
|
### CLI tools
|
|
|
|
**Prefer CLI wrappers over raw SQL.** Never use the `sqlite3` CLI — it crashes in Claude Code (std::bad_alloc). Use the wrapper scripts instead.
|
|
|
|
| Tool | Command | Full reference |
|
|
|------|---------|----------------|
|
|
| Tickets | `tooling/db/ticket list`, `show`, `create`, `assign` | `/ticket` skill |
|
|
| Sprints | `tooling/db/sprint status`, `start-work`, `prepare` | `/sprint-start` skill |
|
|
| SQL queries | `tooling/db/sqlite-query "SELECT ..."` | — |
|
|
| SQL writes | `tooling/db/sqlite-exec "UPDATE ..."` | — |
|
|
| Decisions | `tooling/db/decision next`, `claim`, `check-dupes` | — |
|
|
| Doc search | `tooling/db/qdrant-search "query"` | `/docs-search` skill |
|
|
| Doc index | `tooling/db/qdrant-index path/to/file.md` | `/docs-search` skill |
|
|
|
|
### Testing preferences
|
|
|
|
- **Prefer live Gauntlet testing over mocks.** For visual tests and rendering verification, use the full client/server pipeline (`--test-mode` + `SR_LIVE=1`) instead of TestHarness mocks. The Gauntlet test world produces production-identical data. Mocks can mask rendering bugs by taking different code paths.
|
|
- **Gauntlet rooms are immutable.** Never modify existing rooms — new systems get new rooms. This ensures StableId determinism and fixture stability.
|
|
- Three test tiers: (1) Live server — highest fidelity, (2) MessagePack replay via `Protocol.decode_snapshot()` — for unreachable rooms, (3) TestHarness mock — for UI-only tests where fog data doesn't matter.
|
|
- `make fixtures-gauntlet` regenerates real server snapshot fixtures from the Gauntlet world.
|
|
|
|
### File conventions
|
|
- Decisions: domain files in `decisions/` (see `decisions/README.md` for index)
|
|
- Decision IDs: `D-NNN` (confirmed), `Q-NNN` (open questions), `R-NNN` (rejected)
|
|
- **Claim IDs before writing:** `tooling/db/decision claim D <domain> "title"` — prevents ID collisions across worktrees
|
|
- Diagrams: `.d2` source + `.png` renders in `docs/diagrams/{category}/`. Create or update diagrams via `/d2-diagram` when D-records are added or modified.
|
|
- Discussion rounds: numbered sequentially, archived to `docs/discussions/` when complete
|
|
- Briefings: one per agent, updated after decision-producing rounds
|
|
- Tickets: managed via `tooling/db/ticket` CLI or `/ticket` skill
|