← Back to Nakama · project planning pack
See how it helps
Backend implementation
Implements server-side game rules in small, testable steps. Coordinates validation, permissions and related data changes so interrupted or simultaneous requests leave player state consistent.
backend-implementation
Agents using this skill
When is it useful?
Use when server behavior must enforce business rules across validation, transactions and concurrent requests.
What does it help you do?
- Implements small complete slices with behavior tests before and after changes.
- Places invariants and authorization in existing layers with explicit valid state transitions.
- Keeps related writes consistent and makes external failures visible and recoverable.
Try asking this
Implement claiming a completed daily quest in the existing game backend. Validate completion on the server and update the reward and claim record together. Send two simultaneous claims and interrupt one request: the player must receive the reward once, with a clear response for the repeated attempt.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Backend Implementation
Work in thin slices
- Cycle: implement the smallest complete piece, test it, verify (tests, build, typecheck, lint with the repo's commands), then take the next slice. Never write more than about 100 lines without running the tests.
- Prefer vertical slices (one working path through the layers). With a parallel front end, build against the agreed contract first. Do the riskiest piece first.
- Simplicity first: the simplest thing that works; three similar lines beat a premature abstraction; no code for hypothetical requirements.
- After every slice the project builds and the existing tests pass. Unfinished features hide behind a flag; new behavior defaults to off or to the safe option.
- Keep each change revertible on its own: additive where possible; do not delete and replace in one step; migrations come with their rollback.
Scope discipline
- Touch only what the task needs: no cleanup of adjacent code, no reformatting, no import shuffles, no features the spec does not ask for.
- Put what you notice outside the scope in the report ("noticed, not touched"), not in the diff.
Test as you go
- Red before green: for new behavior or a bug, first a test that fails for the right reason, then only enough code to pass it. One test, one minimal implementation, repeat; never all the tests first.
- Test through public interfaces (endpoint, service method, command), not private internals; a refactor must not break the tests.
- Expected values come from the spec or a worked example, never recomputed the way the code computes them.
Rules before code
- State the business rules and invariants the change must keep (a paid order has a payment, a balance never goes negative). Enforce each in exactly one place, in the layer the repo uses for business logic, not in controllers or scattered queries.
- Model states explicitly: allow only the valid transitions and reject the others with a clear error.
- Validate input where it enters (request, message, job payload) and turn it into typed values; back the rules with database constraints; check authorization on the server for the specific record.
Errors are never swallowed
- No empty catch, no catch that logs and carries on, no fallback value that hides a failure. A failed flow never reports success.
- Catch only what you can handle; let the rest reach the boundary that turns it into a response, with the repo's error types and the right status (validation, not found, conflict, forbidden, internal).
- Keep the cause when rethrowing. Log once, at the boundary, with context and without secrets. Release locks, close handles and roll back on every path.
Consistency
- Writes that must succeed together share one short transaction, with no network calls inside.
- Guard against lost updates and double processing: unique constraints, conditional updates (WHERE version = ?), row locks or idempotency keys, whichever the repo uses.
- Side effects outside the database (emails, payments, webhooks, queue messages) run after commit or through an outbox.
- External calls have a timeout; decide what state remains when step two of three fails, and make it recoverable.
Merge conflicts
- Read both sides' intent from their commits and tasks. Keep both behaviors where they do not contradict; never drop one side to make it compile. Run both sides' tests afterwards.
Before you finish
- Each slice built and tested; the build and the full suite pass.
- The diff holds only what the task needs.
- Invariants enforced in one place and backed by constraints.
- No swallowed errors; failures reach the caller with the right status.
- Transactions, concurrency and side effects after commit handled.
- Rules, error paths and edge cases have tests.
Included files 2
LICENSE.txtSKILL.md
