Seed maps rebuild Minecraft's world generation outside the game. You give one a world seed and it draws the biomes and tells you where the villages, strongholds and end cities are. When a seed map is wrong, nothing looks broken. The map is still plausible, and you only find out after walking 2,000 blocks to a desert pyramid the game never generated.
I work on Seedari, a seed map that runs in the browser. Its engine is C, built on cubiomes, and compiled to WebAssembly. This post is about the harness we use to check that engine against the real game, and three things it taught us.
The setup
The check runs only on GitHub Actions. Each job downloads Mojang's dedicated server jar, verifies it against the SHA-1 Mojang publishes, and creates one fresh world per seed with no mods or plugins. Then it talks to the server over RCON. The worlds are deleted when the run ends.
For every seed, the harness asks the server and the engine the same questions:
| Question | Official server | Map engine |
|---|---|---|
| Where is the nearest X? | execute in <dim> positioned <x> 0 <z> run locate structure <id> | the same search, on the shipped WASM in Node |
| Is X really at this spot? | /locate again, positioned at the engine's answer | — |
| Which biome is here? | forceload add, then execute if biome <x> 64 <z> <id> | biome at (x, 64, z) |
| Where is the spawn? | the world spawn saved in level.dat | the engine's spawn search |
Structure ids, tags and placement rules come from the server's own data generator, so both sides use the same list. Each run covers 22 structure types in the Overworld, the Nether and the End, looked up from 3 starting points in every seed, on two versions: Java 26.3 and 1.21.4.
Lesson 1: the placement grid is only half the rule
The first full run put 1,213 of 1,320 structures in the same chunk as the server on 26.3 (91.9%). Almost all of the misses were in a few types:
| Structure | Same chunk, first run |
|---|---|
| End city | 9 / 60 |
| Desert pyramid | 35 / 60 |
| Jungle temple | 49 / 60 |
| Trail ruins | 50 / 60 |
The pattern was the same each time. The engine said a structure starts in a chunk, and the server said there was nothing there.
Minecraft places structures in two stages. First a seeded grid picks one candidate chunk per region. Then the game checks whether the structure can actually stand there. Everyone implements the biome part of that check. The part we had skipped was the ground. Desert pyramids, jungle temples and woodland mansions test the surface height at the corners of their footprint. End cities need enough terrain under them.
Engine 0.3.0 added those rules:
- the surface-height test for desert pyramids, jungle temples and mansions, on the engine's own terrain model;
- cubiomes'
isViableEndCityTerrainfor end cities; - the biome check at the real centre and height of the starting jigsaw piece for trail ruins, abandoned camps and ancient cities;
- the "move below sea level" step for mineshafts before their biome check.
On the same seeds, structures went from 1,213 to 1,320 of 1,320.
Lesson 2: a score on the seeds you tuned on is a training score
Those 1,320 matches came from the seeds whose mismatches we had studied to write the fixes, so they don't tell you much. We needed seeds we had never looked at, picked in a way nobody could have tuned. So we fixed a second set of 20 seeds in advance, by a rule anyone can rerun:
import crypto from 'node:crypto'; const holdoutSeed = (i) => crypto.createHash('sha256') .update(`seedari-holdout-2026-11-10:${i}`) .digest() .readBigInt64BE(0) .toString(); console.log(holdoutSeed(0)); // 7005500739568772969 The harness checks the committed seed list against this rule when it loads. It also refuses a seed that is in both sets. And there is one rule for us: if any engine rule is ever changed because of a mismatch on this set, the set is used up. The next independent number then needs a new prefix and new starting points.
The held-out run on November 10, 2026 compared Java 26.3 and 1.21.4 together:
- structures in the same chunk as the server: 2,580 of 2,580;
- biome points that match at Y 64: 1,198 of 1,200;
- spawn on the same block: 40 of 40.
Lesson 3: /locate doesn't return the nearest structure
The harness actually compares two engine answers. One copies the search order of /locate, and the 2,580 above come from that one. The other is what the map shows people: the nearest structure by distance. These two are often different, because /locate walks outward region by region and returns the first valid structure it finds, which isn't always the closest one.
Take villages on 26.3, on the held-out seeds. In 38 of 60 lookups the map's nearest village and /locate's village were the same. In 20 of them, the map named a village that was closer than the one /locate returned. The last 2 were ties within 16 blocks.
When the two answers differ, the harness runs /locate again, positioned at the map's answer, so the server itself confirms the structure is there. Every one of the map's answers was confirmed. Twice on each version, though, the game had one that was slightly nearer: an ocean ruin and a woodland mansion. In both cases the two answers were within about 20 blocks of the same distance, and the server's was nearer when you measure to the chunk centre. We count those as misses.
What's still wrong
The report lists the gaps too, and these are the ones we know about.
Large Biomes worlds. On the first 10 held-out seeds, 536 of 540 structures land in the same chunk on 26.3 (99.2%), and 9 of 10 spawns are on the same block. Every difference is in a place where the game checks the ground. Three woodland mansions and one desert pyramid stand over a hollow below sea level that the game leaves dry, while the map assumes there is water. The spawn is off because the map's spawn search uses rough heights and passed over dry ground at Y 62.
Bedrock Edition (beta). Bedrock builds Overworld biomes from the same climate noise as Java. On the same 20 held-out seeds, 571 of 600 biome points match the official Bedrock Dedicated Server (95.1%). All 29 misses are on the edge between two biomes, where the map draws the edge a cell or so off. We haven't found the cause yet. The beta map doesn't show structures for Bedrock.
A smaller check you can run yourself
Slime chunks are the easiest piece of world generation to verify. On Java they come from java.util.Random, seeded from the world seed and the chunk position. On Bedrock they don't depend on the world seed at all: MT19937 is seeded from the chunk position alone. I put a standalone slime chunk finder on Hugging Face Spaces that is about 40 lines of JavaScript for both editions. Before publishing it we compared the Java version with cubiomes' isSlimeChunk on 59,085 chunks across 9 seeds, and found no differences. The full map version is Seedari's slime chunk finder.
The per-structure tables, the method and every known gap are in Seedari's accuracy report. If you build tools on top of world generation, I'd recommend this kind of harness: hold some seeds back, and make sure you test against what the real game does.
Not an official Minecraft product. Not approved by or associated with Mojang or Microsoft.



