TinyGames · how it works
Fifteen reds and six colours, in the order the game insists on. A long table, a thin pot, and a penalty for every ball you were not aiming at.
Draft. It is built, compiled and tested like every other game, and it is
not on the hub: "draft": true in build/games.json keeps it off the cards,
out of the sitemap and without a readme page until the rules are real. Take the
flag off when it is worth playing.
Three layers, not two. src/shared/baize.ts is what a ball does - spin,
cushions, contacts, pockets - and is shared with Carom. frame.ts is the rules
and touches nothing: no canvas, no engine, no storage, no Math.random.
snooker.ts is the table, everything that draws or listens, and the two
translations between the other two - a ShotOutcome assembled from what the
physics reported, and the geometry of where a respotted colour actually goes.
The split is what makes the hard half testable: node test-frame.js runs
against the shipped, minified JavaScript rather than the source, which is how a
minification fault gets caught.
Every screen except the run itself belongs to the shared shell, so this game
has one scene of its own, play. The menu, the pause card, the game-over
screen and the high-score table come from src/shared/scenes.ts and look and
behave the same here as in the other twenty.
src/snooker/frame.ts - 188 assertions, 22 mutantssrc/snooker/snooker.tsframe.ts"draft": true off the entry in build/games.json, and give it real
facts instead of status: in progressAdvertisement