Version: v9.10.74 baseline
Prepared by: KAI Engineer session (June 28, 2026)
Purpose: Hand off visual improvements Ryan wants that require deep shader work — particularly planet texture quality, NMS-style atmosphere, and galaxy appearance. Ryan will share screenshots after you finish so he can verify.
---
C:\KAI\kaiverse.js is a Three.js r128 browser 3D explorer — ~5570 lines, LF line endings (not CRLF). It renders a procedural solar system where 9 AI bot agents are planets orbiting a central "KAI Core" star. Ryan flies through it in first-person.
Hard rules you must not violate:
kaiverse.js — surgical byte-replace edits only. Whole-file writes have caused truncation and broken the file before.kaiverse.js must use Python open(f,'rb') + data.replace(old, new, 1) + open(f,'wb') — the file has mixed encoding behavior; the Edit tool will corrupt it.node --check C:\KAI\kaiverse.js and verify output is SYNTAX OK before moving on.nsUpdateCamera movement/throttle — first-person flight controls are sacred.NS_SCALE, NS_BODY, NS_SPREAD, COSMOS — these affect everything.kaiverse-graphics.js file (C:\KAI\kaiverse-graphics.js) contains cloud/atmosphere shader helpers. You can edit it too, same rules.C:\KAI\The KAI Codex.md and C:\KAI\Cargo.toml after each meaningful change. Current version is 9.10.74. Increment minor (e.g., 9.10.75, 9.10.76…).---
These are done, skip them:
1. ✅ Spawn save bug — stale-clear threshold raised from 30M → 4.1B game units so saves at bot planet positions (192M units) are preserved
2. ✅ Nebula follows camera — NS.nebula.position.copy(NS.camera.position) added per-frame so gas clouds don't show parallax
3. ✅ Polar-cap stars — skybox fragment shader now places stars across full sphere (not just galactic plane); starBase = max(0.15, baseIntensity) ensures poles have stars
4. ✅ Bloom threshold lowered from 1.0 → 0.35 so core star actually blooms from far away
5. ✅ Core far-glow sprite — added r*22 size sprite in nsBuildCoreFX() so core is visible from 100M+ km
---
Planets look pixelated/blocky and the texture appears to swim/slide when the camera rotates or moves around the planet.
nsMakePlanetTexture() in kaiverse.js creates a 2D canvas noise texture then UV-maps it onto the sphere (THREE.SphereGeometry). UV-mapped spheres have two problems:
1. The texture resolution is fixed (low); up close it looks pixelated.
2. UV seams and pole-pinching cause the "swim" artifact when rotating.
NMS-style solid rocky/gas surfaces that look real at any distance, with no obvious tiling or swimming.
Replace nsMakePlanetTexture usage with a custom ShaderMaterial that does triplanar projection in the fragment shader — samples noise in 3D object-space (not UV space), so there's no seam and no swim.
Where: kaiverse.js — function nsBuildBodies() around line 2622–2625 for bot/channel nodes:
// Current (bad):
const tex=nsMakePlanetTexture(nsHashStr(n.name), n.kind==='channels'?'exotic':'rock');
mat=new THREE.MeshStandardMaterial({map:tex, bumpMap:tex, bumpScale:22.0, color:col, roughness:0.85, metalness:0.04, emissive:col, emissiveIntensity:0.08});
Replace with a THREE.ShaderMaterial that:
vObjectPos (object-space position passed from vertex shader) for triplanar blendsnoise + fbm functions already present in the skybox shader)n.colorVertex shader minimum:
varying vec3 vObjectPos;
varying vec3 vNormal;
void main() {
vObjectPos = position; // object-space, no UVs needed
vNormal = normalize(normalMatrix * normal);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
Fragment shader minimum:
varying vec3 vObjectPos;
varying vec3 vNormal;
uniform vec3 uColor;
uniform float uSeed;
// [paste snoise() + fbm() here]
void main() {
// triplanar weights from world normal
vec3 blendW = abs(vNormal);
blendW = pow(blendW, vec3(4.0));
blendW /= (blendW.x + blendW.y + blendW.z);
vec3 scaledPos = vObjectPos / (length(vObjectPos) + 0.001) * 3.5 + uSeed;
float nx = fbm(scaledPos.yz);
float ny = fbm(scaledPos.xz);
float nz = fbm(scaledPos.xy);
float noise = nx*blendW.x + ny*blendW.y + nz*blendW.z;
// map noise to color bands
vec3 albedo = uColor * (0.5 + noise * 0.5);
gl_FragColor = vec4(albedo, 1.0);
}
You'll need lights: true or switch to MeshStandard-compatible approach. An easier alternative: use onBeforeCompile to inject triplanar noise into the existing MeshStandardMaterial fragment shader — this preserves PBR lighting.
Make it look like NMS reference:
n.r so all planets look consistent regardless of size---
The reference NMS screenshots show a thick colored atmosphere rim glow that is:
nsMakeAtmosphere() in kaiverse-graphics.js creates a BackSide sphere shell. It uses additive blending. Check its current implementation — it may already be close, but the issue is:
1. Opacity might be too low to see from far
2. The Fresnel calculation might not be strong enough
3. The atmosphere scale might be too small
In kaiverse-graphics.js, find nsMakeAtmosphere and update its shader:
// Fragment: Strong Fresnel atmosphere rim float rim = 1.0 - max(0.0, dot(normalize(vNormal), normalize(vViewDir))); float atmosphere = pow(rim, 2.5); // lower exponent = thicker atmosphere float glow = atmosphere * uIntensity; gl_FragColor = vec4(uAtmoColor * glow, glow * 0.85);
Also:
side: THREE.BackSide (already correct) and transparent: true, depthWrite: falseuIntensity to 2.5–3.5 for vivid NMS-style lookThe atmosphere color per planet type:
Look in nsPlanetDNA() (kaiverse.js) — it determines planet type from seed (rock, gas, ocean, exotic). Map types to atmosphere colors:
ocean → #3af5ff (bright teal/cyan) rock → #ffaa44 (amber/orange) gas → #cc88ff (purple/lavender) exotic → #ff44cc (pink/magenta) n.color tinted toward cyan---
The galaxy band (Milky Way-like backdrop) should be:
Skybox fragment shader: kaiverse.js lines ~742–769 (inside nsBuildStarfield()).
Colors: The current colEdge, colMid, colCore palette is very muted (dark purple/teal). Make it much more vivid:
// Current (muted): vec3 colEdge = vec3(0.02, 0.0, 0.08); vec3 colMid = vec3(0.05, 0.2, 0.45); vec3 colCore = vec3(0.2, 0.6, 0.7); // Target (vivid NMS-style): vec3 colEdge = vec3(0.04, 0.01, 0.18); // deep violet vec3 colMid = vec3(0.12, 0.05, 0.55); // vivid purple vec3 colCore = vec3(0.55, 0.8, 1.0); // bright blue-white core // Add magenta highlight near band center: color += vec3(0.6, 0.1, 0.4) * smoothstep(0.6, 1.0, intensity) * 0.4; // magenta
Galaxy arm structure: Add a spiral-arm modulation to break up the uniform band into distinct arms:
// Spiral arm modulation (add before intensity computation) float angle = atan(dir.z, dir.x); // azimuthal angle in galactic plane float radius = length(dir.xz); // distance from galactic axis float spiralPhase = angle * 2.0 + radius * 8.0; // 2-arm spiral float armMod = 0.5 + 0.5 * cos(spiralPhase); float baseIntensity = exp(-planeDist * 6.0) * (0.6 + armMod * 0.4);
Overall brightness: Increase the alpha so the galaxy band is more opaque/vivid. Change:
gl_FragColor = vec4(color, max(clamp(intensity * 1.2, ...), starAlpha)); // → gl_FragColor = vec4(color * 1.4, max(clamp(intensity * 1.8, 0.0, 1.0), starAlpha));
---
Stars should look like NMS stars:
kaiverse.js lines ~820–835 — THREE.ShaderMaterial for the starfield.
Improvements:
1. Increase point size slightly: size attribute or size multiplier in the vertex shader
2. Add a bloom-like halo in the fragment shader (soft edge falloff per point):
// Fragment: round soft star with bright center vec2 uv = gl_PointCoord - 0.5; float d = length(uv) * 2.0; float star = exp(-d * d * 4.0); // soft gaussian float spike = max(0.0, 1.0 - abs(uv.x)*8.0) * max(0.0, 1.0 - abs(uv.y)*8.0); // cross spike gl_FragColor = vec4(vColor * (star + spike * 0.3), star);
---
v9.10.74 already:
If still not bright enough: increase the far-glow sprite opacity (currently 0.18) and/or add a second even-larger sprite at r*60 with opacity 0.06 for extreme distances.
Also: the n.atmo.visible = d > n.r * 100 condition (line ~3717) hides the inner halo at close range — leave this alone, it prevents blowout when very close.
---
C:\KAI\kaiverse.js | Main 3D engine (~5570 lines, LF endings) |C:\KAI\kaiverse-graphics.js | Cloud/atmosphere ShaderMaterial helpers |C:\KAI\oracle.html | Dashboard HTML that loads kaiverse.js |C:\KAI\The KAI Codex.md | Living manual — must update version + changelog |C:\KAI\Cargo.toml | Version must match Codex |Key function locations in kaiverse.js:
nsBuildStarfield() — skybox shader + starfield Points (~line 660)nsBuildBodies() — planet mesh + material creation (~line 2606)nsBuildCoreFX() — core star rings/rays/sprites (~line 2593)nsMakeAtmosphere() — in kaiverse-graphics.jsnsPlanetDNA() — planet type/traits from seed (somewhere ~line 2550+)nsStreamAmbient() — star wrapping per-frame (~line 1010)---
1. Planet texture triplanar (Issue 1) — most visually impactful, fixes the pixelly swimming look
2. Atmosphere NMS-style (Issue 2) — vivid rim glow visible from space
3. Galaxy colors + spiral arms (Issue 3) — richer background
4. Star quality (Issue 4) — nice but secondary
5. Core brightness (Issue 5) — check if v9.10.74 fixes were enough first
---
After each change, Ryan hard-refreshes the browser (no server restart needed for kaiverse.js). He will send screenshots. Do NOT make multiple changes before he can verify — iterate one issue at a time.
Ryan will send screenshots of what it looks like, then you compare against the NMS reference style: vivid colored planet surfaces, thick atmosphere rim glow visible from orbit, bright galaxy band with spiral arm suggestion.