惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Jina AI
Jina AI
WordPress大学
WordPress大学
Recent Announcements
Recent Announcements
G
Google Developers Blog
I
InfoQ
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
MyScale Blog
MyScale Blog
M
MIT News - Artificial intelligence
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
Check Point Blog
J
Java Code Geeks
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
V
Visual Studio Blog
人人都是产品经理
人人都是产品经理
量子位
A
About on SuperTechFans
D
DataBreaches.Net
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

Red Blob Games: latest blog posts

Red Blob Games: Differential heuristics Red Blob Games: Responsive design calculator Red Blob Games: Academic citations Red Blob Games: Highlighting interactive code blocks Red Blob Games: Optimizing page size Red Blob Games: Writing a guide to SDF fonts Red Blob Games: URLs with trailing punctuation Red Blob Games: What I did in 2025 Red Blob Games: Goodbye Sass Goodbye Sass Red Blob Games: RotMG map seeds Red Blob Games: Mapgen4 Mapgen4's use of WebGL2 Red Blob Games: Mapgen4 river shader Red Blob Games: Mapgen4 renderer Red Blob Games: Harnessing ChatGPT hallucinations Red Blob Games: Let Let's write a search engine, part 2 of 2 Red Blob Games: Let Let's write a search engine, part 1 of 2 Red Blob Games: Hexagon conversions Red Blob Games: Mapgen4 trade routes Red Blob Games: Hexagon spiral coordinates Red Blob Games: Thoughts on Flash Red Blob Games: What I did in 2024 Red Blob Games: Hexagon page animations Red Blob Games: SDF Halos SDF Halos Red Blob Games: SDF headless tests, part 2 Red Blob Games: SDF headless tests, part 1
Red Blob Games: De-optimizing mapgen4
2025-04-23 · via Red Blob Games: latest blog posts
Blog post: 22 Apr 2025

Lately I’ve been experimenting with map algorithms. I have three starting points:

Generator Elevation Biomes Rivers Editable?
mapgen1 noise noise down no
mapgen2 distance field distance field down no
mapgen4 noise simulation up yes

(What happened to mapgen3? It was a failure. I had tried to change the programming language, data structures, and algorithms at the same time. I had better luck changing one thing at a time.)

I’d prefer to use mapgen4 for my experiments. But it’s hard.

Mapgen1 and mapgen2 were non-interactive. They had to run at a reasonable speed, but just once. My goal was to have it take less than 1 second. In mapgen4 I wanted every edit to re-run the entire simulation from scratch. I re-calculated the elevation, evaporation, wind, rainfall, biomes, and river flow, and then render the whole thing, ideally in 30ms. But the simulation was far more expensive than what I was using in mapgen1 and mapgen2. It took 30 seconds.

I needed to speed it up by a factor of 1000.

It took a few months in 2018, but I did it. I’m proud of that.

To make the code run faster, I:

  1. Precomputed as much as I could (triangle mesh, polygon vertices, simplex noise, mountain positions, …)
  2. Made assumptions about what algorithms ran, in what order, and what data would not change.
  3. Rendered everything on the GPU instead of on the CPU. Precomputed textures encoding data.
  4. Used multiple threads with message passing (no shared memory or locking back then).
  5. Reduced the resolution of some of the data so that I would have less data to process.
  6. Cached results of some algorithms.
  7. Used fixed-sized arrays of numbers instead of variable-sized arrays of objects.

But all of this made the code hard to work with. I had optimized it to do only the things I needed in mapgen4. It’s hard to change anything, especially at run time, with a slider. And I grew to hate working with that code.

Back in 2019 I posted to twitter[1]:

When I’m working with simple but inefficient code, I can move from design A to B to C easily. When I optimize the code, I’m often pushing myself into a local minima. It’s not only harder to change designs, I often can’t even see the other designs anymore. Mapgen4 is stuck.

Optimization vs flexibility

This also happens to me with abstractions. When I use abstractions early, I push myself into local minima. Harder to change, also harder to see other possibilities. Last year I had to de-abstract the code on my A* page before I could make progress https://simblob.blogspot.com/2020/04/graph-search-diagrams-and-reusable-code.html[2]

The next time I’m working on a map generation project, it will be hard to start from mapgen4 because it’s so optimized into its niche. I hate the code. I’m going to have to de-optimize it first before I can move around in generator design space. Then re-optimize it at the end.

It’s been many years now, and I’m ready to revisit the code. I wanted to experiment with some map algorithms, and tried using mapgen4 as the base. But it was a pain. Drawing a bezier curve or text in webgl is so much more work than drawing it in 2D Canvas. So I thought: what if I drew to a 2D Canvas, and then “draped” that over the mapgen4 map? I tried that back in January. It worked. Mostly. I don’t have the map data in the main thread; it’s only in the worker thread. So I drew to the 2D Canvas in the worker thread, using OffscreenCanvas, a feature that wasn’t available back in 2017 when I started mapgen4, but is available as of 2023. It was a little awkward. And sometimes glitchy. And inconsistent across browsers. It’s good enough for my own experiments but not as good for things I want to share.

So when I wanted to try an actual experiment, I went back to mapgen2. It’s reliable. I tried an experiment to build towns and roads on the map. It was so much easier to work with mapgen2 code than mapgen4 code. But it doesn’t let me paint on the map. And the generation algorithm is designed for Realm of the Mad God[3], not for other projects of mine.

So I decided to start de-optimizing mapgen4. Mapgen2 and mapgen4 share some “DNA”. They’re both built on the same underlying data structures and libraries, but they use different map generation and rendering code. So I tried gluing the mapgen2 renderer onto the mapgen4 generator, and … it worked! For now, I left in the multithreaded part of mapgen4, but I removed all the webgl rendering code and replaced it with mapgen2’s software renderer. There’s plenty more de-optimization I could do, but that’ll be another day.

So try it out! It’s a mapgen2 + mapgen4 hybrid. You can draw on the map like mapgen4 but it will draw in the style of mapgen2. It’s not optimized to the extent mapgen4 was, but I think it’ll be a good place for me to try some map experiments.