Overview
SeedCracker searches the 32-bit Bedrock seed space in parallel (native
library) and keeps the seeds whose generated structures line up with the
coordinates you provide. The more structures you list - and the tighter
the tolerance - the fewer probable seeds come
back. Because a full sweep is measured in minutes, the request is bounded
by a time budget (max_seconds, default 30);
results are returned even when the search is stopped early.
Availability
SeedCracker runs on the local API only
(http://127.0.0.1:7890, started with
server\start.bat or
server/start.sh).
[
{
"status": "unavailable",
"message": "SeedCracker is not available on Vercel at the moment. This service is too expensive to keep running for free - please donate or use the offline/local version.",
"download": "https://github.com/zebedelu/SeedFinder/releases",
"docs": "/seedcracker/documentation"
}
]
The computation is too expensive to host for free; download the tool from GitHub or run it offline.
Base URL
http://127.0.0.1:7890
Endpoints POST /seedcracker and GET /seedcracker
Both verbs accept the same parameters. POST
uses a JSON body (recommended); GET uses the
query string with structures serialized as
semicolon-separated type,x,z groups.
POST /seedcracker - 400 response:
[
{
"status": "error",
"message": "at least 4 structures are required"
}
]
503 response (native library missing / not loaded):
[
{
"status": "error",
"message": "SeedCracker native library (.dll/.so) not loaded on this server."
}
]
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
structures |
list | — | At least 4 structure objects: {"type": int, "x": int, "z": int}. |
tolerance |
int | 6 |
Distance radius between a listed coordinate and a generated structure, in chunks (0..8). Lower = stronger match. |
units |
string | blocks |
blocks or chunks (chunks are the structure's anchor chunk). |
start |
int | 0 |
First seed to test (inclusive); useful to resume a partial scan. |
end |
int | 4294967296 |
Last seed to test (exclusive); the full Bedrock seed space is 2^32. |
max |
int | 500 |
Result cap (1..2000). The best seeds by fit score are kept. |
max_seconds |
float | 30 |
Time budget in seconds (1..120). Partial results are returned when it expires. |
Request format
The canonical body is a list: the first item is the options object (tolerance and friends live at the root of the list), followed by the structure objects.
[
{"tolerance": 0, "max_seconds": 120},
{"type": 5, "x": -280, "z": 152},
{"type": 5, "x": -280, "z": -360},
{"type": 8, "x": 696, "z": 360},
{"type": 8, "x": 712, "z": 760}
]
An object body with a structures key is accepted too:
{
"tolerance": 0,
"max_seconds": 120,
"structures": [
{"type": 5, "x": -280, "z": 152},
{"type": 5, "x": -280, "z": -360},
{"type": 8, "x": 696, "z": 360},
{"type": 8, "x": 712, "z": 760}
]
}
GET form:
http://127.0.0.1:7890/seedcracker?tolerance=0&max_seconds=120&structures=5,-280,152;5,-280,-360;8,696,360;8,712,760
Response format
The response is always a list. Item 0 is the header
(status: ok,
partial when the time budget ran out,
error or unavailable),
followed by the probable seeds with a score
(sum of squared chunk deviations across structures - lower is better)
and the matched structure chunk coordinates.
[
{
"status": "ok",
"message": "crack completed",
"structures": 4,
"tolerance": 0,
"units": "blocks",
"checked": 16000000,
"elapsed_ms": 2800,
"timed_out": false
},
{
"seed": 8675309,
"score": 0,
"matches": [[-18, 9], [-18, -23], [43, 22], [44, 47]]
}
]
Structure IDs
The cracker accepts the same IDs as SeedFinder, except Mineshaft (15), which uses a per-chunk RNG and cannot be searched by region.
| ID | Name | ID | Name |
|---|---|---|---|
1 | Desert Pyramid | 11 | Ruined Portal |
2 | Jungle Temple | 13 | Ancient City |
3 | Swamp Hut | 14 | Buried Treasure |
4 | Igloo | 10 | Pillager Outpost |
5 | Village | 23 | Trail Ruins |
6 | Ocean Ruin | 24 | Trial Chambers |
7 | Shipwreck | | |
8 | Ocean Monument | | |
9 | Woodland Mansion | |
Live examples (local)
Run the server with server\start.bat, then
run the requests below. Example A cracks the exact seed
8675309 from 2 villages and 2 monuments;
example B uses a 2-chunk tolerance on seed 31415.
Example A - exact crack (tolerance 0)
curl -X POST http://127.0.0.1:7890/seedcracker \
-H "Content-Type: application/json" \
-d '[{"tolerance":0,"max_seconds":120},{"type":5,"x":-280,"z":152},{"type":5,"x":-280,"z":-360},{"type":8,"x":696,"z":360},{"type":8,"x":712,"z":760}]'
Expected response:
[
{"status":"partial","message":"search stopped by time budget - results are partial","structures":4,"tolerance":0,"units":"blocks","checked":660275200,"elapsed_ms":120000,"timed_out":true},
{"seed":8675309,"score":0,"matches":[[-18,9],[-18,-23],[43,22],[44,47]]}
]
max_seconds and returns
"status": "partial" with
"checked" seeds tested so far. The seed is
found early because the sweep starts at seed 0. Run the sweep fully
with "max_seconds": 120 and a named
"start"/"end" range to resume it offline.
Example B - tolerance 2 (4 villages from seed 31415)
curl -X POST http://127.0.0.1:7890/seedcracker \
-H "Content-Type: application/json" \
-d '[{"tolerance":2,"max_seconds":30,"max":50},{"type":5,"x":712,"z":-520},{"type":5,"x":-360,"z":-840},{"type":5,"x":168,"z":1176},{"type":5,"x":136,"z":-1352}]'
Expected response (first item + the top seed):
[
{"status":"partial","message":"search stopped by time budget - results are partial","structures":4,"tolerance":2,"units":"blocks","checked":615841792,"elapsed_ms":120000,"timed_out":true},
{"seed":31415,"score":0,"matches":[[44,-33],[-23,-53],[10,73],[8,-85]]}
]
A looser tolerance admits many seeds (hundreds with a 2-chunk radius).
The best one by score - seed 31415 - is on
top; the matches order follows the order of
the structures you submitted.
Client examples
Pick a language below to see how to call /seedcracker
with requests (Python) or
network.post (Lua, e.g. inside Flarial Client).
import requests
BASE = "http://127.0.0.1:7890"
# Standard list form: options object first, then the structures.
payload = [
{"tolerance": 0, "max_seconds": 120, "max": 50},
{"type": 5, "x": -280, "z": 152},
{"type": 5, "x": -280, "z": -360},
{"type": 8, "x": 696, "z": 360},
{"type": 8, "x": 712, "z": 760},
]
r = requests.post(f"{BASE}/seedcracker", json=payload, timeout=200)
r.raise_for_status()
data = r.json() # list: [header, seed, seed, ...]
print(data[0]) # {"status": "ok", "checked": ..., ...}
for result in data[1:]:
print(f"seed={result['seed']} score={result['score']} matches={result['matches']}")
-- Drop-in for Flarial Client modules. `network` is a Flarial global.
local BASE = "http://127.0.0.1:7890"
local payload = {
{ tolerance = 0, max_seconds = 120, max = 50 },
{ type = 5, x = -280, z = 152 },
{ type = 5, x = -280, z = -360 },
{ type = 8, x = 696, z = 360 },
{ type = 8, x = 712, z = 760 },
}
local resp = network.post(BASE .. "/seedcracker", jsonencode(payload))
if not resp or resp.code ~= 200 then
print("[seedcracker] HTTP error: " .. tostring(resp and resp.code))
return nil
end
print(resp.body) -- JSON list; decode with your JSON lib if needed
Performance & notes
- The search sweeps the 32-bit seed space with as many threads as CPU cores (capped at 64).
- Structures with the smallest generation cell are tested first, so most seeds are rejected after one or two checks.
toleranceis a radius in chunks (Euclidean), default 6. With tolerance 0 a fixed set of coordinates usually maps to a single seed.- The result cap keeps the
maxbest seeds by score; a looser tolerance makes many seeds pass - narrow it for a sharper answer. - Mineshaft (15) is rejected;
tolerancebeyond 8 is rejected;max_secondsbeyond 120 is capped.