← Back to work

Sports · Web Game · Solo Build

Built, shipped, and still improving

I enjoyed playing a game until the UX started to frustrate me, so I built and shipped my own version, then kept refining it through real playtester feedback across 15+ shipped improvements.

iknowball gameplay demo: rolling a random team and drafting real NBA players onto a roster
Play iknowball →

Project Type

Self-Initiated, Live Product

Role

Solo, End-to-End: Concept, Design, Build, Ship

Tools

React, Vite, Vercel, Claude Code

Year

2026

Why this project exists

Sneakers and basketball go hand in hand, and I've always enjoyed draft-and-guess basketball games, the kind where you pull a random real team and see how far you can take it. 82-0.com is the one I kept coming back to, until the same handful of teams and eras kept showing up over and over, undermining the entire premise of a "random draft" game. So I built and shipped iknowball: draft a 5-man NBA roster one position at a time from randomly rolled real teams across six decades, then get scored on how that roster would perform across an 82-game season.

Who I Talked To

Research happened in two rounds. First, four unmoderated interviews (Maddy, Arnold, Justin, and Nicky) spanning basketball knowledge levels from none to expert, testing version 1.0: a simple randomization ticker, a 10-player pool per spin, and an end-of-round breakdown of the score, best pick, and a better alternative. Then, after the first wave of fixes shipped, a 20-person structured playtest run by Kevin and his rec basketball league, the first round with real quantitative data and the first head-to-head test against 82-0 itself.

Research → decision → ship

Foundation already in place going into this research: four scoring pillars (Scoring, Rebounding, Defense, Team Chemistry), a rule-based post-game breakdown, tier cards shown only after the draft, and a full 168-roster data audit. Everything below is what changed after real players got their hands on it.

The roll: from a text ticker to a tumbling 3D die

  • Finding: players couldn't tell a randomized roll was happening at all, especially casual and non-knowledgeable testers.
  • Decision: a basketball-textured 3D die that tumbles through team/era combos before locking on the result, synced to the old ticker's decelerating cadence.
  • A later polish pass fixed three animation bugs it surfaced along the way, tightening wobble amplitude from 24° to 9°.
Before Old v1.0 text ticker shuffling through team/era combos
After Shipped 3D die tumbling and locking on a result

Stat legibility: from inline text to standout-highlighted stat blocks

  • Finding: stats were hard to see, and one stat-driven tester didn't notice they existed on the card at all.
  • Decision: a bold number and label per stat, plus a computed "standout" badge (Rebounder, Playmaker, Rim Protector...) per player, reusing the same real-data ceilings already powering the scoring model.
Before Old stat display: plain grey numbers, easy to miss
After Shipped stat display: bold white numbers with an orange standout stat

The founding bug: decades weren't rotating across games

  • Finding: the exact complaint that started the project, resurfacing. Franchises rotated across games; decades never did.
  • Decision: gave decades the same cross-game rotation logic franchises already had.
  • Verified with an 8-game simulation: 30/30 franchises cycled before repeat, 6/6 eras surfaced every cycle, including the 1970s and 1980s.

Era weighting, before the first rotation fix

Static weights only, no cross-game memory, so the same 2-3 eras dominated every single game regardless of what came before.

Before 1970s: 0.02 · 1980s: 0.05 · 1990s: 0.6
2000s / 2010s / 2020s: 1.6 each
No cross-game exclusion for any era.
After Same weights still shape ordering within a cycle, but every era is now excluded once seen, guaranteeing all six appear before any repeat, then the cycle resets.

Tier-rating restructure: giving each rarity its own lane

  • Finding: Silver, Gold, and Diamond shared one continuous 40-99 curve, so a fresh Diamond could score as low as 85, barely distinct from a strong Gold.
  • Decision: fixed, non-overlapping bands per tier (Silver 40-79, Gold 80-89, Diamond 90-99), verified across the full ~1,690-player dataset.

Rating scale, before vs. after the tier restructure

Before One shared 40-99 curve. Lowest Diamond in the dataset: 85. Highest Gold: 84.
After Silver 40-79 · Gold 80-89 · Diamond 90-99. Every tier gets a clean, non-overlapping band.

Team/decade repetition, round two: a per-franchise memory

  • Finding: Kevin's group reconfirmed the founding complaint even after the first rotation fix. A team could still land on the same decade again almost immediately.
  • Decision: added a lightweight per-franchise memory that heavily penalizes (not bans) a team's most recent era on its next roll.
  • Verified with a 300-game simulation: same team/decade back-to-back dropped from 11 instances to 1, with zero regression to franchise rotation.

Same-franchise repetition, before vs. after round two of the fix

Measured over an identical 300-game / 1,500-pick simulation on production code.

Before A team could repeat its exact last era in the very next game 11 times out of ~1,350 combo-repeats observed.
After Down to 1 instance, a roughly 90% reduction, with zero regression to the franchise hard-cycle or 1970s/80s rarity.

The data behind the calls

24
Total research participants
37
Player ratings corrected
90%
Drop in same team/decade repeats
30
Franchises in rotation, 0 violations
168
Team-era rosters audited

Live, and playable right now

iknowball is a shipped, live product: real teams across six decades, real per-season stats, and a scoring model that explains itself in plain language after every round.

Noticing the flaw is easy. Shipping the fix is the actual work.

Anyone who plays 82-0 could tell you it repeats itself too much. The harder part was building an alternative good enough that real players preferred it, then discovering my own fix had quietly reintroduced a narrower version of the exact bug I built the whole game to solve, and fixing that too.

A game you actually play is the best source of product instinct you'll ever have. I didn't need a research brief to know 82-0 was repetitive. I needed the discipline to build the fix, ship it, and keep listening once real people started playing it.