Version 1.1.0 · algorithm v1
esinxe is a polyglot deterministic random field for procedural software. Give it a seed and a structured key, and it returns the same value in Python, C, C++, C#, Ruby, JavaScript/TypeScript, Rust, Go, Java, and Kotlin. No prior values need to be generated, and work can be split across machines without changing the result.
import esinxe
world = esinxe.Random(20260611)
height = world.at2D(chunk_x, chunk_y, "terrain")
enemy = world.choose(
["archer", "scout", "guardian"],
"enemy",
esinxe.i64(chunk_x),
esinxe.i64(chunk_y),
)
loot = world.weightedChoice(
["common", "rare", "legendary"],
[80, 18, 2],
"loot",
esinxe.i64(chunk_x),
esinxe.i64(chunk_y),
)The output is intentionally predictable. esinxe is not cryptographic. Never use it for secrets, tokens, gambling, lotteries, or security decisions.
| Need | Start here |
|---|---|
| Explore a streamed procedural world | Play Verdant / run locally |
| Install and verify a package | Installation guide |
| Compare measured alternatives | Practical workload evidence |
| Copy a language example | Language quick starts |
| Understand every operation | API reference |
| Compare language boundaries | Port capability matrix |
| Use scoped fields and reusable helpers | Portable helper supplement |
| Implement or verify a port | Algorithm v1 specification |
| Understand design boundaries | Architecture |
| Review statistical evidence | RNG analysis |
| Contribute a change | Contributing guide |
| Report a vulnerability | Security policy |
The practical niche is reproducible content addressed by durable IDs, especially when multiple languages must agree. A stable digest plus your own key encoding can serve the same underlying purpose; esinxe supplies a frozen typed encoding, portable helpers, and conformance fixtures. Its value is that shared contract. The world integration demonstrates it, and the comparison records the costs and limits.
- Generate a world chunk independently while keeping borders and content stable.
- Regenerate loot, encounters, fixtures, or test data from durable identifiers.
- Partition simulation or sampling jobs without assigning mutable RNG streams.
- Add or remove unrelated generated features without shifting existing results.
- Reproduce a failure from the exact seed and structured key that produced it.
esinxe is not a noise library: adjacent coordinates are separately addressed, not spatially smoothed. It is also not a replacement for a scientifically validated Monte Carlo generator. A future noise module can build spatial interpolation on top of this keyed core without changing algorithm v1.
Each seeded field provides:
raw(key...): full unsigned 64-bit value.int(max, key...): deterministic bounded[0, max)integer.range(min, max, key...): deterministic bounded[min, max)integer.float01(key...): upper 53 bits mapped to[0, 1).at2D(x, y, namespace?)andat3D(x, y, z, namespace?).chanceRatio(numerator, denominator, key...).choose(items, key...).stableChoice(items, ids, key...): preserve selections when candidates reorder; additions change only assignments won by the new stable ID.shuffle(items, key...): deterministic Fisher-Yates copy.weightedChoice(items, integerWeights, key...).
Structured keys support signed int64, unsigned uint64, UTF-8 strings, and bytes. Use explicit signed/unsigned constructors in compatibility-sensitive code. Integer weights and rational probabilities are the portable conformance surface; floating wrappers are deliberately excluded.
The frozen reducer uses deterministic rejection/remixing, not fresh independent random draws. Exact uniformity and statistical independence are not guaranteed; see the statistical limitations.
The formal byte encoding, FNV-1a pass, rejection sampling, mixer, domains, and
error rules are frozen in SPEC_V1.md. Golden outputs live in
tests/vectors-v1.json and are generated by
scripts/generate_vectors.py.
The original Next* family remains compatible:
Next()/NextRaw()advance a stream.NextAt(offset)/NextRawAt(offset)address an offset directly.NextMax*,NextMinMax*, and list helpers retain their existing behavior.
Keyed calls read only the seed and never alter stream position.
Use the hosted deterministic field inspector, or run it locally:
python3 -m http.server 8765Then visit http://localhost:8765/demo/. Change the seed, namespace, display
mode, and language snippet while inspecting the same deterministic 2D field.
Per-language examples are collected in docs/QUICK_STARTS.md. Runnable Python examples cover procedural world content and partition-independent jobs.
Python 3.9 on Apple silicon, best of five, 200,000 values, native extension enabled. These categories are intentionally separated because keyed hashing, stream stepping, and native batches solve different jobs.
| Category | Operation | Values/second |
|---|---|---|
| Random access | raw(u64(i)) |
147,813 |
| Random access | NextRawAt(i) |
727,349 |
| Sequential | NextRaw() |
756,255 |
| Sequential | Next() |
365,370 |
| Sequential | NextMax(100) |
435,483 |
| Batch | NextList(N) |
11,778,823 |
| Batch | NextListMax(N, 100) |
54,397,109 |
Regenerate locally with:
python3 setup.py build_ext --inplace
ESINXE_BENCH_N=200000 python3 scripts/benchmark.pyThe repository is the source of truth until registry access is available.
| Port | Version | Registry status | Source install |
|---|---|---|---|
| Python | 1.1.0 | Not published | python3 -m pip install -e . |
| JavaScript/TypeScript | 1.1.0 | Not published | import JavaScript/src/index.js |
| Rust | 1.1.0 | Not published | path dependency on Rust/ |
| Go | algorithm v1 | Not published | local module under Go/ |
| Java/Kotlin | algorithm v1 | Not published | compile sources under JVM/ |
| C/C++/C#/Ruby | algorithm v1 | Not published | include/load repository sources |
The historical Python/Esinxepy1-0-0.py filename remains a compatibility shim.
All ten ports also provide scoped fields, sampling without replacement, and prepared weighted choices. These additions preserve every existing v1 output.
world = esinxe.Random(20260611)
terrain = world.scope("terrain")
height = terrain.raw(esinxe.i64(-4), esinxe.i64(9))
# Same result as world.raw("terrain", esinxe.i64(-4), esinxe.i64(9)).
party = world.sample(["archer", "scout", "guardian", "healer"], 2, "party")
loot = world.prepareWeightedChoice(["common", "rare", "legendary"], [80, 18, 2])
drop = loot.choose("room", esinxe.i64(7))Scopes and prepared tables snapshot the seed and prefix. Sampling copies its
input; repeated counts share the same deterministic permutation. Prepared choices
match weightedChoice while reusing validation and cumulative weights. See the
helper contract and port names and limits.
Python wheels include generic type declarations and py.typed.
Run all available compiler, conformance, statistical, native-extension, and packaging checks:
./scripts/ci.shThe script explicitly names missing toolchains instead of treating them as a pass. Statistical conclusions remain bounded to the included sample sizes; see docs/RNG_ANALYSIS.md for the practical quality verdict.
On Windows, use python -m unittest discover -s tests -v after building the
optional extension with python setup.py build_ext --inplace. Compiler discovery
supports GCC/Clang and CC/CXX overrides. CI exercises all ports on Windows and
Linux, installed Python/Rust packages, and documented minimum runtimes. The
shared corpus is generated independently of the
reference package and consumed across the ports.
Algorithm compatibility follows the versioning policy. Changes are recorded in the changelog, releases follow the release checklist, and community help is described in SUPPORT.md. Contributions are governed by the Code of Conduct.