Gretzky ’82 and Lemieux ’89 on the same roster
Wax Pack is a set of salary-cap sports sim games built from one memory of a 2006 browser game. It went from "can we make a nicer version of this?" to four live games, one shared account and 52,009 draftable NHL seasons, built in a running conversation with Claude Code and shipped to Cloudflare as it went.
A game worth paying too much for
Around 2006, WhatIfSports ran a hockey sim league. You were general manager and coach: draft players from any season in NHL history under a salary cap, set your lines, and watch an 82-game season play out in box scores and play-by-play.
The hook was the butterfly effect. Every player-season was its own card with its own price, so with careful cap math you could put peak Gretzky and peak Lemieux on one bench and see what happened.
The brief was never to clone that game. It was to build an original one in the same genre, around the same idea, and make it feel good on a phone.
“Ancient, but wildly comprehensive… if you could afford it you could have Gretzky ’82 and Lemieux ’89 on the same roster.”
The original request, describing the 2006 game
Four games, one account
Six spins, three skips, one trade. Build a lineup from three blind real seasons at a time, then see what it does over 82 games. Has a leaderboard.
Play Line Change →The full salary-cap league: draft, lines, a live Game Center, the trade deadline, playoffs, and franchises that run for years.
Play Time on Ice →The lineup game for baseball, built on the same pattern with real MLB seasons.
Play Rally Cap →Every season since 1890, a $190M cap for 26 players, and best-of-seven series. Built on the same league core as Time on Ice.
Play Pennant Race →

The cap is the game
Everything interesting comes from scarcity. If every legend costs the same, the draft is a formality. So every player-season has a salary set by its rating, and the cap forces trade-offs: one Gretzky, or three solid second-liners.

From 484 cards to 52,009
The first version had 484 hand-rated seasons, mostly career peaks. That was enough for one 8-club league. It was nowhere near enough for 32 clubs with bench players, minor leaguers and players who age.
So the pool grew to every NHL season a player actually played. The 484 hand ratings stay as they are. Every other season gets an estimated rating: the player’s hand-rated level, moved up or down by how that season’s era-adjusted scoring compared. Gretzky the rookie rates 91, Gretzky in his prime 99, Gretzky at 38 rates 87.
The pool now covers 5,771 players from 1917 to 2025. Estimated ratings show with a dashed outline in the draft, so nobody mistakes a guess for a hand rating.
Coach it, trade it, share it
The sim runs in 20-second slices of game time, with line changes, penalties, power plays, pulled goalies, 3-on-3 overtime and shootouts. Tuned over full test seasons, it lands near 3 goals and 32 shots per club per game, with about one game in six going past regulation.




One ask at a time, shipped as it came
No spec, no backlog. Each request was a sentence or two in chat. Each one was built, tested in a real browser at phone and desktop widths, and usually live on Cloudflare within the hour. These are the requests in order.
- Night oneOct 27
- “Can we make a really nice, responsive version of this bad boy?”
An original salary-cap league: draft from 484 real player-seasons, 8 clubs, a full sim with box scores, play-by-play, standings and a playoff.
- “Can we deploy on Cloudflare?”
Live on the existing Worker the same night, next to the original lineup game.
- “Can you put a salary range filter?”
A dual-handle slider over a histogram of how many players sit at each price.
- Stat lines, then “make the stats sortable”
Real season lines on every card, with a switch. Every column sorts both ways, including position and club.
- “16 and 32 team versions… a bench and/or a minor league… injuries… a third goaltender”
Divisions, wild cards, a 16-club bracket, a 23-man roster with cap-free minors, injuries, and the pool expanded to 4,955 seasons.
- “I personally think Bobby Orr was overrated.”
His rating stayed. His salary didn’t. Then Hasek got the 99 he deserved.
- “Allow the user to play their game and see a box score”
The Game Center, with live play and coaching at each intermission.
- Night twoOct 28
- Share options, league stats sharing, a save option
Short share links stored in D1, score-aware link previews, image cards, CSV export, and save files.
- Another season, historical stats, and a trade deadline
Careers or Keep core seasons, the History tab, pre-deadline offers and the 30-second Deadline Day.
- “A small cap increase over the years”
3% a season, rounded to the nearest half million.
- “Make the save an add account thing”
Username and password with optional passkeys, then one account for every Wax Pack game, with cloud saves that autosave.
- “There’s no option to start a fresh league, let’s get that first haha”
A New league button, then a start screen: One season or Franchise, followed by an account step.
- “You took away the single season 82 (should be 84 tbh) 32 team stuff”
Size and length back on One season, 84-game seasons, more lengths, and Sim to the end.
- Since thenParallel sessions
- Baseball, and every NHL season
Other Claude sessions built Pennant Race on a shared league core and grew the hockey pool to 52,009 seasons. Deploys were coordinated so half-finished baseball files never went live.
What testing caught
Every shot ended the game
Splitting the sim into periods added a function called finish. It quietly replaced the shooter-skill function of the same name, so every shot tried to end the game and nobody could score. A full test season caught it before release.
Bobby Hull for Bobby Hull
The first Deadline Day offered Hull ’68-69 for Hull ’61-62. Technically legal. Swaps of the same player are now blocked.
Jagr inherited a stranger’s career
When Jagr ’95-96 aged into ’96-97, another club signed the freed ’95-96 season and got his career stats. Every signing now starts its own career line.
The domain that wasn’t localhost
Passkey sign-in failed in local testing because the dev server reports the production domain. The check now follows the browser’s own rule, and a simulated authenticator verifies sign-in, replay and cloned keys.
Small stack, no framework
Plain HTML pages and JavaScript modules, no build step. The league engine is pure logic, so the same file runs in the page and in Node for full-season checks.
One Cloudflare Worker serves the pages and a small JSON API. D1 holds leaderboards, share links, accounts and saved leagues.
Passwords stored only as PBKDF2 hashes, sessions as hashed tokens in HttpOnly cookies, and WebAuthn passkeys verified in the Worker.
Leagues are gzipped in the browser before upload, a 32-club league down to a few hundred KB. A revision check stops two devices from overwriting each other.
About 10,000 lines of code, plus 60,000 lines of generated player data built offline from cached NHL stats.
A full 32-club, 84-game season simulates in under a second in Node, and in a few seconds in the browser with a progress readout.
What comes next
Monetization is the live question: a free tier with a Pro subscription, pay per season like the original, a one-time unlock, or human-vs-human leagues first. Real player names in a paid game also raise a licensing question to settle before charging anything.
- Line Changehockey
- Time on Icehockey league
- Rally Capbaseball
- Pennant Racebaseball league
Screenshots are from the live site at waxpackgames.com. Player ratings, salaries and leagues shown are from the game’s own sims. Wax Pack is an independent project and isn’t affiliated with the NHL, MLB or WhatIfSports.