Atlanta · working globally · open to roles

← Back to the menu
Course 03Design + buildReal-time web

Five players, one draft, thirty seconds.

Cozy Draft is a real-time draft prep tool for League of Legends Clash and amateur teams. I designed it, then built it by directing AI coding agents, and tested every change on the team I play jungle for. It's live, and it still changes every week.

Role
Solo designer · AI-directed build
Testers
5 teams including my own roster (25+ players)
Timeline
2026 to now
Tools
React, Firebase · Claude Design, Antigravity
Live
Try the demo lobby ↗
The Cozy Draft Crew view for a real team: squad readiness shows all five lanes ready, and five player cards list each player's lane, champion classes and the champions they're playing this week

A tool I needed, tested by the people sitting next to me.

Clash drafts happen fast, and five people have to agree on picks, bans and who plays what. Our spreadsheets and Discord threads fell apart under that pressure. So I built the tool, and treated every practice session as a playtest.

ORDER #03COZY DRAFT · TABLE FOR 5
ProblemFive players, one plan, no shared place to keep it.
My partResearch · interaction and visual design · directed an AI-assisted build
TestingWeekly with my roster; closed beta with 5 teams including my own roster (25+ players)
PatternsLive lobby sync · pool inheritance · lane claiming · Draft Lab
LearnedThe shortcut I took for convenience cost the most.
Total1 live product · 5 teams
gg, thanks for reading

Drafting is a team sport, and the tools were built for one person.

In League of Legends Clash, a team of five drafts champions against another team before each game. Good drafts are prepared ahead: who plays which lane, which champions each player is comfortable on, and what to do if the other team takes your pick.

Amateur teams usually prep in shared spreadsheets and chat threads. That works until draft day, when everyone is in the lobby at once, the timer is running, and the plan lives in five different places.

How might we…give five players one shared plan they build together before draft day, and can trust the moment the draft clock starts?

My own team was the first test kitchen.

I play jungle on a five-player competitive roster, which gave me something most side projects don't have: the same five users, every week, under real pressure.

  • A tight loop. Mock it up in Claude Design, hand one small, scoped change to an AI coding agent, test it myself on the live app, then bring what broke to the next practice.
  • Investigate before fixing. When something broke, the first step was a diagnosis with no code changes. After the header regressed three times in a row from patch-on-patch fixes, I switched to reverting to the last working version and isolating the change instead.
  • Tied to the tournament cycle. Fixes had to land before the next Clash weekend, which kept the scope honest.
When the draft timer is running, every extra tap is a lost pick.The constraint behind every screen

Kitchen fires

Real people on a real database found problems no mockup would. These are the ones that changed how I work.

222GB in one monthThe bill for syncing every keystroke.
Five production problems: what broke, why, what I changed and what it taught me
What brokeWhyWhat I changedWhat it taught me
The app burned through 222GB of data in one month. Every keystroke in a shared text field synced to every teammate instantly. Saves now wait for a pause in typing. Moved to a paid plan with a budget alert. Real-time is a cost decision, not just an interaction decision.
One teammate saving their champion pool could erase someone else's. Each save rewrote the whole team's data instead of only the part that changed. Every save now touches only the exact thing being edited. That became a rule for the whole app. In a shared tool, how much one save touches is a design decision.
Switching lobbies could write one team's data into another team's room. A timing bug when switching between rooms. Fixed the switching logic and kept test lobbies strictly separate from real teams' lobbies. Some bugs only exist when real people use the app at the same time.
Every room in production was deleted, and there was no backup. Still unclear. With no backup to compare against, I couldn't trace what removed it. Backups now run daily, and I take a manual one before any risky change. I now plan for the failure I hope never happens.
A single typo could turn the whole app into a blank page, with no error shown. No build step, so broken files failed silently. Files are now checked before every deploy, and the app shows a clear error message instead of a blank page. Design visible failure states, even in tools only you will see.

Three real-time patterns that hold the draft together.

I applied the dense information design I'd used on enterprise fintech and healthcare tools to a very different table. The core is three multiplayer patterns:

assets/img/cz-lobby-sync.mp4Placeholder: muted, looping, about 10s. Two browser windows side by side, one player's change appearing live in the other.
Live lobby sync

Everyone in the lobby sees the same draft plan update as it changes. No refreshing, no "which version are you looking at?"

assets/video/cz-pool.mp4Screen recording: building a champion pool per role.
Pool inheritance

Each player builds one champion pool per role on their own account. Every team they join inherits it, so prep starts from what people can actually play, not a blank sheet.

assets/video/cz-lanes.mp4Screen recording: claiming a lane.
Lane claiming

Players claim the role they're playing. Ownership is visible to the whole team, so nobody picks for a lane that's already taken.

Try lane claimingA recreation for this page. Tap an open lane to claim it.

2 lanes still open.

The live app also covers the quieter moments: an empty state that tells new players exactly what to do, a lobby code to join a team, a bench for substitutes, patch alerts that only flag buffs and nerfs to champions you actually play, a tracker for series where used champions are locked out, and a light and dark theme for late-night scrims.

The bets I made, and the ones I lost.

Every screen here started as a guess about how teams prep. These are the three that mattered most, written the way I log decisions now: what I bet, what it would cost if I was wrong, and how sure I actually was.

Lost

Who "you" are

The bet
Players won't make an account for a hobby tool, so remembering them by device is enough.
The risk
If the app forgets or confuses who you are, you see someone else's data on your card and stop trusting everything the team shares.
How sure
Low. It was a convenience call to keep sign-up friction at zero, not something I tested with players.
What happened
It broke four different ways: the wrong player marked as "you," old names pre-filled, rejoining a team failing, and lane data surviving a cleared cache. Patching each symptom didn't hold, so I rebuilt identity on real accounts.
Options I considered
  1. Remember the deviceShipped, failed
  2. Sign in with GoogleBuilt, then replaced
  3. Username and passwordChosen

Why I switched from Google: on a team tool, your username is your identity, and I wanted players picking the name their teammates know, not inheriting their Google one. The trade-off: I now own account recovery and password rules, which Google would have handled for me. I accepted that.

Lost

"Close enough" draft order

The bet
A simplified pick and ban order is close enough for a prep tool.
The risk
Competitive players know the real order by heart. A practice tool that gets it wrong trains the wrong instincts.
How sure
High, which was the problem. I built it from memory and never checked it against the real sequence.
What happened
My first version ran all bans, then all picks. A teammate spotted it immediately: that isn't how Clash drafts. I rebuilt the simulator to the real 20-step tournament order, including the second ban phase where red bans first. I also added a tracker for series play, where champions used in earlier games are locked out for the rest of the series.

Ban phase 1

  1. 1Blueban
  2. 2Redban
  3. 3Blueban
  4. 4Redban
  5. 5Blueban
  6. 6Redban

Pick phase 1

  1. 7Bluepick
  2. 8Redpick
  3. 9Redpick
  4. 10Bluepick
  5. 11Bluepick
  6. 12Redpick

Ban phase 2

  1. 13Redban
  2. 14Blueban
  3. 15Redban
  4. 16Blueban

Pick phase 2

  1. 17Redpick
  2. 18Bluepick
  3. 19Bluepick
  4. 20Redpick

My first version ran all bans, then all picks. The real order interleaves them, and red opens this phase.

BanPick

Open

Draft Lab, planning for Plan B

The bet
Teams don't prep one draft. They prep contingencies: "if they take our ban, we go here."
The risk
If teams only ever plan one line, side-by-side scenarios and ranked backups are clutter that slows prep down.
How sure
Medium and rising. Beta teams now take their scouting findings into Draft Lab each week to plan bans. What I don't know yet is whether they plan past the first option.
What I'm watching
Whether teams build more than one scenario per opponent, and whether they fill in backups or leave every slot at one champion. If most slots never get a second option, the bet was wrong.
Options I considered
Option 1

Tap a champion to make it the first choice.

Built first
Option 2

Tap a champion to swap it for another.

Chosen

I shipped Option 1 first. In use, I kept wanting to change which champion sat in a slot, and promote made that a remove and a re-add. Swapping also covered promote's job: swap the first slot and you've changed your first choice. The cost: reordering backups now takes a remove and a re-add. I accepted that.

Each scenario mirrors the in-game draft screen: blue side on the left, red on the right, first choice closest to the center and backups spreading outward. It should read like the screen players are about to stare at.

Try a Draft Lab slotA recreation for this page. Tap a champion to swap it.

Blue side: the first choice sits next to the center line, backups spread outward.

First choice: Ahri. 2 backups.

Then I opened the doors to four more teams.

5teams in the closed beta, including my own roster
25+players testing it hands-on
1live production release, used every tournament cycle

My own roster could only tell me so much. The closed beta widened validation beyond one team's habits. I turned beta feedback into prioritized fixes and roadmap decisions, the same way I'd run a backlog at work, just with a lot more trash talk.

What would have counted as failure

Before the beta, I wrote down what failure would look like. Here's what I watched:

  • Do teams come back for their second Clash weekend?

    Yes, all 5. They kept using it through their amateur league seasons, not just Clash.

  • Does the plan live in Cozy Draft, or does it still get pasted into Discord?

    It stayed in Cozy Draft. But most teams had one person screenshare it on a Discord call, so everyone reacted to the plan together.

  • Do all five players claim a lane, or does one captain do everything?

    On all 5 teams, every player claimed their own lane and built their own pool.

What held, and what didn't

What held

  • Live lobby sync

    On most teams, several players edited during the same session. Changes showed up for everyone as they happened, with no refreshing or re-sending.

  • Team comp builder

    Every beta team built five or more comps and rotated between them all league season, not just for one tournament.

  • Shared scouting reports

    Each week, once teams knew their opponent, they scouted every enemy player's most-played champions, win rates, and mastery, then took those findings into Draft Lab to plan their bans.

What didn't, and what replaced it

  • Comfort bar on every player's cardreplaced byClass breakdown

    Testers called it cluttered and redundant. They wanted to see what kinds of champions each player brings. I'd assumed comfort was the most useful summary. It wasn't. Comfort still lives in the full pool view.

  • Separate "Main" and "One-trick" tagsreplaced byA single Flex toggle

    Next to comfort level, the extra tags read as the same question asked twice, and every champion needed two decisions. I cut to one optional toggle. The cost: the pool no longer flags a one-trick's champion as a must-protect pick in draft.

  • Auto-calculated "Top picks"replaced byA "Playing this week" row each player sets themselves

    Auto picks just showed each player's highest-comfort champions, which the card already said. What teams needed was what someone planned to play this week, and only the player knows that. A "Set 3 days ago" label shows when picks go stale.

  • Own pool only viewable in edit modereplaced byA read-only "View your pool" quick view

    Testers wanted to check their own pool without risking an accidental edit. I reused the same quick view teammates already had.

assets/img/cz-card-before.pngPlaceholder: player card with the comfort bar (before).
Before: the comfort bar.
assets/img/cz-card-after.pngPlaceholder: player card with the class breakdown and "Playing this week" (after).
After: class breakdown and "Playing this week."
Everyone updates their own pool, so by game day the whole plan's already there. We just talk it through.Manager, Green Goblins

What building it taught the designer.

Cost

Every interaction has a price. Building real-time sync myself made me much more careful about which interactions are worth their complexity.

Density

Dense is fine when the next action is obvious. The same rule that helped analysts at Cigna helps five players with a draft clock running.

What I'd do differently

  • Real accounts from day one. The convenience shortcut was the most expensive decision in the build.
  • Backups and locked-down data before the first outside tester, not after.
  • A build step from the start, so one typo can't blank the whole app.
  • Write the failure signals down before the beta. I tracked them after the fact.
  • Ask sooner which of my habits are really everyone's. Draft Lab started as my team's way of prepping. Beta teams now use it weekly, but I got lucky. I should have asked first.

Still on the stoveAn iOS app, now that the web version has held up through a full league season.