All articles
Rendering 2026-07-15 · 8 min read

Drawing the artwork at runtime, in code

Every shape in these games is painted on a canvas as it plays. That sounds extravagant, and it is the reason a whole game weighs less than one photograph.

There is no artwork folder in this project. The gems, the bricks, the serpent, the tower blocks and the backgrounds are all drawn by code, every frame, from arithmetic. The only image files in the whole catalogue are the social-sharing covers, which are not part of any game.

Bytes against kilobytes

A single photograph on a typical website is a few hundred kilobytes. A gradient drawn in code is a few dozen characters. When a game's entire budget is under thirty kilobytes, the difference between shipping one texture and describing it is the difference between a fast start and a slow one.

Drawing also scales for free. A vector shape rendered at whatever size the canvas happens to be is sharp on every screen, with no set of pre-rendered resolutions to choose between and no enlargement artefacts on a high-density display.

What a scene is actually made of

Very few of the visuals here need anything beyond rounded rectangles, circles, straight lines and simple polygons. A brick wall is a grid of rounded rectangles with a lighter top edge. A gem is a polygon with a highlight. A serpent is a chain of circles, each slightly smaller than the last. A neon background is two gradients and a grid of thin lines.

The canvas API gives all of that directly, with anti-aliasing included, which means code-drawn artwork does not have to look like a geometry exercise. Adding a soft shadow, a subtle gradient and a one-pixel lighter edge is usually enough to make a rectangle read as a solid object with a lit top.

The cost, and how it is kept down

Described that way, the naive version is expensive: rebuilding gradients and re-issuing hundreds of drawing commands sixty times a second will show up on a slow phone. Three techniques keep it cheap.

  • Build once, reuse. A gradient that never changes is created once and kept, not recreated per frame.
  • Draw to an offscreen canvas. Anything static — a background, a HUD ornament, a repeated icon — is drawn once into a separate canvas and then blitted as a single image.
  • Draw only what changed. A full-screen clear followed by a full redraw is simple and correct; where a scene is mostly static, it is also the slowest option available.

Why not SVG, and why not sprites

SVG would give vector sharpness with markup, but it is the wrong tool for a game: animating thousands of individual DOM nodes is far slower than painting the same shapes into a single canvas, and the browser has to keep a live document tree in step with every frame.

Sprites would make the drawing trivial and the download heavy. They also lock the art to a fixed resolution, which is exactly the problem a vector approach does not have. For games this small, code is the smaller and more flexible option — and as a bonus, the entire art direction is a source file you can diff.

Want to go deeper?

Building something for the browser? Send us a link and we will tell you honestly whether it fits.

Talk to us