Function bodies 69 total
createPlaneModel function · javascript · L8-L194 (187 LOC)js/aircraft.js
function createPlaneModel() {
const group = new THREE.Group();
const hullColor = 0x0a1a1a;
const neonColor = 0x00ffaa;
const neonOrange = 0xff6600;
// ---- Hull material (shared) ----
const hullMat = new THREE.MeshStandardMaterial({
color: hullColor, emissive: neonColor, emissiveIntensity: 0.12,
metalness: 0.9, roughness: 0.2
});
const trimMat = new THREE.MeshBasicMaterial({ color: neonColor });
// ---- Main fuselage: tapered lifting body ----
// Wide at the back, narrow at the nose — like a flattened wedge
const fuseGeo = new THREE.BufferGeometry();
const verts = new Float32Array([
// Top face (4 verts: nose tip, left shoulder, right shoulder, tail center-top)
0, 0.3, -4, // 0: nose tip (front)
-2.5, 0.4, 3, // 1: left rear shoulder
2.5, 0.4, 3, // 2: right rear shoulder
0, 0.3, 4, // 3: tail top center
// Bottom face (4 verts: nose tip bottom, left bottom, right bottom, tail bottom)
0, -0.2, -4, initAudio function · javascript · L12-L83 (72 LOC)js/audio.js
function initAudio() {
if (audioInitialized) return;
try {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
} catch (e) { return; }
audioInitialized = true;
// --- Engine drone: two detuned sawtooth oscillators ---
engineGain = audioCtx.createGain();
engineGain.gain.value = 0;
engineGain.connect(audioCtx.destination);
const engineFilter = audioCtx.createBiquadFilter();
engineFilter.type = 'lowpass';
engineFilter.frequency.value = 800;
engineFilter.Q.value = 1;
engineFilter.connect(engineGain);
engineOsc1 = audioCtx.createOscillator();
engineOsc1.type = 'sawtooth';
engineOsc1.frequency.value = 80;
engineOsc1.connect(engineFilter);
engineOsc1.start();
engineOsc2 = audioCtx.createOscillator();
engineOsc2.type = 'sawtooth';
engineOsc2.frequency.value = 82;
engineOsc2.detune.value = 15;
const osc2Gain = audioCtx.createGain();
osc2Gain.gain.value = 0.4;
engineOsc2.connect(osc2Gain);
osc2Gain.connect(engineFilter)updateAudio function · javascript · L85-L116 (32 LOC)js/audio.js
function updateAudio(dt) {
if (!audioCtx || audioCtx.state === 'suspended') return;
// Guard against NaN from physics — prevent audio errors
if (isNaN(STATE.speed)) return;
const t = audioCtx.currentTime;
const speed = STATE.speed;
const throttle = STATE.throttle;
// Engine: pitch from 60–200 Hz based on throttle + speed, volume from throttle
const engineFreq = 60 + throttle * 80 + Math.min(speed * 0.15, 60);
engineOsc1.frequency.setTargetAtTime(engineFreq, t, 0.1);
engineOsc2.frequency.setTargetAtTime(engineFreq * 1.02, t, 0.1);
engineGain.gain.setTargetAtTime(0.04 + throttle * 0.1, t, 0.08);
// Wind: volume and filter frequency from speed
const windVol = Math.min(speed / 200, 1) * 0.12;
windGain.gain.setTargetAtTime(windVol, t, 0.15);
windFilter.frequency.setTargetAtTime(300 + Math.min(speed * 3, 2500), t, 0.1);
// Stall warning: pulse at stallRatio > 0.85 (only in atmosphere)
const stallRatio = Math.abs(STATE.angleOfAttack) / PHYS.stallAlpha;
playWeaponSound function · javascript · L118-L169 (52 LOC)js/audio.js
function playWeaponSound(weaponName) {
if (!audioCtx) return;
if (audioCtx.state === 'suspended') audioCtx.resume();
if (weaponName === 'MG') {
// Short noise burst — gunshot
const dur = 0.04;
const buf = audioCtx.createBuffer(1, audioCtx.sampleRate * dur, audioCtx.sampleRate);
const d = buf.getChannelData(0);
for (let i = 0; i < d.length; i++) {
d[i] = (Math.random() * 2 - 1) * (1 - i / d.length);
}
const src = audioCtx.createBufferSource();
src.buffer = buf;
const g = audioCtx.createGain();
g.gain.setValueAtTime(0.15, audioCtx.currentTime);
g.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + dur);
const hp = audioCtx.createBiquadFilter();
hp.type = 'highpass';
hp.frequency.value = 800;
src.connect(hp);
hp.connect(g);
g.connect(audioCtx.destination);
src.start();
} else if (weaponName === 'MISSILE') {
// Swept sine — whoosh
const osc = audioCtx.createOscillator();
osc.type playExplosionSound function · javascript · L171-L221 (51 LOC)js/audio.js
function playExplosionSound(x, y, z, damage) {
if (!audioCtx) return;
if (audioCtx.state === 'suspended') audioCtx.resume();
// Distance attenuation from player
const dx = x - playerObj.position.x;
const dy = y - playerObj.position.y;
const dz = z - playerObj.position.z;
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
const volume = Math.max(0.01, Math.min(0.3, 0.3 * (1 - dist / 3000)));
// Delay based on distance (speed of sound ~340 m/s), capped
const delay = Math.min(dist / 340, 1.5);
const t = audioCtx.currentTime + delay;
// Low boom oscillator
const osc = audioCtx.createOscillator();
osc.type = 'sine';
const boomFreq = 40 + damage * 0.5;
osc.frequency.setValueAtTime(boomFreq, t);
osc.frequency.exponentialRampToValueAtTime(20, t + 0.5);
const oscGain = audioCtx.createGain();
oscGain.gain.setValueAtTime(volume, t);
oscGain.gain.exponentialRampToValueAtTime(0.001, t + 0.6);
osc.connect(oscGain);
oscGain.connect(audioCtx.destinationplayClickSound function · javascript · L223-L235 (13 LOC)js/audio.js
function playClickSound() {
if (!audioCtx) return;
const osc = audioCtx.createOscillator();
osc.type = 'sine';
osc.frequency.value = 1200;
const g = audioCtx.createGain();
g.gain.setValueAtTime(0.06, audioCtx.currentTime);
g.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.04);
osc.connect(g);
g.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + 0.05);
}airDensityAtAlt function · javascript · L10-L13 (4 LOC)js/flight.js
function airDensityAtAlt(alt) {
const T = 288.15 - 0.0065 * Math.min(Math.max(alt, 0), 11000);
return 1.225 * Math.pow(T / 288.15, 4.256);
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
liftCoefficient function · javascript · L15-L23 (9 LOC)js/flight.js
function liftCoefficient(alpha) {
const absA = Math.abs(alpha);
const sign = Math.sign(alpha);
if (absA < PHYS.stallAlpha) {
return PHYS.liftSlope * alpha;
}
const stalled = PHYS.maxCL * PHYS.postStallDropoff * Math.sin(2 * absA);
return stalled * sign;
}startGame function · javascript · L4-L44 (41 LOC)js/game.js
function startGame() {
initAudio();
if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume();
document.getElementById('main-menu').style.display = 'none';
// Reset flight state
playerObj.position.set(0, 200, 0);
playerObj.quaternion.identity();
STATE.velocity.set(0, 0, -30); // start with some forward speed
STATE.angularVelocity.set(0, 0, 0);
STATE.speed = 30;
STATE.altitude = 200;
STATE.angleOfAttack = 0;
STATE.gForce = 1;
STATE.braking = false;
STATE.throttle = 0.4; // start with some throttle
STATE.mouseX = 0;
STATE.mouseY = 0;
STATE.freelook = false;
STATE.freelookX = 0;
STATE.freelookY = 0;
STATE.chaseDist = 18;
STATE.firing = false;
smoothPitch = 0; smoothRoll = 0; smoothYaw = 0;
shakeAmount = 0;
// Reset camera to behind the spawn point (world space)
camera.position.set(0, 201, 1);
camera.lookAt(0, 200, 0);
camera.fov = 60;
camera.updateProjectionMatrix();
// Reset ammo and health
STATE.weapons.types.forEach(w showBuilder function · javascript · L46-L51 (6 LOC)js/game.js
function showBuilder() {
document.getElementById('main-menu').style.display = 'none';
document.getElementById('builder-menu').style.display = 'flex';
recalcStats();
renderBuilder();
}hideBuilder function · javascript · L53-L56 (4 LOC)js/game.js
function hideBuilder() {
document.getElementById('builder-menu').style.display = 'none';
document.getElementById('main-menu').style.display = 'flex';
}applyBuild function · javascript · L58-L61 (4 LOC)js/game.js
function applyBuild() {
recalcStats();
hideBuilder();
}showControls function · javascript · L63-L67 (5 LOC)js/game.js
function showControls() {
document.getElementById('main-menu').style.display = 'none';
document.getElementById('controls-menu').style.display = 'flex';
renderKeyBindings();
}hideControls function · javascript · L69-L72 (4 LOC)js/game.js
function hideControls() {
document.getElementById('controls-menu').style.display = 'none';
document.getElementById('main-menu').style.display = 'flex';
}togglePause function · javascript · L75-L79 (5 LOC)js/game.js
function togglePause() {
paused = !paused;
document.getElementById('main-menu').style.display = paused ? 'flex' : 'none';
if (paused) document.exitPointerLock();
}Repobility · MCP-ready · https://repobility.com
updateFDRIndicator function · javascript · L4-L13 (10 LOC)js/hud.js
function updateFDRIndicator() {
let el = document.getElementById('fdr-indicator');
if (!el) {
el = document.createElement('div');
el.id = 'fdr-indicator';
el.style.cssText = 'position:fixed;top:10px;right:10px;color:rgba(255,50,50,0.4);font-size:10px;z-index:999;pointer-events:none;';
document.body.appendChild(el);
}
el.textContent = FDR.recording ? '●' : '';
}ensureNoxMarker function · javascript · L20-L28 (9 LOC)js/hud.js
function ensureNoxMarker() {
if (_noxMarker) return;
_noxMarker = document.createElement('div');
_noxMarker.id = 'nox-marker';
_noxMarker.style.cssText = 'position:fixed;pointer-events:none;z-index:15;font-family:Orbitron,sans-serif;text-align:center;';
_noxMarker.innerHTML = '<div style="font-size:24px;text-shadow:0 0 12px currentColor,0 0 24px currentColor;">◇</div><div style="font-size:10px;letter-spacing:2px;margin-top:-2px;">NOX</div><div id="nox-dist" style="font-size:11px;letter-spacing:1px;font-family:Share Tech Mono,monospace;opacity:0.7;"></div>';
document.body.appendChild(_noxMarker);
_noxLabel = document.getElementById('nox-dist');
}ensureProgradeMarker function · javascript · L33-L40 (8 LOC)js/hud.js
function ensureProgradeMarker() {
if (_progradeMarker) return;
_progradeMarker = document.createElement('div');
_progradeMarker.id = 'prograde-marker';
_progradeMarker.style.cssText = 'position:fixed;pointer-events:none;z-index:15;width:28px;height:28px;';
_progradeMarker.innerHTML = '<svg width="28" height="28" viewBox="0 0 28 28"><circle cx="14" cy="14" r="11" stroke="rgba(0,255,170,0.7)" fill="none" stroke-width="2"/><circle cx="14" cy="14" r="3" fill="rgba(0,255,170,0.7)"/><line x1="14" y1="0" x2="14" y2="3" stroke="rgba(0,255,170,0.5)" stroke-width="1.5"/><line x1="14" y1="25" x2="14" y2="28" stroke="rgba(0,255,170,0.5)" stroke-width="1.5"/><line x1="0" y1="14" x2="3" y2="14" stroke="rgba(0,255,170,0.5)" stroke-width="1.5"/><line x1="25" y1="14" x2="28" y2="14" stroke="rgba(0,255,170,0.5)" stroke-width="1.5"/></svg>';
document.body.appendChild(_progradeMarker);
}updateTargetMarkers function · javascript · L42-L141 (100 LOC)js/hud.js
function updateTargetMarkers() {
ensureNoxMarker();
ensureProgradeMarker();
const w = window.innerWidth;
const h = window.innerHeight;
// ---- Nox marker: project Nox center onto screen ----
_noxScreenPos.copy(NOX.center);
_noxScreenPos.project(camera);
const noxDist = playerObj.position.distanceTo(NOX.center) - NOX.radius;
// Check if Nox is in front of camera
// project() gives z in [-1, 1], z < 1 means in front
if (_noxScreenPos.z < 1) {
// On screen
const sx = (1 + _noxScreenPos.x) * w / 2;
const sy = (1 - _noxScreenPos.y) * h / 2;
// Clamp to screen edges with padding
const pad = 30;
const cx = Math.max(pad, Math.min(w - pad, sx));
const cy = Math.max(pad, Math.min(h - pad, sy));
_noxMarker.style.left = (cx - 10) + 'px';
_noxMarker.style.top = (cy - 10) + 'px';
_noxMarker.style.display = 'block';
// Distance label
if (noxDist > 1000) {
_noxLabel.textContent = (noxDist / 1000).toFixed(1) + 'km';
} updateHUD function · javascript · L146-L194 (49 LOC)js/hud.js
function updateHUD() {
updateFDRIndicator();
document.getElementById('alt-display').textContent = Math.floor(STATE.altitude);
document.getElementById('speed-display').textContent = Math.floor(STATE.speed);
document.getElementById('throttle-display').textContent = Math.floor(STATE.throttle * 100) + '%';
// AoA display with stall warning
const aoaDeg = THREE.MathUtils.radToDeg(STATE.angleOfAttack);
const aoaEl = document.getElementById('aoa-display');
aoaEl.textContent = aoaDeg.toFixed(1) + '\u00B0';
const stallRatio = Math.abs(STATE.angleOfAttack) / PHYS.stallAlpha;
const inAtmosphere = airDensityAtPos(playerObj.position) > 0.001;
if (stallRatio > 1 && inAtmosphere) {
aoaEl.className = 'hud-value stall';
aoaEl.textContent = 'STALL';
} else if (stallRatio > 0.8 && inAtmosphere) {
aoaEl.className = 'hud-value warning';
} else {
aoaEl.className = 'hud-value';
}
playerObj.getWorldDirection(_hudDir);
const rawHeading = THREE.MathUtils.radToDeanimate function · javascript · L11-L112 (102 LOC)js/main.js
function animate(time) {
requestAnimationFrame(animate);
const _frameStart = performance.now();
const dt = Math.min((time - lastTime) / 1000, 0.05);
lastTime = time;
// FPS counter
frameCount++;
fpsTime += dt;
if (fpsTime >= 0.5) {
document.getElementById('fps-display').textContent = Math.round(frameCount / fpsTime) + ' FPS';
frameCount = 0;
fpsTime = 0;
}
if (!STATE.playing || paused) {
composer.render();
return;
}
let _t0 = performance.now();
updateFlight(dt);
updateOrbits(dt);
updateAudio(dt);
_perf.flightT += performance.now() - _t0;
// Altitude-adaptive visibility
const viewAlt = Math.max(0, STATE.altitude);
// Fog recedes with altitude: surface=2K-10K, orbit=50K-200K
const fogScale = 1 + viewAlt / 200; // every 200m doubles fog distance
const fogNear = 2000 * fogScale;
const fogFar = 10000 * fogScale;
// Update scene fog (exponential — lower density = see further)
scene.fog.density = 0.00015 / Math.max(1, fupdateMinimap function · javascript · L9-L41 (33 LOC)js/minimap.js
function updateMinimap() {
mCtx.fillStyle = 'rgba(0, 10, 5, 0.9)';
mCtx.fillRect(0, 0, 150, 150);
const scale = 0.04;
const px = playerObj.position.x;
const pz = playerObj.position.z;
// Draw terrain dots
for (let x = -75; x < 75; x += 5) {
for (let z = -75; z < 75; z += 5) {
const wx = px + x / scale;
const wz = pz + z / scale;
const h = terrainHeight(wx, wz);
const brightness = Math.max(0, Math.min(1, h / 100));
mCtx.fillStyle = `rgba(0, ${Math.floor(100 + brightness * 155)}, ${Math.floor(80 + brightness * 90)}, 0.4)`;
mCtx.fillRect(75 + x, 75 + z, 3, 3);
}
}
// Player indicator
const dir = playerObj.getWorldDirection(new THREE.Vector3());
mCtx.save();
mCtx.translate(75, 75);
mCtx.rotate(Math.atan2(dir.x, dir.z));
mCtx.fillStyle = '#00ffaa';
mCtx.beginPath();
mCtx.moveTo(0, -6);
mCtx.lineTo(-4, 4);
mCtx.lineTo(4, 4);
mCtx.fill();
mCtx.restore();
}createParticleTexture function · javascript · L14-L27 (14 LOC)js/particles.js
function createParticleTexture() {
const size = 64;
const c = document.createElement('canvas');
c.width = size; c.height = size;
const ctx = c.getContext('2d');
const grad = ctx.createRadialGradient(size/2, size/2, 0, size/2, size/2, size/2);
grad.addColorStop(0, 'rgba(255,255,255,1)');
grad.addColorStop(0.3, 'rgba(255,255,255,0.6)');
grad.addColorStop(0.7, 'rgba(255,255,255,0.15)');
grad.addColorStop(1, 'rgba(255,255,255,0)');
ctx.fillStyle = grad;
ctx.fillRect(0, 0, size, size);
return new THREE.CanvasTexture(c);
}Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
spawnExplosion function · javascript · L62-L81 (20 LOC)js/particles.js
function spawnExplosion(x, y, z, radius, color1, color2, count) {
for (let i = 0; i < count && particles.length < MAX_PARTICLES; i++) {
const angle = Math.random() * Math.PI * 2;
const elev = (Math.random() - 0.3) * Math.PI;
const spd = (3 + Math.random() * 8) * (radius / 20);
const t = Math.random();
particles.push({
x, y, z,
vx: Math.cos(angle) * Math.cos(elev) * spd,
vy: Math.sin(elev) * spd + 2,
vz: Math.sin(angle) * Math.cos(elev) * spd,
life: 0.6 + Math.random() * 1.2,
maxLife: 0.6 + Math.random() * 1.2,
size: 2 + Math.random() * 6,
r: color1.r * (1-t) + color2.r * t,
g: color1.g * (1-t) + color2.g * t,
b: color1.b * (1-t) + color2.b * t
});
}
}updateParticles function · javascript · L83-L118 (36 LOC)js/particles.js
function updateParticles(dt) {
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.life -= dt;
if (p.life <= 0) { particles.splice(i, 1); continue; }
p.x += p.vx * dt;
p.y += p.vy * dt;
p.z += p.vz * dt;
p.vy -= 8 * dt;
p.vx *= 0.98;
p.vz *= 0.98;
}
const pos = particleGeo.getAttribute('position');
const col = particleGeo.getAttribute('color');
const siz = particleGeo.getAttribute('size');
for (let i = 0; i < MAX_PARTICLES; i++) {
if (i < particles.length) {
const p = particles[i];
const a = p.life / p.maxLife;
pos.array[i*3] = p.x;
pos.array[i*3+1] = p.y;
pos.array[i*3+2] = p.z;
col.array[i*3] = p.r * (1 + (1-a) * 0.5);
col.array[i*3+1] = p.g * a;
col.array[i*3+2] = p.b * a * 0.5;
siz.array[i] = p.size * a;
} else {
siz.array[i] = 0;
}
}
pos.needsUpdate = true;
col.needsUpdate = true;
siz.needsUpdate = true;
}damagePlayer function · javascript · L4-L19 (16 LOC)js/player.js
function damagePlayer(amount) {
if (STATE.dead) return;
// Armor reduces damage: armor 1 = 0.68x reduction, armor 5 = 1.0x, armor 10 = 1.4x reduction
const armorMult = 1 / (0.6 + STATE.plane.stats.armor * 0.08);
const finalDamage = amount * armorMult;
STATE.health = Math.max(0, STATE.health - finalDamage);
// Damage flash
const flash = document.getElementById('damage-flash');
flash.classList.add('active');
setTimeout(() => flash.classList.remove('active'), 150);
if (STATE.health <= 0) {
playerDeath();
}
}playerDeath function · javascript · L21-L46 (26 LOC)js/player.js
function playerDeath() {
STATE.dead = true;
STATE.deathTime = performance.now();
if (FDR.recording) FDR.stop();
// Silence persistent audio
if (audioCtx) {
const t = audioCtx.currentTime;
if (engineGain) engineGain.gain.setTargetAtTime(0, t, 0.05);
if (windGain) windGain.gain.setTargetAtTime(0, t, 0.1);
if (stallGain) stallGain.gain.setTargetAtTime(0, t, 0.02);
}
// Big explosion at player position
explodeAt(playerObj.position.x, playerObj.position.y, playerObj.position.z, 40, 30);
// Exit pointer lock
document.exitPointerLock();
// Show death screen with animation delay
const deathScreen = document.getElementById('death-screen');
deathScreen.style.display = 'flex';
// Force reflow before adding active class for CSS transition
deathScreen.offsetHeight;
deathScreen.classList.add('active');
}restartFromDeath function · javascript · L48-L53 (6 LOC)js/player.js
function restartFromDeath() {
const deathScreen = document.getElementById('death-screen');
deathScreen.classList.remove('active');
deathScreen.style.display = 'none';
startGame();
}returnToMenu function · javascript · L55-L62 (8 LOC)js/player.js
function returnToMenu() {
const deathScreen = document.getElementById('death-screen');
deathScreen.classList.remove('active');
deathScreen.style.display = 'none';
STATE.playing = false;
STATE.dead = false;
document.getElementById('main-menu').style.display = 'flex';
}pseudoNoise function · javascript · L4-L8 (5 LOC)js/terrain.js
function pseudoNoise(x, z) {
let n = Math.sin(x * 0.01 + z * 0.013) * 43758.5453;
n = n - Math.floor(n);
return n;
}_sH function · javascript · L13-L16 (4 LOC)js/terrain.js
function _sH(x, y) {
const v = Math.sin(x * 127.1 + y * 311.7) * 43758.5453;
return Math.floor((v - Math.floor(v)) * 12);
}Repobility analyzer · published findings · https://repobility.com
simplex2 function · javascript · L17-L32 (16 LOC)js/terrain.js
function simplex2(xin, yin) {
const F2 = 0.5 * (Math.sqrt(3.0) - 1.0), G2 = (3.0 - Math.sqrt(3.0)) / 6.0;
const s = (xin + yin) * F2;
const i = Math.floor(xin + s), j = Math.floor(yin + s);
const t = (i + j) * G2;
const x0 = xin - (i - t), y0 = yin - (j - t);
const i1 = x0 > y0 ? 1 : 0, j1 = x0 > y0 ? 0 : 1;
const x1 = x0 - i1 + G2, y1 = y0 - j1 + G2;
const x2 = x0 - 1.0 + 2.0 * G2, y2 = y0 - 1.0 + 2.0 * G2;
const g0 = _sG[_sH(i, j)], g1 = _sG[_sH(i+i1, j+j1)], g2 = _sG[_sH(i+1, j+1)];
let n0 = 0, n1 = 0, n2 = 0;
let t0 = 0.5 - x0*x0 - y0*y0; if (t0 > 0) { t0 *= t0; n0 = t0*t0*(g0[0]*x0 + g0[1]*y0); }
let t1 = 0.5 - x1*x1 - y1*y1; if (t1 > 0) { t1 *= t1; n1 = t1*t1*(g1[0]*x1 + g1[1]*y1); }
let t2 = 0.5 - x2*x2 - y2*y2; if (t2 > 0) { t2 *= t2; n2 = t2*t2*(g2[0]*x2 + g2[1]*y2); }
return 70.0 * (n0 + n1 + n2); // range ≈ -1..1
}terrainHeight function · javascript · L34-L53 (20 LOC)js/terrain.js
function terrainHeight(x, z) {
let h = 0;
h += Math.sin(x * 0.002) * Math.cos(z * 0.003) * 80;
h += Math.sin(x * 0.008 + z * 0.006) * 30;
h += Math.sin(x * 0.02) * Math.cos(z * 0.015) * 15;
h += simplex2(x * 0.05, z * 0.05) * 12 + simplex2(x * 0.18, z * 0.18) * 4;
// City-like structures in certain areas
const cx = Math.floor(x / 200) * 200;
const cz = Math.floor(z / 200) * 200;
const cityVal = pseudoNoise(cx * 0.5, cz * 0.5);
if (cityVal > 0.6) {
const bx = Math.floor(x / 30) * 30;
const bz = Math.floor(z / 30) * 30;
const bh = pseudoNoise(bx, bz) * 120 + 20;
if (Math.abs(x - bx) < 12 && Math.abs(z - bz) < 12) {
h = Math.max(h, bh);
}
}
return h;
}terrainNormal function · javascript · L55-L60 (6 LOC)js/terrain.js
function terrainNormal(x, z) {
const eps = 2.0;
const hL = terrainHeight(x - eps, z), hR = terrainHeight(x + eps, z);
const hD = terrainHeight(x, z - eps), hU = terrainHeight(x, z + eps);
return new THREE.Vector3(hL - hR, 2.0 * eps, hD - hU).normalize();
}terrainColor function · javascript · L62-L88 (27 LOC)js/terrain.js
function terrainColor(x, z, h) {
const cityVal = pseudoNoise(Math.floor(x/200)*200*0.5, Math.floor(z/200)*200*0.5);
if (cityVal > 0.6 && h > 20) {
const v = pseudoNoise(x * 0.3, z * 0.3);
if (v > 0.5) return new THREE.Color(0.55, 0.55, 0.6);
if (v > 0.3) return new THREE.Color(0.35, 0.35, 0.42);
return new THREE.Color(0.7, 0.65, 0.55);
}
// Smooth biome blending
const biomes = [
{ lo: -999, hi: -10, r: 0.15, g: 0.25, b: 0.45 },
{ lo: -10, hi: 5, r: 0.6, g: 0.55, b: 0.4 },
{ lo: 5, hi: 40, r: 0.2, g: 0.45, b: 0.15 },
{ lo: 40, hi: 70, r: 0.3, g: 0.35, b: 0.15 },
{ lo: 70, hi: 999, r: 0.5, g: 0.48, b: 0.44 }
];
const blend = 15;
let tr = 0, tg = 0, tb = 0, tw = 0;
for (const b of biomes) {
const center = (b.lo === -999 ? -50 : b.lo === 999 ? 150 : (b.lo + b.hi) * 0.5);
const halfSpan = (b.hi === 999 ? 80 : b.lo === -999 ? 40 : (b.hi - b.lo) * 0.5) + blend;
const w = Math.max(0, 1 - Math.abs(h - center) / hsmoothTerrainHeight function · javascript · L14-L19 (6 LOC)js/terrain-splat.js
function smoothTerrainHeight(x, z) {
const s = CHUNK_SIZE / (CHUNK_RES - 1) * 0.5; // half grid step
return (terrainHeight(x, z) * 2 +
terrainHeight(x - s, z) + terrainHeight(x + s, z) +
terrainHeight(x, z - s) + terrainHeight(x, z + s)) / 6;
}TerrainChunk class · javascript · L21-L194 (174 LOC)js/terrain-splat.js
class TerrainChunk {
constructor(cx, cz) {
this.cx = cx;
this.cz = cz;
this.key = `${cx},${cz}`;
this.mesh = null;
this.generate();
}
generate() {
const res = CHUNK_RES;
const step = CHUNK_SIZE / (res - 1);
const ox = this.cx * CHUNK_SIZE;
const oz = this.cz * CHUNK_SIZE;
const vertCount = res * res;
const positions = new Float32Array(vertCount * 3);
const colors = new Float32Array(vertCount * 3);
const normals = new Float32Array(vertCount * 3);
// Compute sphere rotation at chunk center
const chunkCenterPos = flatToSphere(ox + CHUNK_SIZE * 0.5, oz + CHUNK_SIZE * 0.5, 0);
const chunkRotQ = sphereRotation(chunkCenterPos);
for (let iz = 0; iz < res; iz++) {
for (let ix = 0; ix < res; ix++) {
const i = iz * res + ix;
const x = ox + ix * step;
const z = oz + iz * step;
const h = smoothTerrainHeight(x, z);
// Project onto sphere
const pos = flatToSphere(x, z, constructor method · javascript · L22-L28 (7 LOC)js/terrain-splat.js
constructor(cx, cz) {
this.cx = cx;
this.cz = cz;
this.key = `${cx},${cz}`;
this.mesh = null;
this.generate();
}generate method · javascript · L30-L149 (120 LOC)js/terrain-splat.js
generate() {
const res = CHUNK_RES;
const step = CHUNK_SIZE / (res - 1);
const ox = this.cx * CHUNK_SIZE;
const oz = this.cz * CHUNK_SIZE;
const vertCount = res * res;
const positions = new Float32Array(vertCount * 3);
const colors = new Float32Array(vertCount * 3);
const normals = new Float32Array(vertCount * 3);
// Compute sphere rotation at chunk center
const chunkCenterPos = flatToSphere(ox + CHUNK_SIZE * 0.5, oz + CHUNK_SIZE * 0.5, 0);
const chunkRotQ = sphereRotation(chunkCenterPos);
for (let iz = 0; iz < res; iz++) {
for (let ix = 0; ix < res; ix++) {
const i = iz * res + ix;
const x = ox + ix * step;
const z = oz + iz * step;
const h = smoothTerrainHeight(x, z);
// Project onto sphere
const pos = flatToSphere(x, z, h);
positions[i * 3] = pos.x;
positions[i * 3 + 1] = pos.y;
positions[i * 3 + 2] = pos.z;
// Vertex color with slight variMethodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
destroySplatsInRadius method · javascript · L151-L187 (37 LOC)js/terrain-splat.js
destroySplatsInRadius(wx, wy, wz, radius) {
// Crater: push vertices toward planet center within blast radius
const posAttr = this.mesh.geometry.getAttribute('position');
const colAttr = this.mesh.geometry.getAttribute('color');
let changed = false;
const r2 = radius * radius;
for (let i = 0; i < posAttr.count; i++) {
const vx = posAttr.getX(i);
const vy = posAttr.getY(i);
const vz = posAttr.getZ(i);
const dx = vx - wx;
const dy = vy - wy;
const dz = vz - wz;
const d2 = dx*dx + dy*dy + dz*dz;
if (d2 < r2) {
// Push vertex toward planet center (crater depth proportional to proximity)
const t = 1 - Math.sqrt(d2) / radius; // 1 at center, 0 at edge
const depth = t * radius * 0.3;
const up = planetUp(new THREE.Vector3(vx, vy, vz));
posAttr.setXYZ(i, vx - up.x * depth, vy - up.y * depth, vz - up.z * depth);
// Darken crater
colAttr.setXYZ(i,
colAttr.gdispose method · javascript · L189-L193 (5 LOC)js/terrain-splat.js
dispose() {
scene.remove(this.mesh);
this.mesh.geometry.dispose();
this.mesh.material.dispose();
}updateChunks function · javascript · L196-L236 (41 LOC)js/terrain-splat.js
function updateChunks() {
// Scale render distance with altitude
const chunkAlt = Math.max(0, STATE.altitude);
RENDER_DIST = Math.min(15, Math.max(5, Math.floor(5 + chunkAlt / 300)));
const flat = sphereToFlat(playerObj.position);
const px = Math.floor(flat.x / CHUNK_SIZE);
const pz = Math.floor(flat.z / CHUNK_SIZE);
// Build list of needed chunks, sorted by priority (forward chunks first)
const fwd = playerObj.getWorldDirection(new THREE.Vector3());
const needed = [];
for (let x = px - RENDER_DIST; x <= px + RENDER_DIST; x++) {
for (let z = pz - RENDER_DIST; z <= pz + RENDER_DIST; z++) {
const key = `${x},${z}`;
if (!chunks.has(key)) {
const dx = (x + 0.5) * CHUNK_SIZE - flat.x;
const dz = (z + 0.5) * CHUNK_SIZE - flat.z;
const dist = Math.sqrt(dx*dx + dz*dz) || 1;
const dot = (fwd.x * dx + fwd.z * dz) / dist;
const priority = dot - dist * 0.001;
needed.push({ key, x, z, priority });
}
}
}renderBuilder function · javascript · L4-L32 (29 LOC)js/ui.js
function renderBuilder() {
['fuselage', 'wing', 'engine', 'weapon'].forEach((cat, ci) => {
const key = cat === 'wing' ? 'wings' : cat;
const container = document.getElementById(cat + (cat === 'wing' ? '-options' : cat === 'weapon' ? '-options' : '-options'));
// Fix the element IDs
const elId = cat === 'wing' ? 'wing-options' : cat + '-options';
const el = document.getElementById(elId);
if (!el) return;
el.innerHTML = '';
PARTS[key].forEach((part, i) => {
const div = document.createElement('div');
div.className = 'part-option' + (STATE.plane[key] === i ? ' selected' : '');
div.innerHTML = `
<div class="part-name">${part.name}</div>
<div class="part-stat">${part.desc}</div>
<div class="part-stat">SPD ${part.speed > 0 ? '+' : ''}${part.speed} | AGI ${part.agility > 0 ? '+' : ''}${part.agility} | ARM ${part.armor > 0 ? '+' : ''}${part.armor} | FP ${part.firepower > 0 ? '+' : ''}${part.firepower}</div>
`;
recalcStats function · javascript · L34-L45 (12 LOC)js/ui.js
function recalcStats() {
const s = { speed: 5, agility: 5, armor: 5, firepower: 5 };
['fuselage', 'wings', 'engine', 'weapon'].forEach(key => {
const idx = STATE.plane[key];
const part = PARTS[key][idx];
s.speed = Math.max(1, Math.min(10, s.speed + part.speed));
s.agility = Math.max(1, Math.min(10, s.agility + part.agility));
s.armor = Math.max(1, Math.min(10, s.armor + part.armor));
s.firepower = Math.max(1, Math.min(10, s.firepower + part.firepower));
});
STATE.plane.stats = s;
}renderStats function · javascript · L47-L63 (17 LOC)js/ui.js
function renderStats() {
const el = document.getElementById('plane-stats');
el.innerHTML = '';
['speed', 'agility', 'armor', 'firepower'].forEach(stat => {
const val = STATE.plane.stats[stat];
const div = document.createElement('div');
div.style.marginBottom = '8px';
div.innerHTML = `
<div style="display:flex; justify-content:space-between; font-size:12px;">
<span style="color:#999; letter-spacing:2px; text-transform:uppercase;">${stat}</span>
<span style="color:#00ffaa;">${val}/10</span>
</div>
<div class="stat-bar"><div class="stat-bar-fill" style="width:${val * 10}%"></div></div>
`;
el.appendChild(div);
});
}renderKeyBindings function · javascript · L68-L82 (15 LOC)js/ui.js
function renderKeyBindings() {
const el = document.getElementById('key-bindings');
el.innerHTML = '';
for (const [action, key] of Object.entries(KEYS)) {
const row = document.createElement('div');
row.className = 'key-bind-row';
const displayKey = key === ' ' ? 'SPACE' : key.toUpperCase();
row.innerHTML = `
<span class="action">${KEY_LABELS[action] || action}</span>
<button class="key-btn ${listeningKey === action ? 'listening' : ''}"
onclick="startListening('${action}')">${displayKey}</button>
`;
el.appendChild(row);
}
}startListening function · javascript · L84-L87 (4 LOC)js/ui.js
function startListening(action) {
listeningKey = action;
renderKeyBindings();
}Repobility · MCP-ready · https://repobility.com
resetControls function · javascript · L89-L103 (15 LOC)js/ui.js
function resetControls() {
KEYS = {
throttleUp: 'w', throttleDown: 's',
rollLeft: 'a', rollRight: 'd',
yawLeft: 'q', yawRight: 'e',
fire: 'mouse0', weaponNext: 'x', weaponPrev: 'z',
brake: ' ', menu: 'escape'
};
sensitivity = 5;
invertY = true;
document.getElementById('sensitivity-slider').value = 5;
document.getElementById('sens-val').textContent = '5';
document.getElementById('invert-y').checked = true;
renderKeyBindings();
}CelestialBody function · javascript · L9-L23 (15 LOC)js/universe.js
function CelestialBody(config) {
this.name = config.name;
this.radius = config.radius;
this.center = config.center.clone();
this.hasAtmosphere = config.hasAtmosphere || false;
this.atmosphereHeight = config.atmosphereHeight || 0;
this.hasOcean = config.hasOcean || false;
this.oceanLevel = config.oceanLevel || 0;
this.parentBody = config.parentBody || null;
this.orbitalRadius = config.orbitalRadius || 0;
this.orbitalPeriod = config.orbitalPeriod || 0;
this.orbitalPhase = config.orbitalPhase || 0;
this.soiRadius = config.soiRadius || 0;
this.mesh = null;
}updateOrbits function · javascript · L55-L67 (13 LOC)js/universe.js
function updateOrbits(dt) {
for (const body of BODIES) {
if (!body.parentBody) continue;
body.orbitalPhase += (2 * Math.PI / body.orbitalPeriod) * dt;
if (body.orbitalPhase > 2 * Math.PI) body.orbitalPhase -= 2 * Math.PI;
// Circular orbit in XZ plane around parent center
const px = body.parentBody.center.x + Math.cos(body.orbitalPhase) * body.orbitalRadius;
const pz = body.parentBody.center.z + Math.sin(body.orbitalPhase) * body.orbitalRadius;
const py = body.parentBody.center.y;
body.center.set(px, py, pz);
if (body.mesh) body.mesh.position.copy(body.center);
}
}page 1 / 2next ›