Proposal: Noise generators standard library (Noise.* — Perlin/Simplex/Cellular, fBm, domain warp), deterministic fixed-point #3
Labels
No labels
area:ci
area:docs
area:input
area:net
area:rendering
area:repo
area:stdlib
area:tooling
area:types
cleanup
dx
priority:high
priority:low
priority:medium
proposal
status:in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: workshopsoft/ludic#3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Procedural generation is a core game-dev tool — terrain, caves, biomes, textures, clouds, wind, placement — and it all rests on noise. Ludic has none today. This proposes a
Noise.*standard-library namespace, researched against FastNoiseLite / FastNoise2 (the de-facto game noise library, also what Godot ships asFastNoiseLite) and OpenSimplex2.Noise types (FastNoiseLite set)
valueperlinsimplex/simplex_smooth(OpenSimplex2)cellular/worleyF1/F2and a cell idwhite/hashFractal layering (fBm) and warping
octaves,lacunarity(freq step),gain/persistence(amplitude step); variants fBm, ridged, billow.API sketch
sample1/sample3too (sample3= 2D + time for animated fields, or caves).fixed, normalized to[-1, 1](with a[0,1]helperNoise.unit(...)).Random.stream("worldgen")(see #2) so worldgen RNG never desyncs gameplay RNG.Game use-cases
Terrain heightmaps, cave systems (3D/ridged), biome maps (cellular), texture/detail, cloud/fog fields, wind and screen-shake modulation, procedural placement (trees/loot) — combined with chunk streaming, enough for infinite worlds.
Phasing
value2/perlin2/simplex2+ seed.octaves/lacunarity/gain) +Noise.newhandle.cellular2(Worley) +ridged/billow.sample3,sample1.References
FastNoiseLiteRandom.streamin #2;fixed/vec2in #1.Determinism-first fixed-point noise, tailored to reproducible procedural worlds.
Done in commit
a4f1494.Added the
Noise.*namespace — deterministic, fixed-point (Q16.16) procedural noise over an integer permutation hash seeded from an explicit seed, so a seed reproduces the exact same field on every platform and run (the determinism edge this issue calls for):Noise.value2(x, y, seed)— value/lattice noiseNoise.perlin2(x, y, seed)— classic gradient noise (exactly 0 at integer lattice points)Noise.simplex2(x, y, seed)— organic simplex noise (the recommended default)Noise.fbm2(x, y, seed, octaves)— fractal Brownian motion (octaves of simplex, lacunarity 2 / gain 0.5, normalised)Noise.cellular2(x, y, seed)— Worley F1 distance;Noise.cellular2_id(...)— nearest-cell idNoise.unit(n)— remap [-1,1] to [0,1]All pure integer IR, C-free; outputs are
fixedin [-1,1]. cellular/fbm reuse the math prelude'sfx_sqrt.Phasing:
Also not yet: the stateful
Noise.new(...)generator handle (the one-shot helpers cover the same ground for now). These remain as follow-ups.Tests:
examples/library/noise.ludicasserts the invariants a fixed-point generator must hold — Perlin == 0 at lattice points, every sampler stays within [-1,1], reproducibility, seed sensitivity, non-negative cellular distance — wired intox test. Docs: newdocs/language/noise/section. (A float reference can't be matched bit-for-bit — that difference is the whole point — so tests assert structural invariants + determinism.)