Skip the terminal and read the text

· runawaydevil , ansi , art

Sixteen Colours and a Registry

The IBM PC text mode gave an artist sixteen foreground colours, eight backgrounds, and 256 shapes. No pixels, no gradients, no partial transparency. A cell was one character in one colour on one background, and that was the whole medium. People made astonishing things with it for twenty years.

Everything drawn for this system works under the same rules. Here is what that means in practice, and what the build does about it.

The vocabulary is smaller than the palette

█ full block     ▓ dark shade
▒ medium shade   ░ light shade

Those four are not textures — they are mixing. Light shade of white on black is a grey that does not exist in the sixteen. Medium shade of bright blue on blue is a blue that is not in the palette either. The entire tonal range of the medium comes out of four characters.

The site's own pieces are held to the CP437 character set, and the validator says so out loud when they wander:

WARN  ornaments   27x4   outside CP437: ▪ ▫ †

Which is how ▪▫▪ became ■·■ and a dagger became . Worth knowing: CP437 has no tilde vowels. It has ç, it has á, it has no ã. That is exactly why a Brazilian on a 1994 board read cora‡Æo instead of coração — and why the webfont here is the "Plus" variant rather than the pure 437 one.

The art is data, and that is deliberate

Original pieces live as typed data rather than as .ANS files on disk, so the compiler and the tests can measure them with the same code that measures every other line in the system. A piece 92 cells wide fails the build instead of arriving crooked.

The format is not lost. npm run art:export writes each piece out as a real .ANS: CP437 bytes, CRLF, a SAUCE record built from the registry, a terminating SUB. They open in PabloDraw and pass through AnsiLove.

Getting that right took two bug fixes worth mentioning, because both destroy art silently:

Nobody's work goes up without their name

Every piece has an entry in src/art/art-registry.yml: author, handle, group, year, licence, original filename, notes. A piece with no entry does not build. When the terms are unclear the entry says reference_only: true, and the validator keeps it out of the build, out of the gallery and out of dist/.

SAUCE records — the 128 bytes the scene stapled to the end of a file with the artist's handle, group and date — are read on import and shown by art info <slug>. They are the reason we still know who drew what, thirty years later.

There is one rule with no exception: an artist's signature is never removed. Not to fit a layout, not to fit the grid. If the signature does not fit in 80 columns, the piece does not go in.

Why it still reads well

A constraint that severe forces an artist to think in shape and value rather than detail. Same discipline as woodcut, as stencil, as any printing process with a limited number of passes. Work made under those rules tends to survive changes in display technology, because it never depended on the display being good.

An ANSI drawn in 1993 on a CRT still looks correct on a 5K panel in 2026. Very little else from 1993 can say that.