Get in touch

From the workshop

Midpack Hero

A trail running life sim that runs on real time.

One runner, for years. Real Wellington trails, a field of simulated locals who take your ground while you sleep, and race days played live as a branching terminal story. Built with Bradley Houghton of Trail Running NZ, and now in the hands of its first testers. Two to five minutes a day.

In beta Web
Laravel Livewire Scenario engine Simulated field Web push
The build story

The build story

A trail running life, at one day per day.

Midpack Hero is a trail running life sim, built with Bradley Houghton of Trail Running NZ. You create one runner and that is your allocation, permanently. They live in real Wellington, hold down a job, train on trails you could run this weekend, and get hurt when you push them past the warnings. Race days are played live, as a branching terminal story where the doors that open are the ones your training earned. Football Manager’s depth, a Tamagotchi’s attachment, a race-day Choose Your Own Adventure, on the sport’s real calendar. Nobody had made this game.

Bradley wrote the founding piece: a Western States playthrough in his own voice, with thirteen ways it could end. The first thing built, in July 2026, was an engine that could play it. Everything since has been the other question: what does a runner do on the 364 days that are not race day?

commits since 16 July 2026
694 commits since 16 July 2026
decisions written down
236 decisions written down
endings, ten scenarios
76 endings, ten scenarios
tests
3,254 tests
runner per person
1 runner per person

Two clocks, and the slow one is the game

The life clock runs at one to one. A session takes its real length to resolve: a drill is home inside the hour, a long run owns half the day. You press go, get on with your life, and a ping says how it went. Your runner wakes at an hour their job sets, inside a forty-minute window seeded per runner per day, because the first playtest note was “wake-up time is always 6.12 and says the same thing”.

Race day is the other clock: a branching narrative played live against a field that is real, so your finishing place comes from the same model that timed everyone else, seeded off your stats and never rolled. Between the two the daily loop is two to five minutes, on purpose. A game about patience should not demand addiction.

00:00 06:00 12:00 18:00 00:00 06:12 wake ping, jittered 07:30 you press go 09:00 outcome ping 17:30 a second slot, once earned 22:00 nothing reaches your phone the day job, 09:00 to 17:00: the afternoon slot goes with it the night’s recovery is earned off the load taken today quiet hours, 22:00 to the wake hour
One weekday. Every mark is a rule, not a record: the wake window, the session length, the slot a job eats, the hours nothing is allowed to buzz. An unstarted session lapses at the rollover and costs a point of confidence.

The teaser is not a demo

The race-day half plays on its own at /teaser, no account needed: Bradley’s Western States, 68 nodes and 13 endings, typed out character by character under a blinking block cursor. Six hidden stats (energy, nutrition, stomach, quads, confidence, heat) move with every choice, and some story nodes read them to decide which way the road bends.

For a month the site called it a demo. Bradley’s note: a demo makes it sound like a demo of the full game. He was right. A demo is a cut-down build of the product; this is a different product that shares an engine. So the copy says teaser, and a test scans every template for the old noun, because the word only ever comes back the way it arrived: somebody adding a button and typing what they have typed a hundred times.

The Western States teaser in its phosphor-green terminal: a course profile in the masthead, a half-block pixel rendering of Olympic Valley at dawn, a block of current conditions, the opening beat of prose, and four numbered choices for how to start the race.
The first beat, after the typewriter has finished. Sponsors: Watching is a status line and a joke, which is the house style. Option D starts so conservatively your watch asks if the run has begun.

Every road through Western States

A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road A decision: two to four options, none of them safe A decision: two to four options, none of them safe A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road A decision: two to four options, none of them safe A decision: two to four options, none of them safe A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings A decision: two to four options, none of them safe The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings One of thirteen endings One of thirteen endings The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings One of thirteen endings The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road A decision: two to four options, none of them safe A decision: two to four options, none of them safe One of thirteen endings One of thirteen endings The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings One of thirteen endings The story goes on. Some of these read your stats to pick the road The story goes on. Some of these read your stats to pick the road One of thirteen endings Olympic Valley Robinson Flat Devil's Thumb Michigan Bluff Green Gate No Hands Bridge Robie Point decision story ending
All 70 nodes and 85 links, laid out by distance from the start line. It is not a tree: roads split at a decision and rejoin at the next aid station, so thirteen endings share the same canyons. The names of the endings are the one thing the results feed never shows, and they are not here either.

A finishing time is the sum of the stretches you ran

On 18 September Bradley and I raced the WUU2K half against each other, live, and four complaints came back to one cause. My runner has climbing 80. I took the line that says “Attack it. You climb for a living,” and it cost me 39 places. The model only ever charged for effort and never paid any back, so the best plan in every race was to spend as little as possible. One gate re-priced the whole race: a point either side of it moved my projected time by 33 minutes. And place and finishing time were two models that never met, so Bradley held sixth all race and lost nineteen places in one tick at 20 km, when his story ended and an estimate became a time.

The fix is the heading. The ground between one call and the next is priced when the call is answered, from what the choice spent, whether you had the legs for it, how tired you were and how sure of yourself. Attack a climb on climbing 80 and that stretch is priced at 0.97; scrape through the gate on exactly 55 and it is 1.14, worse than the 1.10 for walking it. Place, the kilometre on the board, the countdown to the line and the result are one number read four ways now, so nothing moves when a story ends and no place changes without a call.

Five minutes to the gun

I wanted the nervous wait before a start. Since October the five-minute push opens the start line: about ten runners stood around you, picked by how close their expected time is to yours, mates first, and an announcer saying who is in and how they look. The announcer is a pool of written lines filled from facts the field already holds (a debut, a niggle, last year’s winner), so race time still calls no model. When the gun goes the same picture runs, and the spread is the board itself: a gap on screen is a share of the real gap in expected time, times how far in you are. The field strings out over the race instead of all at once, and nobody is drawn where the board does not have them.

The start line the way the game draws it: ten simulated locals in its own sprites, and its announcer’s lines. With motion on, scrolling runs the race, and Moley comes down his ladder to enter it.

The board that locked solid on 3 August

The Wellington rivals started as five names in a config file and one rule: two days after you took a crown, it came back at your own time minus two per cent. They are a population now, sharing the runners table with the people. Each has an archetype (mountain goat, gravity merchant, diesel, weekend warrior) jittered into a policy of its own, and trains, peaks, gets hurt and attacks ground on the same physiology the humans run on. A crown only ever changes hands to a faster time.

Then my own feed went quiet: nothing had changed hands since 3 August, the day the eighth and last piece of ground found a holder. Eight pieces, eight holders, a cap of one each, and the guard benched a bot outright at the cap: it stopped looking at ground at all. Every runner quick enough to take anything was benched, and the six still attacking were the slowest in the field. Without a human the board could not move, ever.

The fix is that the cap limits what a bot may hold, never whether it goes out. At the cap it still attacks, under two rules: it must expect to win outright, and the ground must suit it better than the worst piece it holds, which it then gives up. The second rule is what makes the drop safe. Open ground always sorts to the top of the list, so without it a full bot takes back the piece it just dropped and the board cycles inside one runner while looking busy. Measured on a copy of the production world over sixty simulated days:

Crowns a bot may hold Changes of hands, before After Holders in the second month
1 2, none in days 30 to 60 75 6
2 7 27 5
3 4, none late 7 3
Eight pieces of ground, fourteen bots, sixty days, counted twice: in total, and in the second month alone, which is the half that matters. A higher cap is now strictly worse: the fast bots hoard. The dial sits at two.

No AI at runtime, and a voice bible read off disk

Every word a player reads is committed JSON. Serving a player costs hosting, never inference: replay Western States ten thousand times and the model bill is zero. Drafting happens in artisan commands, at build time, under Bradley’s voice bible: second person, present tense, deadpan escalation, body parts filing complaints, one genuinely true line per act and no more. A linter measures what a document cannot enforce. The spaced em dash is counted (zero across Bradley’s 276 exemplar lines), and the phrases a language model reaches for when it has nothing to say fail the build. Four runtime exceptions exist, each named by file in a test, and two of them only classify what a player wrote: they never produce a word anybody reads.

What it uncovered was in the drafting command itself. It carried a paraphrase of the voice bible, and the paraphrase had drifted: it dropped six of the ten signature moves and contradicted the guide on te reo. There is one copy now, read off disk at authoring time, and a test fails if a summary reappears. A style guide that a tool restates is two style guides.

The trailer keeps the same rule. It is a JSON file of shots, narration, pings and music, and a build script films the real game for it under Playwright’s fake clock, so the same inputs give the same frames. The narrator is my own cloned voice, generated once a line and cached by a hash of everything that made it. Every word it says is copy already on the site, every ping is a real line from the game, and the key clicks are synthesised one per character, on the schedule the screen types on.

A minute of the game, with sound, from a console waking up to a finish arch. The poster is its end card. It plays from midpackhero.com, which also has an upright cut for phones.

Honestly: in beta, drafted, and waiting for Bradley

Free, one runner per person, and money never buys fitness. A race fee gates a start line and does nothing else, and the in-game purse is marked with the generic currency sign so a NZ$380 entry never sits beside a Buy button and reads as a purchase. What the purse does buy is things other people can see: kit in the shop’s colours, a campervan, a pain cave, and a dog that runs with you and goes to stay with family if the purse cannot feed it. None of it makes you faster. Since October it has been in beta, with its first invited testers on a fresh world, and their first season closes on 1 December with a promotion and a relegation. Wellington is the only region. Every string outside Bradley’s own playthrough is still drafted and pending his pass, and the majors on broadcast time are still on paper. Two to five minutes a day is the deal, and the clock is the whole point.

Got a game, or a world, that needs a simulation underneath the story? Here’s how we could work together.

Visit Midpack Hero