BilliardTurns
Takes turns at the table: who shoots, and who potted what.
What it does
BilliardTurns plays the rule most people learn first. Pot a ball and you shoot again. Miss, and it is the next player's turn. Pot the cue ball (a scratch) and you lose the turn, even if another ball went down on the same shot.
Every ball you pot is yours. When the rack is clear, whoever potted the most wins.
The turn is decided when the balls stop, not when one drops. A shot can sink the 3 and then scratch a second later, and that shot is a scratch.
It never moves a ball. It listens to the rack, the cue, the pockets and the table, and after every change it sends the whole game on billiards.turns.changed. A HUD draws that and nothing else.
Use it in a scene
A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.
Build it from scratch with the bjs CLI:
- 1Scaffold a project
World, renderer, and dev server — ready to run.
- 2Install dependencies
- 3Add BilliardTurns
Copies its source into src/ so the scene resolves.
First time? Run bjs login once.
- 4Paste the scene into src/scenes/arcade-room.ts and run
SceneLoader builds the world from the JSON; reload to rebuild.
A new rack (R, or billiards.rack.request) starts a new game, and the first player breaks.
Props
players(string[], default["Player 1", "Player 2"]). Who is playing, in order. The first breaks.
Events
Emits:
billiards.turns.changed,{ current, players: [{ name, potted }], reason, shot, over, winner }.reasonisstart,potted,again,miss,scratchorover.winneris a player index, ornullon a tie.
Listens to:
billiards.rack.racked. A new game.billiards.cue.struck. A shot is on the table.billiards.ball.potted. That ball goes to the shooter.billiards.cue.scratched. The shooter loses the turn.billiards.table.settled. Decide the turn.
Dependencies
None. It only reads events from BilliardRack, BilliardCue and BilliardTable.
Changing the rules
- The rules are a pure core:
createTurns,startShot,potBall,scratch,endShot. Swap in 8-ball or 9-ball rules there without touching the system. - A settle with no shot (the rack coming to rest) decides nothing.

















