Pickle Royale
A 2v2 pickleball ladder I designed and built for my own group.
- Role
- Design and build, solo
- Type
- Personal project
- Live
- pickleball.dhrumilkherde.com/demo
01 /
The problem
Me and my friends play 2v2 every week, random teams every time.
Nobody could remember who was actually any good. Rankings lived in people's heads and got argued about in the car park.
So I built the scoreboard.
02 /
How I gave it a look
I do not describe a design to an AI in words. Words drift.
I collect references, annotate them in Shottr to mark exactly which part I mean, put them in a folder named for what they are for, and hand over the path.
It reads what I pointed at instead of what I managed to describe.
03 /
The form follows the moment
Log Match asks: who played, what was the score, who carried.
That is the order you decide it in, standing on court with one phone between four people.
Not the order a database would prefer.
03 /
The form follows the moment, on one phone

Step one: who played

Step two: what was the score
04 /
The system I was offered
The AI proposed the simple version. Everyone starts at 100. Win, go to 110. Lose, go to 90. Every time.
Beat the best player in the group: +10.
Beat the worst player in the group: +10.
It cannot tell those apart, so it cannot tell you anything.
05 /
What I asked for instead
Rate everyone, predict every match, and move people by how wrong the prediction was.
Beat someone you were meant to beat and barely anything happens. Lose to someone you were meant to beat and it costs you.
Hard to climb, easy to fall down. That is what makes the top of it worth anything.
06 /
What that looks like in play
Maya and Neha, 1467 and 1333. Kabir and Sanjay, 1085 and 889.
The model gave the favourites 92%.
06 /
What that looks like in play, the upset

06 /
What that looks like in play, the magnitude
They lost 3-11.
59 points, each way. An even match moves about 9.
06 /
What that looks like in play, the ladder before and after


07 /
Margin, dampened
An 11-0 counts for more than an 11-9, on a log curve, so a blowout matters without being everything.
And a strong team crushing a weak one earns less than the scoreline suggests, deliberately. Otherwise whoever is top farms the bottom of the ladder and never defends anything.
07 /
Margin, dampened, the skunk

An 11-0 skunk, the bigger swing
08 /
Who carried
In doubles a win is not split evenly, and everyone at the court knows it.
A slider from centre, 10/90 at the extremes. Drag it toward whoever did the work.
08 /
Who carried, the slider at rest and dragged


08 /
Who carried, in a loss
In a loss it inverts: whoever carried loses less. It was not their fault.
The split only moves points inside a team, never changes the team total. Which is why it is safe to let friends argue about it.
09 /
Ratings are never stored, only replayed
Every rating is recomputed from the whole match log, in order, per group.
So deleting a mistyped match is safe, and one group's results cannot leak into another's.
10 /
Then I had to let people in
The login wall blocked everyone I wanted to show it to. So there is a demo: every visit mints a throwaway group seeded with a real season, signs you in, hands you a player. Log a match, watch the ladder move.
A daily cron deletes them. Real groups are never touched.

Built with
- Frontend
- React, Vite, TypeScript
- Platform
- One Cloudflare Worker serving app and API, D1 for data, one deploy
- Auth
- Google sign-in
- Ratings
- shared/elo.ts: base 1200, K of 40 for the first ten games then 24, contribution clamped 10/90, margin of victory on a FiveThirtyEight-style log curve
- Made with
- Claude Code, with design references annotated in Shottr