Loading recipe…
Press Run. three trigger coins seed the board, two respin waves land more, the counter drains down on misses, and when the feature ends every held coin flies off the board into the counter widget.
The strips spin the source game’s full base set — cherry, lemon, orange, plum, grape, watermelon, bar, bell — while only coins ever land. Value coins are the gold lightning coin with their amount in the game’s own gold bitmap digit font (25.00 — always two decimals); the digits, comma and dot glyphs were rebaked from the original sprite sheet into a BMFont (/hw-spine/goldfont.fnt) and rendered with PIXI.BitmapText.
This is the Hold & Win starter upgraded to production-style art. Every cell is still its own 1×1 ReelSet under HoldAndWinBuilder; the difference is the symbol class and the collect choreography.
Registering the Spine coins
Each id maps to its skeleton through a spineMap; SpineReelSymbol drives the standard lifecycle, and the jackpot coin gets a small custom class (GoldCoinSymbol) because its “win” is the tier reveal:
r.register(id, id === COIN ? GoldCoinSymbol : SpineReelSymbol, {
spineMap: SPINE_MAP, // id → { skeleton: 'hw-jackpot' | 'hw-cherry' | …, atlas: 'hw-atlas' }
idleAnimation: 'idle', // played only if the skeleton defines it
landingAnimation: 'fall', // ditto — no-ops where the skeleton lacks it
winAnimation: 'win', // the board calls playWin() on every lock
scale: scaleFor[id], // computed by probing each skeleton's bounds
});
The fruit skeletons ship a win; the jackpot coin ships its tier one-shots (coin / mini / major / …) instead and has no idle / fall / win of its own — those hooks simply no-op (SpineReelSymbol guards every setAnimation with findAnimation), the landing settles on the money face, and the tier word is the reveal. The Hold & Win choreography never touches Spine directly.
Jackpot tiers: word on, spin, money face
The MINI and MAJOR coins share one extra skeleton whose animations are named by tier. The coin lands wearing its tier word (mini_x / major_x idle loops); on lock, the tier one-shot (mini / major) spins the coin, throws the wording off and settles on the coin money-face loop — at which point the amount paints over it in the gold font, exactly like a plain value coin. The reveal is driven from the coin:locked event via symbolAt(cell); the board itself stays oblivious. Jackpot coins land server-placed only (weight: 0), and the matching plaque above the reels plays its win on lock.
public/recipes/hold-and-win-spine/jackpot-reveal.gif Coins stay opaque, values stay game-side
Each hit is { cell, id, data: { value, kind? } }. The board never reads data; the recipe paints value labels from the coin:locked event (skipping jackpot coins — their art carries the tier), flashes plaques on kind, and sums on collect. Swap the payload for multipliers or collector flags — the board doesn’t change.
The collect flight
When the feature ends the recipe walks the locked coins and, per coin:
- spawns a throwaway Spine clone at
board.cellCenter(cell), - calls
board.release([cell])so the board cell empties under it (and thecoin:releasedevent clears the label), - tweens the clone to the counter, which plays its own
incrementanimation as the total ticks up.
Flight and trail art are deliberately not a board feature — the board hands out exact pixel geometry and events, and the game layer owns whatever flies. A golden-trail Spine or particle ribbon drops into step 3 without touching anything else.
Asset note
The skeletons are converted from a Spine 3.7.94 game export to 4.2 with tools/spine-3.7-to-4.2 — normalized-to-absolute bezier rewrite, skins/timeline restructure — and validated against the real spine-core 4.2 parser before ever reaching the browser.
Related recipes
- Hold & Win respin. the minimal starter board, plus the holdReels variant
- Spine big symbols. SpineReelSymbol on a standard reel set
- Value-carrying coin. coins carrying a coefficient in data on the board