SeedCracker Documentation

SeedCrackerX is the reverse path of SeedFinder: give it at least 4 structures with coordinates and it returns the most probable Bedrock world seeds. Everything returns JSON, in a standard list format.

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).

The hosted deployment disables the route. The response is a list with a single entry:
[
  {
    "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

ParameterTypeDefaultDescription
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.

IDNameIDName
1Desert Pyramid 11Ruined Portal
2Jungle Temple 13Ancient City
3Swamp Hut 14Buried Treasure
4Igloo 10Pillager Outpost
5Village 23Trail Ruins
6Ocean Ruin 24Trial Chambers
7Shipwreck
8Ocean Monument
9Woodland 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)

Open request ▸
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]]}
]
The full 32-bit space takes several minutes, so the request stops at 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']}")

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.
  • tolerance is 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 max best seeds by score; a looser tolerance makes many seeds pass - narrow it for a sharper answer.
  • Mineshaft (15) is rejected; tolerance beyond 8 is rejected; max_seconds beyond 120 is capped.