Eight Sprites

Everyone who played a Nintendo watched characters blink in and out when the screen got busy. The number behind it is famous: eight sprites on a scanline, and the ninth is not drawn. What is almost never said is that eight is not a rule anybody chose. It is 32 bytes of buffer divided by 4 bytes a sprite.

One scanline, and what fits on it

Each square is a sprite on one line of the screen, numbered by its place in the sprite list. Add more than eight and watch which ones stop being drawn.

drawn
8 of 12
dropped
4: 8, 9, 10, 11
frame
0

Over the limit. The last 4 never appear at all, on any frame.

Eight is a buffer, not a budget

The PPU keeps the sprite list in a memory called OAM: sixty-four sprites, four bytes each, two hundred and fifty-six bytes in total. That is the whole cast of a frame.

A scanline is drawn from a second, smaller memory. The PPU has thirty-two bytes of secondary OAM, which nesdev describes as enough for 8 sprites, and the program cannot touch it. Before each visible line the PPU wipes those thirty-two bytes and then walks the sixty-four entries of OAM in order, copying across every sprite whose rows cover the line about to be drawn.

Eight is what you get when you divide one of those numbers by the other. The ninth sprite is not judged, deprioritised or skipped for speed. The walk reaches it and there is no room left, so it is simply not in the list the line gets drawn from.

Why they flickered instead of vanishing

Two things above do the work together. The eight that survive are the first eight the walk finds, and the order it walks is the order they sit in OAM. That same order decides what draws in front of what: the sprite that comes first covers the ones after it.

So the order is not a detail, it is a priority list, and a game can rewrite it whenever it likes. Rewrite it every frame and a different eight win each time. Turn the switch on above and the readout stops saying that four sprites never appear and starts saying every sprite appears on two thirds of frames, because with twelve sprites and eight slots that is exactly what happens.

Rodrigo Copetti names the technique, OAM order rotation, and does not oversell it: the sprites appear to flicker on-screen. That is the trade. A permanent absence becomes an intermittent one, and a generation read the intermittence as the machine straining.

What is real here, and what is not

This is one rule, not an emulator

Nothing here runs a 6502 or a PPU. The page implements sprite evaluation and nothing else: walk the list in order, take the first eight that fall on the line, drop the rest. Real sprite evaluation also has cycle timing, an eight-by-sixteen mode, a y range that is off by one, and a first scanline where no sprite is ever drawn. None of that changes the number this page is about, and none of it is modelled.

The eight is derived, not typed

The code holds thirty-two bytes of secondary OAM and four bytes per sprite, and divides. If either number were wrong the page would show a different limit rather than quietly showing eight anyway, which is the point of deriving it: the claim the page makes is that eight is a consequence, so eight had better be computed like one.

The fairness figure is measured over frames, not asserted

When rotation is on, the page says what share of frames each sprite is drawn on. That number is produced by running the evaluation over a full cycle of frames and counting, not by printing eight divided by the sprite count. They agree, which is the point; if the rotation were implemented wrongly they would not, and the page would say the wrong thing out loud instead of hiding it behind a formula.

The hardware's own alarm for this does not work

There is a bit for it. PPUSTATUS bit 5, sprite overflow, was meant to be set whenever more than eight sprites land on a line. It does not do that. In nesdev's words: the logic for detecting this does not work correctly, resulting in the PPU checking incorrect indices in OAM when searching for a 9th sprite. This produces both false positives and false negatives. A machine with a limit, and a broken detector for its own limit, is worth saying plainly rather than tidying away.

Nobody who made this chip ever wrote it down

There is no datasheet. Nintendo and Ricoh published nothing about the 2C02's internals, and there is no standard and no patent to fall back on: searching for one turns up a 1985 patent describing a raster line buffer for sprites that belongs to Commodore's Amiga, not to this machine at all. Everything on this page comes from people decapping the chip, photographing the die, pulling a netlist out of the photographs, and testing behaviour against real hardware. For silicon nobody documented, that work is the primary literature rather than a substitute for it, and this site's source gate was taught the distinction while this page was being built.

Rotating by one is the simplest version of a real technique

Games did this in many ways, and some rotated only the sprites of one object, or swapped halves, or reordered on a schedule tied to what mattered that frame. The page rotates the whole list by one position per frame because that is the shortest thing that shows the effect. It is a real technique shown in its simplest form, not the way any particular game did it.

Nothing moves unless you ask it to

The frames advance only when you press a button, and stop when you press it again. A page about flicker that flickers at you on arrival would be a worse page, and there is no reading of it that needs motion to be automatic.

Sources