I spent 24 days digging into the code of {Shan, Shui}* Chinese painting generator and lived to tell the story.

This article is written for my Substack, you can subscribe to it by email now!

While a lot of fellow developers spent this year’s advent on solving this year’s Advent of Code puzzles, I decided to have my own little “advent.”

A few weeks before December, I’ve stumbled upon an awesome generative art project by developer and artist Lingong Huang. It generates infinite (and surprisingly varying) scrolls of Chinese paintings like this:

It struck me with its beauty—as well as with the fact that I don’t have the slightest idea of how it might work. After half-an-hour looking into the code, I knew I wanted to have some level of understanding of how those things are done in general—and this one, in particular—enough to spend some hours on it. So, I thought, let it be my “advent”—and that happened.

Trying to understand

My usual way to understand how others’ code works is to translate it into another language. I did quite a few projects of this kind. And deciding on what language to translate it to, I made a weird decision: to just rewrite (some parts of the) {Shan, Shui}* in the same JavaScript—but using modern features of the latest versions and semi-functional style of chained computations I am fond of.

This is not to say the original author’s code was “bad,” and I made it “good”—nothing of the kind. I just experimented with how things might be expressed so they would be closer to my reading/writing habits—just as some goal making me understand them.

The result of the project is the diary below. By the end of 24 advent days, I haven’t seen/read/rewritten all parts of the algorithm—that would require trice this amount of time, probably. But I went through all the layers of the picture and got some understanding on how things are done there—from a singular brushstroke to generating a whole mountain with a small village and a forest. And I didn’t lose my awe, and I am trying to pass it to others.

For the impatient: you can probably just go through the day 1 intro and then go immediately to day 24 with the overview of everything I’ve understood on the road. But I hope that reading through the whole diary might also be of some fun. There are small philosophical bits here and there, too, discussing how the code might be written, and it can be either insightful or repulsing, or both.

Note that JS is not my mother tongue. While using modern features for better expression of the meaning, I probably still went far for the modern preferred JS style: say, I dropped a lot of vars everywhere (never bothering with let/const, though I probably should’ve) and didn’t use any linter/autoformatter. So it might be a somewhat painful reading or a JS developer by trade.

And English is not my first language either. Usually, I use at least Grammarly to make sure the texts are decent… But with the amount of work this project brought, I can only promise the diary was spellchecked. Have mercy.

So, here goes!

The diary of grokking!

PS

You know what? I have a Substack now! And a lot of plans for writings for the upcoming year.