UYLLII

Blog › Engineering

Engineering

4,500 brick breaker levels from pictures: an image-to-bricks pipeline

By David3 min read
Wrecking Ball feature graphic

I wanted Wrecking Ball's boards to be designed, not random rows of bricks. Designed means thousands of them, because a roguelite run can go a hundred levels deep and nobody wants to see the same board twice. Drawing thousands of brick layouts by hand was never going to happen.

The answer was pictures. Every board is an image turned into bricks: a fox, a lighthouse, a slice of pizza, the Eiffel Tower, a famous painting. The library now has about 4,500.

Where the pictures come from

Open-licensed emoji, first. Twemoji is a complete, consistent set of emoji artwork under CC BY 4.0. A script renders it into 1,188 pictures in 12 themes, mapped from the Unicode emoji groups: animals, sea life, nature, food, travel, landmarks, faces, home, sports, music, holidays and more than 250 country flags. The licence is credited in the game's settings.

Generated pixel art, for the gaps. Emoji can't do famous paintings, castles or real landmarks, so those themes are generated pixel art: about 150 pictures with several variants each, including public-domain famous art reduced to a brick palette.

Shape boards, generated from motifs, fill in about one level in six.

The lesson from the first batch: for content at scale, look for an open-licensed set before generating anything. I'd started generating hundreds of pictures before realising emoji covered most of them better, faster and more consistently. That batch was stopped part-way. Generation is for the gaps and the hero art.

From image to board

Each picture is reduced to the board grid and a small palette, and every cell becomes a brick of that colour. Then:

Difficulty comes from brick health, not board type, so every picture can appear at every depth. A fox at level 3 and a fox at level 90 look the same and play very differently.

The whole library stores compactly as a palette plus one character per cell: 1.8 MB, or 312 KB compressed. The home screen still shows in about 200 ms.

Keeping it varied

My first variety rule said no board could repeat within 40 levels. It worked by board id, and deep runs kept showing the same family of shape boards, "Pocket II" through "Pocket VII": at the hardest difficulty, 21 of 23 shape boards were Pockets. Each counted as a different board.

The rule now works by subject: no fox, no flag of the same country and no shape motif repeats within 40 levels. Each theme also mixes styles: about a third full width, a third inset with side lanes, and a third hollow or carved with pockets and steel channels. The same style never comes twice in a row.

A family-friendly filter

With 1,188 emoji, some aren't right for a family game. A blocklist removes smoking, alcohol, drugs, weapons, death and money. The first version matched any name containing a blocked word, so "pill" also removed the caterpillar. It matches whole words now. Every theme also got a contact sheet, reviewed by eye.

Names in 12 languages

Every board shows its picture's name: Fox, Lighthouse, Mona Lisa. For a while those names were English in every language, because they lived in a data file rather than the game's translation tables. Nobody noticed until the German store screenshots showed English captions under the boards. There are now 1,314 picture names in each of the 12 languages.

The general lesson: any player-visible text in a data file needs translating too, not just the strings in your UI code.