Somewhere in the second week of August, at a kitchen table that wasn't mine, I did the thing you should never do on holiday: I handed my phone, with my games on it, to someone whose opinion I value.
They gave Duels about ninety seconds. They solved one LineBy puzzle out of politeness, the way you eat one of someone's home-made biscuits. Then they tried the racer I'd been building since the end of July — a magnetic sled screaming through a black storm drain, sodium lamps, everything the colour of an oil slick — and handed the phone back with the kindest possible version of no. Not "it's hard", not "it's broken". Just: why is everything so grim?
I'd like to tell you I defended my artistic vision. What actually happened is that I looked at the game properly for the first time in weeks and thought: they're right, this is a lovely physics engine wearing a horror film.
The game they didn't like
Its bones were — are — the best code I've got. A pure simulation at a fixed 120 Hz, a sled with eight thrusters and no grip at all, so yawing the chassis doesn't turn you; only thrust does. Learning to aim with your nose and steer with your engines is genuinely wonderful, in the way ice skating is wonderful once you stop hitting the ground.
But I'd dressed all of that in dread. The verdict wasn't about the driving. They never got far enough to meet the driving. The costume was doing all the talking.
Make it bright
So, mid-holiday, I forked it. Same simulation, byte for byte — the physics is a shared package now, and the dark game still exists and still gets every fix. The whole register above it flipped: the drain got skylights and hard noon sun, the sled became a board with a rider standing on it, and the look moved to flat ink on bright paper.
The expensive lesson was that you can't brighten a dark game by turning the lights up. The cheap version — take the grim concrete recipe, raise the values — was tempting enough that I wrote myself a rule against it before I could act on it: the bright look gets authored from scratch or not at all. New wall, new colour, new light, and eventually a real cel-shading model with ink outlines, because I'd made every surface flat and printed and the frame still read photographic. The surfaces were never the problem. The light was.
Nine days as TUBULAR
The game was called TUBULAR for exactly nine days, which is how long it took me to run a proper trademark search instead of a vibes-based one. It came back with a live US registration — an actual 1980s-styled surf-and-skate board game of that name, registered in 2024, owned by someone with a lawyer. Different goods class, same commercial impression, and "same impression" is the part that loses you the argument.
RUNOFF won the replacement round on the register, not on taste: seven live marks, none of them a game, and a double meaning where both halves land — the stormwater that fills a pipe, and the race that decides things. That it is also honest about my development process is a bonus I choose not to examine.
There's a page for it now. The trailer is back on the cutting table — but the rule every cut follows is settled: the opening seconds are generated, dressed up as a 1985 videotape, not one frame of the game in them, because the game cannot show you a face. The moment the riders go through the grate, that stops: the riding is the game rendering itself, the same chase camera you play with. The racing is never the thing I fake.
The one useful thing
If your Unity URP project claims to use Forward+, check the number, not the comment. My setup script wrote the renderer mode like this:
// Forward+ — hundreds of lamps in one pipe.
soRenderer.FindProperty("m_RenderingMode").intValue = 1; // 1 = ForwardPlus
That 1 was Deferred — URP 17's enum runs Forward = 0, Deferred = 1, ForwardPlus = 2. The
comment said Forward+, twice, the log line said Forward+, and the game
rendered deferred for its entire life without anyone noticing — because deferred also lights
hundreds of lamps happily. It only surfaced when the new cel shader drew nothing: a custom
lighting model has no place in a deferred g-buffer, so URP silently classified it
forward-only and skipped it. The fix is (int)RenderingMode.ForwardPlus — the enum, never
the literal — pinned by a test that compares the asset against the enum. A comment is not a
setting.
Runoff isn't out, and the person who set all this off hasn't seen what it turned into. I built an entire register flip on a sample size of one, and I'd do it again.
More soon — RSS.
