Monthly Archives: January 2018

a e s t h e t i c 💫 g e n e r a t o r

Update: the a e s t h e t i c g e n e r a t o r is now online.


Ryan McVerry, Per-Andre Stromhaug, and I got together this weekend to do a mini-hackathon. We’d been inspired by a Chicago-based artist on Tumblr named Galactic Castle. Specifically, this image:

Our goal, was to write python to generate images that looked like Galactic Castle’s. We used the Pillow python library for the most part, messing around with 256×256 arrays of integers, limited to 10 or so colors.

We experimented with a few different rendering techniques, eventually settling on a layered technique. I’ll start with some examples of the finished product, and then a quick walk through some of the fun images we generated along the way. You can run it yourself at

Here are a few shots from the process along the way.

This is one of the first renders we saved. You can see most of the elements coming together, and the dithering in the sky is already in place.

Experimenting with color palettes:

I messed up the color palette:

Getting reflections working. At this point I was doing two things that I eventually stopped doing: reflecting the actual colors (instead, we just use a single color to represent any reflection) and at this point we weren’t doing any sort of layering, so the reflections were crude and unaware of what they were reflecting. In the latest version we use a different algorithm for things above the horizon (mountains, moon) and things in the water (rocks/land).

Better reflections, added a moon.

Re-worked the rocks code. We were originally using polygons that were then filled by PIL. The new code instead generates an enormous int buffer and we manually fill in from the edge. The rocks at the base of the land spits are just handled by keeping track of a number that grows and shrinks, and switching colors when we reach that threshold.

We were originally working at 512×512 (scaling up x4 for the final image), but eventually realized that Galactic Castle works at about 150×150, so we scaled down. The resulting pixelation is much more pleasing. Added trees and improved the mountain cross-hatching.

I hope you enjoy this! You can see it for yourself at

In 2024, I rewrote it in Typescript so that it runs fully in the browser (instead of a thin frontend on a Python backend). Code here 🙂