KRULZ GAMES / NOTES / NO IMAGE FILES

Build note · 9 September 2026

A WEBSITE WITH|NO IMAGE FILES

Sixteen colours, a character map, and a rule that nothing on this domain may be a picture of itself.

The rule is simple enough to state in one line: nothing on krulz.games is loaded as an image. Not the logo, not the ship, not the enemies, not the explosions, not the nebula behind them, not a single icon and not one letter of the display type. All of it is drawn into a canvas at runtime, from a fixed palette of sixteen colours, by code that ships as text.

The sound follows the same rule. There is no audio file anywhere; every tone is synthesised in the browser through Web Audio. A cold visit to the homepage downloads HTML, one stylesheet, two scripts, and nothing else.

This note is about what that costs, because the benefits are the part everyone guesses correctly and the costs are the part that decides whether it is a good idea for you.

WHY NOT JUST SHIP PNGs

The honest answer is not payload size. A handful of optimised PNGs would weigh less than the code that replaces them, and anybody claiming otherwise is selling something.

The answer is the grid. This is pixel art, which means every shape has to land on whole pixels or it stops being pixel art and starts being a blurry rectangle. Browsers make that hard: a device pixel ratio of 1.25 or 1.5 is common, and a bitmap scaled by 1.25 has to invent five pixels for every four it was given. image-rendering: pixelated helps and does not save you, because the underlying arithmetic still does not divide.

Drawing at runtime moves the decision to where the information is. The code knows the device pixel ratio, picks an integer scale that fits the space available, and rasterises at that scale. The pixel stays square on a phone, on a 4K monitor, and on the odd 1.25 laptop that ruins everything else. That is not a size optimisation; it is a correctness one.

The palette does the second half of the work. Sixteen colours, shared by every page and every game screen, means a new element cannot quietly introduce a seventeenth blue. Consistency stops being a matter of discipline and becomes a matter of what the function will accept.

THE LETTERING IS ALSO NOT A FONT

Display type on this site is drawn from character maps: each glyph is a small grid of set and unset pixels, blitted into a canvas at the same integer scale as everything else. There is no @font-face and no request to a font host.

That has one consequence worth stating plainly, because it is the kind of thing a purely visual approach gets wrong: the text has to stay in the document. A heading rendered into a canvas is, to a search engine or a screen reader, an empty element. So the code that replaces a heading with its drawn version leaves the original string behind in a visually hidden span, and the same applies to the logo, which is a link whose entire contents are a canvas. Without the hidden text it would be a link with no anchor text at all — on every page of the site.

The lesson generalises past pixel art. If you draw your interface, you own the accessibility layer that the browser would otherwise have given you for free.

THE ONE EXCEPTION

There are five PNG files on this domain, in /og/, and they exist because a link shared into a chat window was a blank rectangle. Social preview images cannot be generated by the page: the crawler that fetches them does not run your JavaScript, and it wants a real file at a real URL, 1200×630.

The rule bent rather than broke. The share images are not a separate drawing made in a paint program; they are the same code, run at a different size. A build page renders each one from the very functions that draw the live site — the wordmark and the ship from the homepage kit, the face rig and block lettering from the NodBlocks kit, and Rev Rush from its own palette, its own font and its own rider frame out of the game’s exported data. Scale 6, on a 200×105 grid, which lands exactly on 1200×630.

The result is that the previews cannot drift. When the ship changes shape, the share image changes with it on the next render, because there is no second copy of the ship anywhere to forget about.

A BUG THE APPROACH DOES NOT PROTECT YOU FROM

The two icon files — a 32×32 favicon and a 180×180 touch icon — are also real files, because a browser tab and an iOS home screen both want one before any script has run.

The touch icon was quietly broken for a while. Its PNG data chunk promised 1612 bytes and the file contained 1492: it had been truncated on write, and most viewers happened not to complain. The replacement is generated from the known-good favicon, scaled by exactly five with nearest-neighbour sampling (32×5 = 160) and then padded out to 180 rather than stretched, because 180 divided by 32 is not a whole number and a pixel that stops being square on the home screen has stopped being the logo.

Two small files, and the only two things on the site that could be corrupt without anyone noticing. Generated art has many failure modes; silent truncation is not one of them, which is precisely why the two exceptions deserved the paranoia.

WHAT IT COSTS

Everything above is the good half. The other half:

  • You cannot hire this out. There is no file for a designer to hand you. Every visual change is a code change, which means the studio’s art capacity is exactly its programming capacity.
  • There is no asset pipeline to lean on. No sprite sheets, no texture packer, no CDN with automatic format negotiation. Those tools exist because they solve real problems; opting out means owning those problems.
  • Iteration is slower at the start and faster later. Drawing a new enemy takes longer than drawing one in an editor. The second variant of that enemy takes almost no time at all, because it is a parameter.
  • It only works for one kind of art. This is a sixteen-colour pixel aesthetic. A site that needs photographs needs photographs, and no amount of canvas code changes that.

The constraint earns its keep when the visual language is already procedural. It is a terrible idea imposed on a site whose content is pictures of real things — and that distinction, not the elegance, is the part worth copying.