Deterministic world and art generation from token IDs, hashes, or numbers. Same seed = same output, always.
SponsorThe NFT Seed System enables deterministic procedural generation from any input — token IDs, blockchain hashes, or plain numbers. Every seed produces identical output across runs and devices.
setSeed() configures all subsystems (including voxel worlds)Convert any string (hex hash, token ID, arbitrary text) to a deterministic 32-bit unsigned integer seed using FNV-1a hashing. Handles 0x prefix automatically.
const seed1 = createSeedFromHash('0xabc123def456');
const seed2 = createSeedFromHash('my-token-42');
const seed3 = createSeedFromHash('12345');
// Same input always produces the same seed
Create a seeded pseudo-random number generator using xoshiro128**. Returns an RNG object with many utility methods for generating random values deterministically.
const rng = createSeedRNG(42);
rng.random(); // float in [0, 1)
rng.range(1, 100); // integer in [1, 100]
rng.float(0.5, 2.0); // float in [0.5, 2.0)
rng.pick(['a','b','c']); // random element from array
rng.shuffle([1,2,3,4]); // Fisher-Yates shuffle (new array)
rng.gaussian(0, 1); // normal distribution
rng.color(); // random hex color 0x000000-0xffffff
rng.bool(0.7); // true with 70% probability
rng.palette(5); // array of 5 harmonious hex colors
rng.weightedPick(
['common','rare','epic'],
[70, 25, 5]
); // weighted random selection
Map a seed to deterministic traits using a schema definition. Supports categorical (with optional weights), float ranges, int ranges, and boolean traits.
const traits = seedToTraits(42, {
biome: {
values: ['forest', 'desert', 'tundra', 'ocean', 'volcanic'],
weights: [30, 20, 15, 25, 10],
},
elevation: { type: 'float', min: 0, max: 1 },
hasRiver: { type: 'bool', probability: 0.4 },
treeCount: { type: 'int', min: 5, max: 50 },
rarity: {
values: ['common', 'uncommon', 'rare', 'legendary'],
weights: [60, 25, 12, 3],
},
});
// traits = { biome: 'forest', elevation: 0.73, hasRiver: true, ... }
Export ERC-721/1155 compatible JSON metadata from a seed and traits object.
const json = exportSeedMetadata(42, traits, {
name: 'Crystal World #42',
description: 'A unique procedural world',
image: 'ipfs://Qm...',
collection: 'Nova64 Worlds',
});
// Returns JSON with { name, description, image, attributes, properties }
Set the global seed for all Nova64 subsystems. Accepts a number or hash string (auto-converts via FNV-1a). Automatically configures the voxel engine seed if active.
// Set from number
setSeed(42);
// Set from hash
setSeed('0xabc123');
// Set from token ID
setSeed('token-1234');
// Use the global RNG
const rng = getSeedRNG();
const value = rng.random();
Get the current global seed value.
Get the global RNG instance created by setSeed().
setSeed() not called
The RNG object returned by createSeedRNG() provides these methods:
| Method | Returns | Description |
|---|---|---|
rng.random() | float [0, 1) | Uniform random float |
rng.range(min, max) | integer [min, max] | Inclusive integer range |
rng.float(min, max) | float [min, max) | Float in range |
rng.pick(array) | element | Random array element |
rng.shuffle(array) | new array | Fisher-Yates shuffle |
rng.gaussian(mean, std) | float | Normal distribution (Box-Muller) |
rng.color() | 0xRRGGBB | Random hex color |
rng.bool(p) | boolean | True with probability p (default 0.5) |
rng.palette(n) | array of hex | n harmonious colors (analogous/complementary/triadic) |
rng.weightedPick(items, weights) | element | Weighted random selection |
rng.seed | number | Original seed value (property) |
The seedToTraits() schema supports these trait definitions:
| Type | Schema Properties | Output |
|---|---|---|
| Categorical | { values: [...] } | Random element from values |
| Weighted | { values: [...], weights: [...] } | Weighted random pick |
| Float | { type: 'float', min, max } | Float in [min, max) |
| Integer | { type: 'int', min, max } | Integer in [min, max] |
| Boolean | { type: 'bool', probability } | true/false |
let traits, rng;
export function init() {
// Convert token hash to seed
const seed = setSeed('0xdeadbeef1234');
rng = getSeedRNG();
// Generate traits from schema
traits = seedToTraits(seed, {
biome: { values: ['forest','desert','tundra','ocean'], weights: [35,25,20,20] },
elevation: { type: 'float', min: 0.2, max: 0.9 },
hasCaves: { type: 'bool', probability: 0.6 },
treeCount: { type: 'int', min: 10, max: 100 },
});
// Configure voxel world with seed (auto-set by setSeed)
configureVoxelWorld({ renderDistance: 6 });
updateVoxelWorld(0, 0);
// Place seed-deterministic trees
for (let i = 0; i < traits.treeCount; i++) {
const x = rng.range(-80, 80);
const z = rng.range(-80, 80);
const y = getVoxelHighestBlock(x, z);
if (y > 0) placeVoxelTree(x, y, z);
}
}
export function draw() {
print(`Seed: ${getSeed()}`, 10, 10, 0xffffff);
print(`Biome: ${traits.biome}`, 10, 20, 0x00ffff);
print(`Trees: ${traits.treeCount}`, 10, 30, 0x88ff88);
// Press M to export metadata
if (keyp('KeyM')) {
const json = exportSeedMetadata(getSeed(), traits);
console.log(json);
}
}