Eldritch 2

The Style

Making art is one of my least favorite parts of game development. I’m not good at it, it’s slow (maybe because I’m not good at it), and my best efforts still look subpar (definitely because I’m not good at it). If I were a vampire and could devote a decade or two to immersing myself in art the way I’ve immersed myself in programming and design and music, I could probably git gud. But I’ve got a finite number of years on this rock, and games to make in the meantime.

Five years ago, I started learning Substance Designer. I studied other artists’ graphs and picked up a bunch of neat tricks. I made a template to convert Designer’s material properties into the ones my engine expected, and wrote a custom shader to preview materials in Designer the way they’d look in my engine. I liked the non-destructive workflow, and the logical/mathematical basis for texture creation. But I don’t like being tethered to a proprietary tool. My engine and content pipeline are built on free and open source libraries and tools; and while my old Steam copy of Substance Designer 2019 does still work, it felt like a liability to depend on an app that I can’t run without an internet connection. I stopped using Designer and went back to making textures by hand. But a seed was planted.

I’ve got a Trello board for long-term game and tech ideas—the sort of place I’ll write a card like “Vehicles!” and then sit on it for years until I end up making a game that actually wants or needs vehicles. In December 2022, in the middle of working on Li’l Taffer, fed up with making textures, I wrote a card titled “I should make an offline texture generator using a lot of the standard patterns I’ve used for pixeling stuff.” Wild idea, that would probably never happen. Six months later, I actually started building it.

The fundamental click that helped me jump from a vague idea into writing code was realizing that almost all the textures I was making were built in boxes. I didn’t need to make a texture generator that could do lush organic features; I already lived in the realm of bricks and tiles, and most of what I was doing to make those textures could easily be codified. I drew up a list of use cases that I wanted my texture generator to cover, and 99% of them could be broken down into nested boxes with a few common procedural functions.

So, I started coding! I named the project Piet, inspired by Dutch painter Piet Mondrian’s nested rectangular forms, and I got a proof-of-concept done pretty quickly:

I used to be on Twitter.

And then I got busy with Real Life, and I put Piet (and Eldritch 2) aside for a while. In September 2023, I started working on Schloss der Wölfe, which was my first practical use case for Piet. I added a few features, but struggled to make my proof-of-concept tool deliver the materials I wanted. I made a list of things I needed to improve in the future.

This month, with level generation in the rear view mirror, I’ve finally revisited Piet and checked off all those tasks I’d written last year. The schema is now a proper functional language (i.e., with function calls!), reducing a ton of copy-pasted definitions. I’ve added support for water flow materials and decal materials. And I’ve rewritten my material definitions to be primarily height-based, with other properties like normals and smoothness derived from height.

Screenshot from an early version of Eldritch 2. All materials are generated in Piet.

Why do I do this, when there are existing tools that do this sort of thing better? Maybe I’m just stubborn, or maybe I just enjoy this work. I think it’s the latter. I’m a programmer at heart, and making my little tool with my little domain-specific language… it sparks joy. I’m still bad at art, but at least I’m having fun making it.