GUIDES & RESEARCH · 12 MIN READ
Designing Deterministic Generative Art
Deterministic generative art returns the same artistic state when it receives the same input. This lets a token seed identify one work reliably instead of producing an unrelated composition whenever the page reloads.
Reproducibility is not a single switch. An artist must control randomness, input data, execution order, dependencies and the parts of browser rendering that matter to the work.
IN THIS GUIDE
- Use an explicitly seeded PRNG instead of Math.random for artistic decisions.
- The same seed is not enough if random calls occur in an unstable order.
- Separate structural determinism from exact pixel identity.
- Viewport, fonts, floating-point math, GPU shaders and asynchronous loading can change results.
- Test known seeds repeatedly across browsers, dimensions and production builds.
01
What should remain the same?
Determinism begins with a conservation target. For some works, the same seed must produce byte-identical SVG. For others, it must preserve the same palette, geometry and relationships while anti-aliasing varies by browser. Interactive and dynamic works may preserve rules and initial state rather than one frozen frame.
These are different guarantees. A project should say whether its identity lives in exact pixels, vector geometry, a sequence of decisions, a simulation state or a repeatable behavior.
The strongest practical design keeps token-defining decisions deterministic even when presentation details are allowed to adapt to a screen or rendering environment.
02
A seed is input, not randomness by itself
A seed initializes a deterministic process. A pseudorandom number generator expands it into a sequence that appears irregular but can be repeated exactly when the algorithm, seed and call order are the same.
JavaScript’s Math.random is unsuitable for this purpose. MDN notes that its implementation chooses an internal seed that users cannot select or reset, and ECMAScript does not require one common algorithm across engines.
Use a documented PRNG whose implementation is shipped with or recoverable alongside the artwork. p5.js can make random and randomGaussian repeatable with randomSeed, while noise requires its separate noiseSeed function.
03
Convert hashes without losing information
Blockchain projects often provide a 32-byte hexadecimal hash. Converting that entire hash directly with parseInt and storing it as an ordinary JavaScript Number loses precision above 2^53 - 1.
A seed adapter should deliberately map the hash into the state expected by the chosen PRNG: for example, split it into fixed 32-bit words, retain it as BigInt or hash it with a documented domain label. The mapping becomes part of the artwork and must not change silently between versions.
Different streams can be derived for independent concerns. A palette generator and layout generator do not need to consume one fragile global sequence if each receives a stable sub-seed.
const layoutRandom = createPRNG(deriveSeed(hash, "layout"));
const paletteRandom = createPRNG(deriveSeed(hash, "palette"));
const motionRandom = createPRNG(deriveSeed(hash, "motion"));04
The random-call-order trap
A seeded PRNG returns a sequence. Adding one unexpected call near the beginning shifts every later value. This is why a harmless-looking refactor can change an entire collection even when the seed is unchanged.
Unstable loops are a common cause. A collision search that stops after a device-dependent condition, or a loop whose count depends on viewport width, can consume a different number of random values. fxhash’s determinism guidance recommends keeping the number and order of random calls consistent.
Independent streams, precomputed parameter objects and fixed attempt counts make systems easier to reason about. Generate the token’s structural decisions first; render those decisions afterward.
05
Keep the environment out of token identity
Date.now, unseeded randomness, network responses, connected-wallet state and load timing should not influence characteristics that are meant to identify a fixed token. If live data is conceptually necessary, classify the work as state-responsive and document which block or time context is being shown.
Asynchronous code can introduce nondeterministic order even when every source value is stable. Load required assets before generation, await them in a defined sequence and avoid race-dependent mutations of shared state.
A resize should not continue from a partly consumed random stream. Rebuild from the original seed and stored parameters, then project the same composition into the new dimensions.
06
Resolution independence without compositional drift
Artists often want one composition to fit a square preview, a large display and a mobile viewport. Express positions and sizes in normalized coordinates or derive a common scale from the canvas dimensions.
Viewport adaptation should be intentional. If width changes the number of objects, line breaks or random calls, the screen is becoming part of the seed. That can be valid for responsive art, but it is different from showing the same token at another resolution.
A useful test renders one seed at several dimensions and compares its high-level decisions: object count, palette, topology and ordering. Pixel coordinates may scale while identity remains stable.
07
JavaScript and GPU math have limits
ECMAScript precisely defines many basic Number operations, but allows implementation latitude for approximations such as sin, cos, exp and log. MDN therefore warns that some Math results can vary across browser, operating-system or hardware implementations.
WebGL adds GPU, driver and shader-precision differences. Its precision qualifiers specify minimum capabilities rather than universal bit-identical arithmetic. Tiny divergences can become large in chaotic simulations, fractals or feedback systems.
System fonts, text shaping, color management, anti-aliasing and canvas rasterization can also change pixels without changing the artist’s algorithm. Bundle essential fonts, avoid feeding rendered pixels back into token-defining logic and quantize sensitive calculations when exact thresholds matter.
09
A determinism test plan
- Reload the same seed repeatedly in a clean browser context.
- Render a fixed corpus of ordinary, boundary and hand-selected seeds.
- Test Chrome, Firefox and Safari plus representative mobile hardware.
- Test several viewport sizes and device-pixel ratios.
- Test the exact minified production script and stored library versions.
- Record structural parameters separately from screenshot hashes.
- Verify that traits match the live output for every reference seed.
- Fail loudly when a required dependency or input is absent.
Screenshot comparison is useful but should include tolerances when exact raster output is not the intended guarantee. Parameter snapshots catch logical drift; reference renders catch presentation drift. Together they provide a more informative regression suite.
10
Determinism on 256ART
A modern 256ART live document supplies the token ID, stored hash and contract-derived traits to the artist script. Artists should use that preserved hash—or documented values derived from it—for every fixed token decision.
The template emulates inputData during development, but final testing should use the same minified code and libraries that will be placed on-chain. Calls to Math.random, current time or an assumed connected wallet can still break a deterministic project even when the platform provides a stable seed.
Dynamic chain fields are intentionally separate. An artist can keep token identity tied to the hash while allowing motion or environment to respond to ownership and block state. Deterministic does not have to mean visually motionless; it means the rule connecting inputs to behavior is repeatable.
SOURCES AND FURTHER READING
- 01MDN — Math.random
- 02ECMAScript — Math implementation latitude
- 03p5.js — randomSeed
- 04p5.js — noiseSeed
- 05fxhash — Deterministic randomness
- 06Khronos — WebGL specification
- 07256ART — Generative art template
- 08256ART template — Deterministic Random class
- 09256ART template — Local inputData emulator
- 10256ART — Template workflow and deterministic randomness