Split the monolithic 5393-line app.js into 32 focused ES modules under modules/ with a thin ~330-line orchestrator. No bundler required — runs in-browser via import maps. Module structure: core/ — scene, ticker, state, theme, audio data/ — gitea, weather, bitcoin, loaders terrain/ — stars, clouds, island effects/ — matrix-rain, energy-beam, lightning, shockwave, rune-ring, gravity-zones panels/ — heatmap, sigil, sovereignty, dual-brain, batcave, earth, agent-board, lora-panel portals/ — portal-system, commit-banners narrative/ — bookshelves, oath, chat utils/ — perlin All files pass node --check. No new dependencies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
45 lines
1.7 KiB
JavaScript
45 lines
1.7 KiB
JavaScript
// modules/utils/perlin.js — Classic Perlin noise for procedural generation
|
|
|
|
export function createPerlinNoise() {
|
|
const p = new Uint8Array(256);
|
|
for (let i = 0; i < 256; i++) p[i] = i;
|
|
let seed = 42;
|
|
function seededRand() {
|
|
seed = (seed * 1664525 + 1013904223) & 0xffffffff;
|
|
return (seed >>> 0) / 0xffffffff;
|
|
}
|
|
for (let i = 255; i > 0; i--) {
|
|
const j = Math.floor(seededRand() * (i + 1));
|
|
const tmp = p[i]; p[i] = p[j]; p[j] = tmp;
|
|
}
|
|
const perm = new Uint8Array(512);
|
|
for (let i = 0; i < 512; i++) perm[i] = p[i & 255];
|
|
|
|
function fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); }
|
|
function lerp(a, b, t) { return a + t * (b - a); }
|
|
function grad(hash, x, y, z) {
|
|
const h = hash & 15;
|
|
const u = h < 8 ? x : y;
|
|
const v = h < 4 ? y : (h === 12 || h === 14) ? x : z;
|
|
return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
|
|
}
|
|
|
|
return function noise(x, y, z) {
|
|
z = z || 0;
|
|
const X = Math.floor(x) & 255, Y = Math.floor(y) & 255, Z = Math.floor(z) & 255;
|
|
x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z);
|
|
const u = fade(x), v = fade(y), w = fade(z);
|
|
const A = perm[X] + Y, AA = perm[A] + Z, AB = perm[A + 1] + Z;
|
|
const B = perm[X + 1] + Y, BA = perm[B] + Z, BB = perm[B + 1] + Z;
|
|
return lerp(
|
|
lerp(lerp(grad(perm[AA], x, y, z ), grad(perm[BA], x-1, y, z ), u),
|
|
lerp(grad(perm[AB], x, y-1, z ), grad(perm[BB], x-1, y-1, z ), u), v),
|
|
lerp(lerp(grad(perm[AA + 1], x, y, z-1), grad(perm[BA + 1], x-1, y, z-1), u),
|
|
lerp(grad(perm[AB + 1], x, y-1, z-1), grad(perm[BB + 1], x-1, y-1, z-1), u), v),
|
|
w
|
|
);
|
|
};
|
|
}
|
|
|
|
export const perlin = createPerlinNoise();
|