It’s been a while since I’ve worked on mapgen4 features. In 2018 I declared it finished[1]. I then put it away and worked on other projects. Over the years I have updated the code (es6 modules, typescript, pointer events, boundary points, pnpm) without adding any features. I had been leaving all feature updates for a future map generator.
Last year I decided it was time to start thinking about new features. I started experimenting with some prototypes. That made me realize there are many improvements I’d like to make to mapgen4 before getting into big features.

I made a list. One of the projects on the list is rewriting the renderer. But why?
- Migrate to WebGL2. I started mapgen4 in 2017. WebGL2 wasn’t widely available until 2021[2]. I’d like to use it both for features[3] and performance. I’m using a WebGL1 library, Regl.js[4], which does not support WebGL2[5].
- Reduce load time. Regl.js almost doubles the JS size of mapgen4. I would be able to shrink mapgen4 significantly by switching away from it.
Rewriting the renderer was not something I was looking forward to. It’s work that has to be done in “one shot”, where the intermediate steps aren’t testable. I decided to use an LLM to help me. I rarely use LLMs for coding and learned a lot.
- In this project I used the LLM for translating existing working code from Regl.js to WebGL1. This felt different from having it write new code.
- The resulting code had some subtle bugs. I was able to track some of them down by comparing the output of the original mapgen4 renderer with the rewritten renderer. Having a previous working version was important.
- It got me out of my analysis paralysis. Having something that runs rather than a blank editor window was a huge win.
- I didn’t like the structure of the code it generated. It triggered XKCD 386[6] for me. I ended up replacing all of its code, bit by bit, testing after each change.
Along the way I re-evaluated some of how the renderer worked. For example, I’m using nearest neighbor filtering in many places, even though linear might be better.


GL_NEAREST
vs GL_LINEAR
filteringLook at how much smoother the ocean colors are with linear filtering! But there are blue splotches near rivers. I decided to keep nearest neighbor filtering for now.
I also discovered some bugs, like this one where one edge of the map is jagged, but only noticeable when the camera is rotated and zoomed in:

Overall, I don’t think the LLM saved me any time. I didn’t end up keeping the code it gave me. But it got me unstuck, and that meant I actually made progress.
The main benefit of the rewrite was size:
File | Size before | Size after |
---|---|---|
_worker.js | 18543 | 18579 |
_bundle.js | 150672 | 69469 |
(total) | 169215 | 88048 |
The secondary benefits are that I got to revisit some of the decisions I made, I found some bugs, and I got unstuck. I didn’t stop at the main renderer. I also rewrote the river renderer, which saved another 8666 bytes. That’s for the next blog post.