Files
hypercross 9fdce335c2 docs(skills): add game-prep skill
Lists what a game package requires and how to validate it, matching
the checks journal check performs.
2026-09-13 16:41:31 +08:00

5.7 KiB

name, description
name description
game-prep Prepare or validate a game package under games/ for this solo journaling workspace. Use when adding a new game system, porting one from games/generic/, reviewing whether a game package is complete, or checking that its rules, tables, character backgrounds, and commands are wired up correctly before starting a campaign.

Preparing a game package

A game package is a directory under games/<id>/ that holds everything true about a game before play starts: its rules, spark tables, character options, and tool scripts. Campaigns own the play state and reference a game by id from campaigns/<name>/campaign.md frontmatter (game: <id>).

Read docs/games.md for the full contract. games/generic/ is the reference implementation — copy it as a starting point.

Rule of thumb: a game is what is true before play, a campaign is what play changes. Never copy game content into a campaign; reference it.

Required contents

Path Required Purpose
package.json yes @solo/game-<id>, "type": "module", main/exports; depend on @solo/oracle if scripts use dice or tables
index.js yes default-export manifest: id, title, description, rules, commands
game.md yes authoritative rules the agent reads each session
tables/*.csv yes spark and complication tables, header min,max,text[,tags]
characters/ yes backgrounds, playbooks, starting options — the character options, not the PC
rules/ recommended longer rulebook chapters, read on demand
scripts/ optional standalone tool scripts for one-off jobs

Details that trip people up:

  • The directory name is the game id. Keep the manifest's id and the package name @solo/game-<id> in sync with it.
  • Ship a complication-themes.csv. journal oracle --complicate resolves that table name, and without it on either the campaign or the game the roll fails. There is no cross-game fallback.
  • Tables must be contiguous and non-overlapping. min/max are inclusive integers and define the die range; every integer in the table's span should be covered exactly once. Quote any text containing a comma.
  • Commands are declared in index.js as commands: { name: { description, run } } and exposed as journal <name>. Handlers receive (args, ctx) where args is { positional, flags } and ctx carries findTable plus the shared helpers.
  • Run pnpm install after adding the @solo/oracle dependency or creating a new package, so the workspace symlink exists.

Preparation workflow

  1. Copy the reference: games/generic/ → games/<id>/.
  2. Edit package.json: set name to @solo/game-<id> and a real description.
  3. Edit index.js: set id, title, description; replace or remove the example command.
  4. Write game.md: resolution, stats, tracks and conditions, character creation, and the tables the game provides.
  5. Add tables to tables/, one CSV per table, ranges contiguous.
  6. Add character options to characters/ — rollable ones as CSV, prose as markdown.
  7. Add rules/ chapters for anything too long for game.md.
  8. Add tooling: preferred path is a commands entry in index.js for anything the agent calls during play; standalone one-off scripts go in scripts/.
  9. pnpm install.
  10. Validate (below) before starting a campaign.

Validation

Run all of these. Each proves something the others do not.

Command Proves
pnpm install the @solo/oracle workspace link resolves
pnpm journal check --game <id> package.json parses and is named right, index.js loads, the rules file exists, tables parse and are contiguous, tables/ and characters/ exist
pnpm journal games the game appears in the catalog; a manifest that throws shows as ERROR:
pnpm journal game <id> rules path, table count, characters path, and the command list all resolve
pnpm journal roll <table> --game <id> each table rolls and its range resolves
pnpm journal <command> --game <id> each game command runs

journal check exits non-zero on errors. It reports:

  • errors — overlapping table ranges, CSV parse failures, invalid or missing package.json, missing game.
  • warnings — range gaps, package name mismatch, missing "type": "module", missing index.js/tables//characters/, missing rules file.

Fix every error, then work the warnings down to zero. The checks live in packages/cli/src/cli.js (checkGamePackage, checkTablesDir).

Definition of done

  • games/<id>/ exists; directory name, manifest id, and package name agree.
  • pnpm journal check --game <id> exits 0 with no errors.
  • pnpm journal games lists it without ERROR.
  • pnpm journal game <id> shows the rules path and every intended command.
  • Every table rolls cleanly and its ranges are contiguous.
  • game.md covers resolution, stats, tracks, character creation, and the game's tables.
  • characters/ holds the character options.
  • A complication table is present if the game uses --complicate.
  • pnpm journal new-campaign scratch --game <id> succeeds (then remove the scratch campaign).

Common failures

  • Overlapping ranges — e.g. rows 1-3 and 3-6 both cover 3. Error.
  • Gaps — e.g. rows 1-2 and 4-6 leave 3 uncovered. Warning.
  • Unquoted comma in a table's text shifts the columns; wrap it in quotes.
  • ERR_MODULE_NOT_FOUND: @solo/oracle — the dependency was added but pnpm install was not run.
  • Manifest id drifting from the directory name — journal game <id> still works (the directory wins), but the package is inconsistent and the docs become misleading.