@game-hub/game-spades
v0.1.1
Published
Spades for Game Hub — the classic 52-card partnership trick-taking game with per-player bids, nil, blind nil and sandbagging. Four subpath exports: ./engine (pure rules), ./module (backend GameModule seam), ./client (UI GameClient seam), ./bot (AI).
Maintainers
Readme
@game-hub/game-spades
Spades for Game Hub — the classic 52-card partnership bidding game: call your tricks, make them exactly, and try not to collect the bags that cost you a hundred points.
- 4 players, in two fixed partnerships (seats opposite each other).
- 52 cards, thirteen each. Spades are always trump.
- First past 500 (or 200, if the table wants a short game).
Game 9 on the hub, and the second to use table options (kernel 1.5.0).
The rules are in this repo
⚠️ Spades is a traditional game with no published, copyrighted rulebook, so there is no page to cite.
ROADMAP.md §1 is the citable spec — engine code cites ROADMAP §1 exactly where
another game's code would cite a rulebook page — and every gap the source leaves open is a numbered
ruling in §3. Sourcing is recorded in
reference_materials/README.md.
Three rulings do most of the work:
- R4 — "spades are broken" is a property of the hand, not of a trick. You may not lead a spade until one has been played, unless spades are all you hold.
- R7 — a nil bidder's tricks are bags, not contract progress. Taking a trick on a nil hurts twice.
- R10 — the sandbag penalty carries its remainder: 12 bags becomes 2, never 0.
House rules (table options)
Picked before the deal, in the host's setup form, and frozen for the life of the game:
| Option | Default | What it does | |---|---|---| | Allow blind nil | off | A side 100+ behind may bid nil before seeing their cards, for ±200, then swap two cards with their partner. Adds a phase to the hand, which is why it is off by default. | | Play to | 500 | 500, or 200 for a short game. |
Install
pnpm add @game-hub/game-spadesFour subpath exports, one per seam:
| Subpath | What |
|---|---|
| ./engine | pure rules — deterministic, injected randomness, 100% test gate |
| ./module | the backend GameModule seam |
| ./client | the UI GameClient seam (a lazy board) |
| ./bot | the AI policy — 90% test gate |
@game-hub/kernel, @game-hub/ui-kit and react are peers: the host provides exactly one copy of
each. This package ships no CSS — its board styles with Tailwind classes in source, so a host must
scan the installed package (@source '../node_modules/@game-hub').
Hosting it
Two dependency lines (backend + ui), one games.config.ts entry, pnpm generate:
{ id: 'spades', module: '@game-hub/game-spades/module', client: '@game-hub/game-spades/client' },Develop
pnpm install
pnpm typecheck && pnpm test && pnpm lint && pnpm format:check && pnpm build && pnpm pack:smoke⚠️ Publish with pnpm publish, never npm publish. npm ignores publishConfig.exports and would
ship a tarball whose subpaths still point at ./src/*.ts. scripts/assert-pnpm-publish.mjs runs as
prepublishOnly and refuses the publish unless pnpm is driving.
License
BSD-3-Clause.
