We're seeing some capacity limits, so parts of the site may be slow or briefly unavailable while we work on an upgrade. Please try again later, or join our Discord for updates.
Discord
Dev blog
Behind the scenes

How 128 pixels learned to tell a Dota story

Dota Captain
7 min read

The match engine already knew what happened. The new Pixel Stage turns those same verified events into a tiny animated Dota scene, without inventing a second match.

The match simulator had reached a slightly awkward point: it knew quite a lot about the game, but presented most of that knowledge like a very serious PDF. The Live Map showed where everyone was and the caster feed explained why the match was moving, yet the thing in the middle was still mostly panels and prose. I wanted one small strip where you could glance up and see the current beat actually happening: a carry farming, a smoke closing in, Roshan getting punched, a tower being worked down. So I gave the match log tiny swords. This is how the Pixel Stage went from a fun prototype to a visual companion for the real simulation, and why getting ten tiny heroes to stop hitting the air became a surprisingly useful design exercise.

The sim did not need more information. It needed a performance

The simulator already had the facts. It knew the teams, the map location, who started a fight, who died, which objective fell, and which narration line was being shown. Adding another chart would not make any of that easier to feel. What was missing was a performance: something small and immediate that could turn the current event from information into a scene.

The inspiration came from taskbar games, where a whole little adventure can live in a narrow strip at the edge of the screen. That shape felt right for Dota Captain. I did not want to replace the Live Map, because the map is still the best place to understand the whole match. I wanted a tiny theatre above the feed: local, linear, readable in a second, and always tied to the moment the casters are talking about.

Pixel art helps because it is forced to be selective. In a 128-pixel-high world there is no room for ten ability tooltips and a minimap argument. A sword, a bow, a tower silhouette, and the distance between two heroes have to do the explaining. That limitation turned out to be the feature.

A stage, not a second simulation

The tempting version of this idea was to build a tiny game inside the game: give every hero its own movement logic, let them pick targets, and hope the little battle arrived at the same answer as the match engine. That would have looked lively right up until the Pixel Stage decided someone survived a fight the real simulation said they lost. Two sources of truth is one too many, especially when one of them has an axe.

So the Pixel Stage does not decide anything. The event engine still owns the match, and the presentation layer stages what has already been verified. The active narration line owns the canvas. Its typed source data supplies the location, cast, attacks, casualties, objective, and result. The system never reads the prose and guesses what an exciting sentence might mean. If the facts do not justify an attack, the stage holds an honest tableau instead of inventing one.

This was also the hardest problem in the prototype. The feed does not display raw engine events one for one: it can combine related moments, split a large fight by location, and add summaries from other match data. My first stage director followed the match clock independently, which meant the words could discuss one event while the tiny actors performed another. The fix was to preserve where every displayed line came from, compile it into one visual beat, and give that beat the stage for its full readable slot.

That produced a simple visual grammar. Farming shows work. Travel and smoke setups move through scenery. Fights keep the background still and play several exchanges. Objectives remain on screen while they are contested or destroyed. Defenses return to the structure being defended. Status moments stay restrained. The match ending gets the Ancient and the survivors. Same seed, same story, same tiny stage manager calling the cues.

The first prototypes were beautifully wrong

The early version tried to show too much map at once. It had a tall canvas, scenery from both sides, heroes standing on different axes, and enough ground to host a small music festival. Instead of feeling like a place, it felt like everyone had met in the vague geographical concept of Dota. The breakthrough was to make the scene much smaller: one floor line, one local place, and only a few distant objects to tell you where you are.

Background art caused its own comedy. A conventional landscape looks fine until you force it into a strip that is 920 pixels wide and only 128 high. Center-cropping gave me giant roads, half a tree, or a lovely close-up of some dirt. Stretching fixed the crop by making the entire world look tired. The answer was to author the final strip itself, like theatre scenery, with the sky and far landmarks already composed for that exact frame.

There are now distinct places for Radiant and Dire lanes, jungles, rivers, bases, and the Roshan pits. Roshan lives in a cave instead of strolling around an open field like he is waiting for a bus. Travel can scroll that scenery, but a fight cannot. If two teams are hitting each other, the forest politely stays put.

Tiny heroes expose every cheat

Once the stage looked like a place, every bad movement became impossible to ignore. A one-hit teamfight looked less like Dota and more like someone switching off a lamp. Ranged heroes wandered into the middle of the brawl. Melee heroes swung at empty air. Creeps vanished between frames. After one fight, survivors from both teams walked away in the same direction like they had agreed the whole thing was a misunderstanding. At another point Centaur attacked enthusiastically from behind his own creep, connecting with absolutely nothing.

Those failures were funny, but they were also excellent design feedback. The choreography became more deliberate: teams approach, melee heroes meet first, ranged heroes keep space, health changes across several exchanges, and casualties happen in order. Winners can advance, defenders can repel a push, and survivors retreat to opposite sides instead of leaving as new friends. Towers, barracks, Roshan, Tormentor, Shrines, and the Ancient stay present while the action happens, so an objective no longer jumps from healthy to destroyed by administrative decision.

The quiet moments needed just as much care. An empty landscape between narration lines is technically calm and visually dead. The stage now fills those gaps with truthful farming, regrouping, movement, or defense, and longer waits accelerate rather than asking you to admire the same bush for half a minute. The goal is not constant noise. It is to make stillness feel intentional instead of forgotten.

Every draft needs its cast

The prototype began with a few familiar faces. That was enough to prove the idea, but a real match can draft anyone. The stage now covers all 127 heroes, with each silhouette built around the details you recognize from across the map: the weapon, the colour blocks, the posture, and occasionally one extremely important hat.

Heroes are only half the story. Lane creeps, jungle camps, towers, barracks, Ancients, Wisdom Shrines, Tormentor, and Roshan give every scene a clear purpose. You should be able to tell whether someone is farming, defending, or taking an objective before reading a word of narration. The art does not need to reproduce every detail from Dota. It needs to make the current moment unmistakable at a glance.

The job is clarity, not cosplay

The Pixel Stage is not trying to recreate a Dota match one spell at a time. It will not teach you the exact angle of a hook or reproduce every animation cancel. Its job is simpler: let you look at the simulator and understand what kind of moment is happening before you finish reading the line beneath it. The Live Map keeps the global truth, the narration keeps the detail, and the stage gives the event a body.

That division of labour is what makes the strip useful. The Pixel Stage tells you what kind of moment is happening, the narration explains how it unfolded, and the Live Map shows where it sits in the wider match. Each view answers a different question instead of repeating the same information in three formats.

Mostly, though, it makes the match more fun to watch. The simulation is still doing the serious work underneath, tracking drafts, timings, map pressure, objectives, and outcomes. Now some very small people act it out on top. If Centaur starts hitting the air again, I fully expect someone to tell me. Until then, the tiny swords are doing their job.

Behind the scenesMatch engineDesign notes