Yowmings LeagueA game that settles a real draft has to be one nobody can argue with.

The kickoff of a Yowmings League quarter-final: a head in a striped referee cap drops in from above with the football just released beneath it, four cut-out heads waiting on the pitch below, and a set of uprights at each end.
Role
Designer & builder
Scope
End to end, solo
Built with
Vanilla JS, no framework
Year
2026
Overview

Every year my friends need a fantasy draft order. A random draw is fair. A game is better, but only if everyone believes the result.

Twelve of their faces drop down a marble course to seed a bracket, then play it out until someone takes the 1.01. It runs in a browser with no framework and no build step.

Frame 1 of 9: a head in a striped referee cap drops in from the top of the pitch with the ball just under it.
Frame 2 of 9: the referee head is lower now, the ball still tucked beneath it, two team heads rising at the edges.
Frame 3 of 9: the referee head has let the ball go and the ball is falling on its own.
Frame 4 of 9: the referee is gone; the ball falls through an empty pitch.
Frame 5 of 9: the first red and blue heads reach the falling ball from below.
Frame 6 of 9: more heads arrive and the ball is swallowed by the bundle.
Frame 7 of 9: both teams are on the pitch, packed around the ball.
Frame 8 of 9: the bundle spreads out and the ball squirts clear of it.
Frame 9 of 9: the ball is loose and away, with the field strung out behind it.
Kickoff, left to right in time: the referee brings the ball down, lets it go, and leaves. Drag the strip sideways.
The stakes

A toy can be wrong. A verdict cannot.

Nobody audits a game they played once. They audit the one that decided who picks first, and they do it out loud, while watching.

So “done” stopped meaning “fun” and started meaning “unarguable”. Six weeks, 991 commits, and the interesting work was never the feature: it was the gap between what my instruments measured and what the screen actually showed.

The course

The race worked on the only screen I had measured.

The race seeds the bracket, so if it stalls there is no draft. Swept across nineteen viewport sizes, twenty-two races ended with nobody across the line. On a TV, fewer than one in five finished.

My theory was the fall. I measured first, and it was the gate: its bar scales with the course, its opening never did. Twenty-two stalled races became zero.

Before
The marble course before the fix: eight heads stacked up above a narrow slot between two black walls, none of them through it.
The same course on a wider screen. The slot at the bottom of the funnel stayed the size it had always been, so the field piles up above it.
After
The same funnel after the fix, on the same wide screen: all eight heads are strung out right across the mouth of it, falling, with nothing queued above the slot.
The opening scales with the bar that makes it. Nothing queues above the slot: the field is strung across the whole mouth of the funnel and still falling through it.
The players

A head could reach a state with no way out.

Players froze mid-match, rarely, briefly, and exactly the kind of thing that gets brought up for a year.

A head could end up falling and not airborne at the same time, which nothing in the engine can leave. It was half of every frozen frame. The fix had to remove the freeze without removing the mess, because the chaos is the point: after it, the ball spent more time in the air, not less.

The rule

I argued for the wrong version, and the measurement won.

Balls were passing through the goal without scoring. Real football has no ceiling over the uprights, so I removed ours. It fixed the complaint outright.

It also awarded more than a quarter of goals with the ball in open sky above the posts, a picture that no longer matched its own rule. The version that shipped is narrower, and no goal lands above the posts now.

Before
The goal before: short yellow uprights on a crossbar that runs past the right upright, standing on a red pad much wider than the post it wraps.
The pad is wider than the post inside it and the crossbar overshoots the upright.
After
The goal after: taller uprights, a crossbar that ends where they stand, and a green pad the same width as the post.
The pad is the post’s own width, the bar ends where the uprights stand, and the uprights are taller.
What I took from it

Counting is not looking.

Four times in one night an instrument said fine and the screen disagreed. A hairline that measured 1px read as a line struck through the score. A layout that measured “nothing off-screen” had two elements sitting on top of each other. Two captains’ names came out invisible on their own bar.

Both lie. The work is knowing which one you are holding.

Before
The score bar before: a hairline runs straight through both score digits like a strike-through, and the captains’ names GUS and CHIP are so pale they almost vanish.
A 1px rule, measured correct, drawn through the middle of the score. The names beside it are there and cannot be read.
After
The score bar after: the rule stops at the digits instead of crossing them, and the names OZZY and JAYDEN are set in dark ink.
The rule stops either side of the digits, and the names carry the bar’s ink.
Outcome

It decides something, and nobody argues.

Every race finishes, on every screen I could find. Players stay on their feet. Goals look like goals. And the thing it was built to protect survived all of it: the winner still is not the halfway leader in two races out of three.

Frame 1 of 6: both finalists’ photographs hang above the pitch and the winner is announced.
Frame 2 of 6: the two photographs settle side by side while the heads gather below them.
Frame 3 of 6: a white tear opens down the middle of the loser’s photograph.
Frame 4 of 6: the loser’s photograph has come apart into two halves.
Frame 5 of 6: the torn halves fall away past the winner’s photograph.
Frame 6 of 6: only the winner’s photograph is left, with the crowned heads under it.
The end of a match, left to right in time: the loser’s photograph tears in half and drops away. Drag the strip sideways.