01Problem
Players starting a new world want a specific kind of start: a cherry grove at spawn, or a village and a desert temple within walking distance. Most "random seed generators" just print a random 64-bit number. The tools that can actually answer "what's at spawn?" are desktop applications.
Answering it accurately means running Minecraft's world generation, which differs by edition (Java vs. Bedrock) and by version. Doing it for thousands of seeds on a free site means the compute has to happen somewhere other than my servers.
02Build
The core is cubiomes, an open-source C reimplementation of Minecraft's biome and structure generation, wrapped in about 650 lines of my own C (wasm_scanner.c). Together they compile with Emscripten (-O3, modularized, growable memory) into one WASM module that exposes only what the UI needs: scanSeed, scanSeedBedrock, genMap, genStructures, setMcVersion, and a few helpers.
The search page keeps a pool of workers alive and sends them batches of seeds. Each worker filters its batch against the requested biomes and structures (with distance limits) and posts back only the matches. Readiness, batch IDs, errors, and teardown go through a small message protocol, so one crashed worker rejects its own batch instead of hanging the search.
03Challenges
False positives in structure finding
Since 1.18, a structure generation attempt can pass the biome check and still fail on terrain height. A naive finder reports temples that will never generate.
Run the surface-height check too, and pin it with end-to-end tests. One test seed has a desert-pyramid attempt that passes biome but fails terrain, so it must not be reported. Another has two pyramids that pass both, so they must be. Both seeds were verified against cubiomes directly.
64-bit seeds in a 53-bit language
Minecraft seeds are signed 64-bit integers. JavaScript numbers silently lose precision past 253.
Parse seeds as BigInt, normalize to unsigned 64-bit, and split them into two signed 32-bit halves for the C ABI. The C side reassembles the exact seed, so analysis matches what the game generates.
Heavy compute without freezing the page
Scanning seeds for biome and structure matches is CPU-bound, and a seed search can run through thousands of candidates.
Move it off the main thread. The pool size leaves a core free for the UI and caps at four. The worker script loads its own WASM module, and work moves in batches to keep message overhead low.
Editions and versions diverge
Java and Bedrock place structures differently, and generation changed across 1.18 to 1.21.
Separate exported entry points per edition, plus a setMcVersion switch driven by a version table in the UI, so the same module serves every supported combination.
04Impact
- 0server compute per analysis or search. Everything runs on the visitor's device.
- 100,000candidate seeds scanned by the native curation run, keeping the top 50
- 2 × 6editions × version profiles supported by one WASM module
- 100+Playwright end-to-end test cases, including ground-truth accuracy checks
- 58statically generated biome and structure landing pages
Sources: the randomseedgen repository (build scripts, scanner source, test suite). The test count comes from the test files and wasn't re-run for this write-up. Traffic numbers are omitted.
05Stack
- Core
- CcubiomespthreadsMake
- Web runtime
- EmscriptenWebAssemblyWeb WorkersCanvasvanilla JavaScript
- Site
- static HTMLNode build scriptssitemap + OG image generationlocalStorage saved seeds
- Mobile
- Flutterdart:ffiCMake
- Testing
- Playwright