What I did in 2025

11 min read Original article ↗
Blog post: 29 Dec 2025

It’s time for my annual self review. In last year’s review I said I wanted to spend time learning things for myself, and less time writing for other people. The main themes for 2025 were:

  • playing with text (very broadly)
  • playing with maps (specifically mapgen4)
  • improving my web site

Outside of Red Blob Games work, I had two goals: improve my health and improve my quality of life. So how did the year go? I think it went well.

Since I have forgotten everything I did, I went through my Notion page[1] and my git logs:

for git in $(find . -name .git)
do 
    dir=$(dirname "$git")
    cd "$dir"
    echo ___ "$dir"
    git --no-pager log --since=2025-01-01 --pretty=format:"%as %s%d%n"
    cd - >/dev/null
done

Interpreters/Compilers

The main theme for this year was text. I wanted to be very broad in applying this theme: interpreters/compilers, procedural generation, rendering, language models, text editors, search engines, and anything else related to text. Last year I bought and started reading munificent’s excellent book Crafting Interpreters[2], but it wasn’t until this year that I spent a lot of time on it. It creates a new language, Lox, and then teaches you how to write an interpreter and compiler for it.

  • I implemented the first part, an interpreter. The code samples in the book are in Java, but I used Python instead. When I use the same language as the book/tutorial, I am more likely to copy code without fully understanding it. By using a different language, it forces me to understand the code so that I can reimplement it.
  • I read but didn’t implement the second part, a compiler. I instead used what I learned with Web Assembly (wasm). I hand-compiled some simple code from Lox to wasm, but didn’t tackle the harder topics (closures and function calls). I also compiled some Javascript to wasm, and tried AssemblyScript. I used tools that compile wasm to C and wasm to x86 to understand better what the opcodes do. I wrote partial notes for myself.
  • I’ve made LL(1) and LALR parsers before, and also an LL(1) parser generator which is now a Debian/Ubuntu package[3]. I’ve long been interested in Pratt Parsers[4], and Crafting Interpreters finally got me to try it. Pratt Parsers turn out to be really cool for the “expression” part of a grammar. Also see Oil Shell’s links to Pratt Parsing tutorials[5] and matklad’s blog post[6]. After implementing the lexer and parser, I compiled to wasm, loaded the wasm module at run time, and ran the code.

I also read lots more about interpreters and compilers. I made notes and bookmarks[7]. It’s an endlessly fascinating area to study.

Text

This year’s theme was text, and although intepreters/compilers were a large part of that, I also did other text-related projects.

  • I had explored Signed Distance Field (SDF) font rendering in 2024 but this year I wanted to write a tutorial with a complete working example. Part of the motivation for this is that my blog posts are already showing up in search engines, and those blog posts are “what I tried” and not “what I recommend”. Knowing that my pages are showing up in the Google search results[8] makes me a bit embarassed by the page it’s returning, and I want to make a better one. I had hoped to finish this in 2025 but it’s still incomplete.
  • I wrote a very simple search engine for my site, and wrote about it: Part 1 and Part 2. You can try it here.
  • It seems like everyone’s talking about “AI”, especially Large Language Models (LLMs). Some people have very strong positive or negative feelings about them. I’ve had fairly negative feelings about them for the past ten years and am exhausted. As part of the text theme for this year, I decided I’d look into them a bit more.
  • I made a text editor tool that lets me quickly tweak the SVG of a diagram. I used CodeMirror with a plugin and “attached” it to SVG diagrams on my page. I can then press Alt while dragging the mouse to tweak a number, and see the results. Once I have something I like, I can paste the updated SVG back into the source page. The goal here was that I want to preserve the formatting and comments from the SVG I had hand written, and only make minimal edits with the interactive tool.
  • I started watching for and fixing my text editing annoyances while using Emacs. As a side effect, I’ve been also watching for and fixing annoyances with Linux, Mac, shell, and other tools I use regularly. My computing environment is getting better!

I wanted to work on procedural name generation for maps, which would’ve connected my text projects to my map projects, but didn’t get around to it. That’s ok. I always have more ideas than time.

Maps

Maps are such a rabbit hole for me that I tell myself not to work on map projects unless someone other than me wants me to work on maps. It turns out this year I had two companies approach me about map work, so I gave myself permission to work on my other map projects too.

It was good to play with mapgen4 again, and I started getting ideas of what might go into a mapgen5.

Site Management

This is the second year that I’m using my own home grown blogging software. I like it a lot better than what I was using before. But I didn’t blog as much this year as last year. Part of that was that I was spending a lot of time on my own projects (particularly learning interpreters/compilers) but also because I spent some time working with Jetbolt Games on Galactic Assault Squad[13] and another game studio on an unannounced project.

For the blog but also the rest of the site I’ve been wanting to add tags like “#hexagons”[14] along with browsing by topic. I have hundreds of pages so it’s going to take a while. I’ve made progress on this but want to label more of my site before I add browsing by topic.

My site is older than most any site out there, and most sites don’t last that long. I have around 5000 links from my site to others. A lot of the links I have on my site have broken over the years. I made some good progress on fixing broken links but there’s still more to do. It’s tricky because some links report as good (status 200) but are actually broken in the sense that the content I linked to is gone, replaced by some generic marketing or spam. And some links report as bad (404) but are actually good, with the server reporting 404 to my crawler but 200 to a regular browser. So there’s a lot of manual checking involved.

I continue to update my existing pages. For example this year I improved the conversions and spiral coordinates sections of the Hexagons Guide. I’ve also updated my pages using Flash applets to use Ruffle, and it’s been great to make those experiments available again.

I significantly sped up my web site build. It had been fast initially but as I’ve added more and more to the site (now 26,079 individual files) it’s gotten slower to process. I’ve been rewriting parts of it from using Bash to Python. If I need further optimizations I may use Rust or C++ in places. I’ve also switched my Python projects to use uv[15], which I’m enjoying very much.

I simplified my web site build by removing the Sass compiler. CSS has added the features I had been using from Sass. The build step is now faster, and the pages are slightly smaller.

Next year

I’ve been thinking about how to choose projects[16], and I ask myself:

  1. Is it that I want it done?
  2. Is it that I want to be doing it?
  3. Is it that I want to have done it?

There are often times I want to have done something, but when I sit down to do it, I don’t actually want to do it. That’s ok. And sometimes the problem is that I don’t know how to do it. That’s ok too. But I need to get better at understanding what’s stopping me, and not beating myself up about it. Here are some projects ideas for this year:

  • A specialized text transformation language, using what I learned about interpreters/compilers this year. I’d like to design something specific to make example code for my Hexagon guide. I currently use Haxe macros to generate hexagon code in C++, Python, C#, Haxe, Java, JavaScript, TypeScript, Lua, and Rust.
  • My guide to SDF font rendering.
  • My guide to procedural river generation.
  • Version 2 of my A* page. I have some ideas[17] of how to improve this page. Last time I worked on it, I focusd on the diagrams, but the next round should be focusing on better explanations.
  • Attempt 3 of explaining coordinate transforms. I’ve tried this twice before but didn’t like the results. I have some ideas of how to approach it differently this time.
  • Using SQLite as an ECS (Entity Component System[18]). I’ve long thought of ECS as a rediscovery of the principles of relational databases. It might be interesting to use a relational database directly instead of an ECS as an intermediary.
  • A “first pass” at all the topics ChatGPT falsely thinks I have written. I could spend my time complaining about its hallucinations, or I could instead consider it a list of ideas.
  • A procedural name generator. I want to try something more interesting than Markov chains, and have lots of ideas.

Whichever ones I end up picking, I think they will be a lot of fun. Happy 2026 everyone!