Race the Sun
GPT 5.6 terra · typescript

Browser check: Artifact runtime error. This is a technical check, not a quality review.
Reviews & generation details
Reviews
No human review yet. Unreviewed does not mean unsuccessful.
Generation context
Imported historical artifact. Its exact original instructions and lineage are not known.
Generation prompt · exact text unavailable
See the current prompt for reference. It may differ from the instructions used to generate this artifact.
Inspect original source 17,461 bytes · SHA-256 beb2796891b6
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SOLAR // RUN</title>
<style>
/* ── css: base ── */
*{box-sizing:border-box}html,body,#app,#game{margin:0;width:100%;height:100%;overflow:hidden;background:#07091a;font-family:Arial,Helvetica,sans-serif;color:#f7f4d8}#game{position:relative;isolation:isolate}canvas{width:100%;height:100%;display:block}#hud{position:absolute;inset:0;padding:26px 34px;pointer-events:none;text-shadow:0 2px 8px #080818}.brand{font-weight:900;font-size:20px;letter-spacing:3px}.brand span{color:#ffce55;margin:0 4px}.readouts{position:absolute;right:34px;top:24px;display:flex;gap:26px;text-align:right}.readouts div{min-width:63px}.readouts small,.energy em,.eyebrow{font-size:9px;letter-spacing:2px;font-style:normal;color:#d5c8bb}.readouts b{display:block;font-size:17px;letter-spacing:1px;color:#fff9d5}.energy{position:absolute;left:34px;bottom:27px;width:210px;height:9px;border:1px solid #f7e5a7;transform:skewX(-18deg);background:#ffffff19}.energy i{display:block;width:100%;height:100%;background:linear-gradient(90deg,#ff7f4d,#ffe56b,#f8fff0);transition:width .16s}.energy em{position:absolute;top:-16px;left:0;font-weight:bold}#overlay{position:absolute;inset:0;display:grid;place-items:center;background:radial-gradient(circle at 50% 48%,#ff8d3522,transparent 35%),#08091b66;transition:opacity .35s;z-index:3}.panel{text-align:center;max-width:680px;padding:35px}.eyebrow{color:#ffcf6b;margin-bottom:8px}h1{font-style:italic;font-size:clamp(62px,11vw,134px);line-height:.74;letter-spacing:-8px;margin:14px 0 28px;font-weight:900;color:#fbf5d8;text-shadow:7px 9px 0 #ed553b}h1 span{color:#ffb34d}#message{font-size:12px;letter-spacing:3px;color:#f9dfb0;margin:0 0 31px}.keys{display:flex;align-items:center;justify-content:center;gap:6px;font-size:9px;letter-spacing:1.5px;color:#d2c8bf;flex-wrap:wrap;margin-bottom:28px}.keys span{margin-right:13px}kbd{font-family:inherit;border:1px solid #f6d47e;border-bottom-width:3px;padding:5px 7px;color:#fff1bc;background:#1d1730}button{border:0;background:#ffe06a;color:#321b29;font-weight:900;font-style:italic;letter-spacing:2px;padding:15px 35px;cursor:pointer;clip-path:polygon(8% 0,100% 0,92% 100%,0 100%);box-shadow:6px 7px 0 #d74c3d}button:hover{background:#fff3a5}.hint{font-size:9px;letter-spacing:1.6px;color:#b3a9af;margin-top:25px}.hint b{color:#fff0a8}#vignette{position:absolute;inset:0;pointer-events:none;z-index:2;background:radial-gradient(ellipse at center,transparent 45%,#060716a8 110%);mix-blend-mode:multiply}body.playing #overlay{opacity:0;pointer-events:none}body.playing #hud{opacity:1}@media(max-width:650px){#hud{padding:18px}.readouts{left:18px;right:18px;top:54px;justify-content:space-between;gap:4px}.readouts b{font-size:13px}.energy{left:18px;bottom:18px;width:150px}.brand{font-size:16px}}
</style>
</head>
<body>
<main id="game"><canvas id="canvas"></canvas><div id="hud" aria-live="polite"><div class="brand">SOLAR<span>//</span>RUN</div><div class="readouts"><div><small>DISTANCE</small><b id="distance">0000</b></div><div><small>SCORE</small><b id="score">000000</b></div><div><small>MULTI</small><b id="multi">x1.0</b></div><div><small>VELOCITY</small><b id="speed">180</b></div></div><div class="energy"><i></i><em>ENERGY</em></div></div><section id="overlay"><div class="panel"><div class="eyebrow">ORBITAL PILOT PROGRAM</div><h1>SOLAR<br><span>RUN</span></h1><p id="message">CHASE THE LIGHT. OUTRUN THE DARK.</p><div class="keys"><kbd>←</kbd><kbd>↑</kbd><kbd>↓</kbd><kbd>→</kbd><span>STEER / PITCH</span><kbd>SPACE</kbd><span>BOOST</span></div><button id="start">BEGIN RUN</button><p class="hint">[ R ] RESTART • HIGH SCORE <b id="high">000000</b></p></div></section><div id="vignette"></div></main>
<script>
(function () {
'use strict';
var __mods = {};
var __cache = {};
var __map = {};
function __require(id) {
if (__cache[id]) return __cache[id].exports;
var module = __cache[id] = { exports: {} };
var factory = __mods[id];
if (!factory) throw new Error("Module not found: " + id);
factory(module.exports, function (spec) {
var target = (__map[id] && __map[id][spec]) || spec;
return __require(target);
}, module);
return module.exports;
}
// ── module: src/main.ts ──
__mods["src/main.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// SOLAR RUN — canvas arcade runner
// === TUNING ===
const T = { base: 180, max: 510, accel: 3.8, road: 260, spawn: 0.62, energyDrain: 1.7, boost: 145, playerY: .76 };
const C = { skyTop: '#181545', skyLow: '#fa7450', sun: '#ffe780', road: '#131b42', line: '#ffbd5b', shadow: '#090b20' };
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
const $ = (s) => document.querySelector(s);
const ui = { distance: $('#distance'), score: $('#score'), multi: $('#multi'), speed: $('#speed'), energy: document.querySelector('.energy i'), overlay: $('#overlay'), message: $('#message'), start: $('#start'), high: $('#high') };
let W = 0, H = 0, DPR = 1, run = false, last = 0, seed = 1, rng = 1;
let speed = 0, distance = 0, score = 0, multi = 1, energy = 100, sun = 1, boost = 0, shake = 0, flash = 0, spawnTimer = 0;
let px = 0, py = 0, vx = 0, vy = 0;
let items = [];
let particles = [];
let keys = new Set();
let audio, wind, windGain;
const high = Number(localStorage.getItem('solarRunHigh') || 0);
ui.high.textContent = high.toString().padStart(6, '0');
function random() { rng = (rng * 1664525 + 1013904223) >>> 0; return rng / 4294967296; }
function resize() { DPR = Math.min(devicePixelRatio, 2); W = innerWidth; H = innerHeight; canvas.width = W * DPR; canvas.height = H * DPR; ctx.setTransform(DPR, 0, 0, DPR, 0, 0); }
addEventListener('resize', resize);
resize();
// === AUDIO ===
function initAudio() { if (audio)
return; audio = new AudioContext(); wind = audio.createOscillator(); windGain = audio.createGain(); wind.type = 'sawtooth'; wind.frequency.value = 58; windGain.gain.value = .012; wind.connect(windGain).connect(audio.destination); wind.start(); }
function beep(f, d = .09, type = 'sine', vol = .08) { if (!audio)
return; const o = audio.createOscillator(), g = audio.createGain(); o.type = type; o.frequency.setValueAtTime(f, audio.currentTime); o.frequency.exponentialRampToValueAtTime(f * 1.7, audio.currentTime + d); g.gain.setValueAtTime(vol, audio.currentTime); g.gain.exponentialRampToValueAtTime(.001, audio.currentTime + d); o.connect(g).connect(audio.destination); o.start(); o.stop(audio.currentTime + d); }
// === RUN STATE ===
function start() { initAudio(); audio?.resume(); seed = (Date.now() ^ Math.floor(Math.random() * 999999)) >>> 0; rng = seed; run = true; document.body.classList.add('playing'); speed = T.base; distance = score = 0; multi = 1; energy = 100; sun = 1; boost = 0; shake = flash = spawnTimer = 0; px = py = vx = vy = 0; items = []; particles = []; beep(280, .12, 'triangle', .08); }
function end() { if (!run)
return; run = false; document.body.classList.remove('playing'); if (windGain)
windGain.gain.value = .005; const n = Math.floor(score); const best = Math.max(high, Number(localStorage.getItem('solarRunHigh') || 0), n); localStorage.setItem('solarRunHigh', String(best)); ui.high.textContent = best.toString().padStart(6, '0'); ui.message.innerHTML = `RUN ENDED — <b>${n.toString().padStart(6, '0')}</b> POINTS<br>PRESS R OR CLICK TO FLY AGAIN`; ui.start.textContent = 'RUN AGAIN'; beep(75, .5, 'sawtooth', .18); }
ui.start.onclick = start;
ui.overlay.onclick = e => { if (e.target === ui.overlay && !run)
start(); };
addEventListener('keydown', e => { if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', ' '].includes(e.key))
e.preventDefault(); keys.add(e.key.toLowerCase()); if ((e.key === 'r' || e.key === 'R') && !run)
start(); if (e.code === 'Space' && run && energy > 12 && boost <= 0) {
boost = .55;
energy -= 12;
beep(520, .08, 'square', .05);
} });
addEventListener('keyup', e => keys.delete(e.key.toLowerCase()));
// === WORLD GENERATION ===
function spawnWave() { const hard = Math.min(1, distance / 9000); const z = 1.12; const lane = [-.66, 0, .66]; const safe = Math.floor(random() * 3); for (let i = 0; i < 3; i++) {
if (i === safe && random() < .7) {
if (random() < .64)
items.push({ x: lane[i], z, w: .12, h: .12, kind: random() < .68 ? 'token' : 'cell' });
continue;
}
if (random() < .74) {
const kind = random() < .46 ? 'rock' : random() < .75 ? 'tower' : 'ramp';
items.push({ x: lane[i] + (random() - .5) * .08, z, w: kind === 'tower' ? .18 : .22, h: kind === 'tower' ? .73 : .25, kind });
}
} if (random() < .16 + hard * .22)
items.push({ x: lane[Math.floor(random() * 3)], z: z + .12, w: .14, h: .14, kind: 'orb' }); }
function particle(x, y, color, n = 8) { for (let i = 0; i < n; i++) {
const a = random() * Math.PI * 2, s = 30 + random() * 120;
particles.push({ x, y, vx: Math.cos(a) * s, vy: Math.sin(a) * s, life: .25 + random() * .45, max: .7, color, size: 2 + random() * 4 });
} }
// === PROJECTION & DRAWING ===
function project(x, z) { const horizon = H * .39; const p = Math.max(.03, 1 - z); return { x: W / 2 + x * W * .52 * p, y: horizon + (H * .63) * p, p }; }
function poly(points, fill) { ctx.fillStyle = fill; ctx.beginPath(); points.forEach((q, i) => i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)); ctx.closePath(); ctx.fill(); }
function drawWorld() { const g = ctx.createLinearGradient(0, 0, 0, H); g.addColorStop(0, C.skyTop); g.addColorStop(.55, C.skyLow); g.addColorStop(1, '#4c2450'); ctx.fillStyle = g; ctx.fillRect(0, 0, W, H); const hy = H * .39; const sunR = Math.min(W, H) * (.105 + sun * .035); ctx.fillStyle = `rgba(255,226,116,${sun})`; ctx.beginPath(); ctx.arc(W / 2, hy + H * .06 * (1 - sun), sunR, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#ffb257'; for (let i = 0; i < 7; i++)
ctx.fillRect(W / 2 - sunR, hy + H * .06 * (1 - sun) - sunR + i * sunR * .29, sunR * 2, sunR * .045); poly([{ x: 0, y: hy }, { x: W, y: hy }, { x: W, y: H }, { x: 0, y: H }], C.shadow); for (let z = 0; z < 1; z += .055) {
const a = project(-.96, z), b = project(.96, z), c = project(.96, z + .035), d = project(-.96, z + .035);
poly([a, b, c, d], Math.floor(z / .055) % 2 ? '#17204b' : '#111a40');
} for (let i = -1; i <= 1; i++) {
const a = project(i * .31, 0), b = project(i * .31, 1);
ctx.strokeStyle = '#ffbd5b70';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(a.x, a.y);
ctx.lineTo(b.x, b.y);
ctx.stroke();
} ctx.fillStyle = '#07091c'; ctx.fillRect(0, hy - 2, W, 3); }
function drawItem(o) { const p = project(o.x, o.z), s = p.p * W; const base = p.y; if (o.kind === 'token' || o.kind === 'cell' || o.kind === 'orb') {
const col = o.kind === 'cell' ? '#75f7e4' : o.kind === 'orb' ? '#e48cff' : '#ffe35b';
ctx.save();
ctx.translate(p.x, base);
ctx.rotate(distance * .03);
ctx.shadowBlur = 18;
ctx.shadowColor = col;
ctx.fillStyle = col;
ctx.beginPath();
if (o.kind === 'token') {
for (let i = 0; i < 8; i++) {
const a = i * Math.PI / 4, r = i % 2 ? 7 * p.p : 14 * p.p;
i ? ctx.lineTo(Math.cos(a) * r, Math.sin(a) * r) : ctx.moveTo(r, 0);
}
ctx.closePath();
}
else
ctx.arc(0, 0, 12 * p.p, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
ctx.fillStyle = '#fff';
ctx.font = `bold ${13 * p.p}px Arial`;
ctx.textAlign = 'center';
ctx.fillText(o.kind === 'cell' ? 'ϟ' : o.kind === 'orb' ? '×' : '✦', 0, 5 * p.p);
ctx.restore();
return;
} const w = o.w * s, h = o.h * s; const top = base - h; const color = o.kind === 'ramp' ? '#e66043' : '#302a56'; poly([{ x: p.x - w, y: base }, { x: p.x + w, y: base }, { x: p.x + w * .68, y: top }, { x: p.x - w * .68, y: top }], color); poly([{ x: p.x + w, y: base }, { x: p.x + w * .68, y: top }, { x: p.x + w * 1.1, y: top - h * .12 }, { x: p.x + w * 1.2, y: base }], '#171a39'); ctx.fillStyle = '#ff9a57'; ctx.fillRect(p.x - w * .65, top, w * 1.3, Math.max(1, 3 * p.p)); }
function drawCraft() { const x = W / 2 + px * W * .36, y = H * T.playerY + py * H * .12; ctx.save(); ctx.translate(x, y); ctx.rotate(vx * -.55); ctx.shadowBlur = 18; ctx.shadowColor = '#ff8b4b'; poly([{ x: 0, y: -25 }, { x: 14, y: 18 }, { x: 0, y: 12 }, { x: -14, y: 18 }], '#fff1ba'); poly([{ x: 0, y: -25 }, { x: 0, y: 12 }, { x: -38, y: 22 }, { x: -13, y: 5 }], '#e25748'); poly([{ x: 0, y: -25 }, { x: 0, y: 12 }, { x: 38, y: 22 }, { x: 13, y: 5 }], '#f8a84c'); ctx.fillStyle = '#44254b'; ctx.beginPath(); ctx.ellipse(0, -6, 5, 11, 0, 0, 7); ctx.fill(); ctx.fillStyle = '#ffed88'; ctx.fillRect(-4, 17, 8, 22 + random() * 10); ctx.restore(); }
function drawFx(dt) { for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.life -= dt;
p.x += p.vx * dt;
p.y += p.vy * dt;
p.vy += 20 * dt;
if (p.life <= 0) {
particles.splice(i, 1);
continue;
}
ctx.globalAlpha = p.life / p.max;
ctx.fillStyle = p.color;
ctx.fillRect(p.x, p.y, p.size, p.size);
} ctx.globalAlpha = 1; if (speed > 330 && run) {
ctx.strokeStyle = 'rgba(255,240,180,.24)';
ctx.lineWidth = 1;
for (let i = 0; i < 16; i++) {
const x = random() * W, y = H * .4 + random() * H * .6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(W / 2 + (x - W / 2) * .78, H * .42 + (y - H * .42) * .78);
ctx.stroke();
}
} if (flash > 0) {
ctx.fillStyle = `rgba(255,100,60,${flash})`;
ctx.fillRect(0, 0, W, H);
} }
// === SIMULATION ===
function update(dt) { if (!run)
return; const left = keys.has('arrowleft') || keys.has('a'), right = keys.has('arrowright') || keys.has('d'), up = keys.has('arrowup') || keys.has('w'), down = keys.has('arrowdown') || keys.has('s'); const tx = (right ? 1 : 0) - (left ? 1 : 0), ty = (down ? 1 : 0) - (up ? 1 : 0); vx += (tx * 2.9 - vx) * Math.min(1, dt * 12); vy += (ty * 2 - vy) * Math.min(1, dt * 12); px += vx * dt; py += vy * dt; px = Math.max(-.82, Math.min(.82, px)); py = Math.max(-.62, Math.min(.55, py)); boost = Math.max(0, boost - dt); speed = Math.min(T.max, speed + T.accel * dt) + (boost > 0 ? T.boost : 0); distance += speed * dt * .16; sun = Math.max(0, 1 - distance / 18000); energy -= T.energyDrain * dt * (sun < .28 ? 2.6 : 1); if (wind && windGain) {
wind.frequency.value = 42 + speed * .13;
windGain.gain.value = .007 + speed / 40000;
} spawnTimer -= dt; if (spawnTimer <= 0) {
spawnWave();
spawnTimer = T.spawn - Math.min(.23, distance / 24000);
} for (let i = items.length - 1; i >= 0; i--) {
const o = items[i];
o.z -= speed * dt / 650;
if (o.z < -.15) {
items.splice(i, 1);
continue;
}
if (o.z < .19 && o.z > -.04 && Math.abs(o.x - px) < (o.w * .62 + .09)) {
if (o.kind === 'token') {
score += 80 * multi;
multi = Math.min(8, multi + .12);
particle(W / 2 + px * W * .36, H * .72, '#ffe35b');
beep(720, .06);
}
else if (o.kind === 'cell') {
energy = Math.min(100, energy + 25);
score += 60 * multi;
particle(W / 2 + px * W * .36, H * .72, '#77ffdd');
beep(480, .1, 'triangle');
}
else if (o.kind === 'orb') {
multi = Math.min(8, multi + 1);
score += 150 * multi;
particle(W / 2 + px * W * .36, H * .72, '#ee8cff', 16);
beep(880, .14);
}
else if (o.kind === 'ramp') {
vy = -.7;
score += 25;
beep(250, .05);
}
else {
flash = .55;
shake = 18;
particle(W / 2 + px * W * .36, H * .72, '#ff684d', 35);
end();
}
items.splice(i, 1);
}
else if (!o.near && o.z < .1 && o.z > 0 && ['rock', 'tower'].includes(o.kind) && Math.abs(o.x - px) < o.w + .19) {
o.near = true;
score += 45 * multi;
shake = 7;
particle(W / 2 + px * W * .36, H * .72, '#ffbd68', 5);
beep(320, .04);
}
} energy = Math.max(0, energy); if (energy <= 0 || sun <= 0)
end(); shake = Math.max(0, shake - dt * 28); flash = Math.max(0, flash - dt * 2.8); score += speed * dt * .08 * multi; ui.distance.textContent = Math.floor(distance).toString().padStart(4, '0'); ui.score.textContent = Math.floor(score).toString().padStart(6, '0'); ui.multi.textContent = 'x' + multi.toFixed(1); ui.speed.textContent = Math.floor(speed).toString(); ui.energy.style.width = energy + '%'; }
function frame(t) { const dt = Math.min(.033, (t - last) / 1000 || .016); last = t; update(dt); ctx.save(); if (shake)
ctx.translate((random() - .5) * shake, (random() - .5) * shake); drawWorld(); items.sort((a, b) => b.z - a.z).forEach(drawItem); drawCraft(); drawFx(dt); ctx.restore(); requestAnimationFrame(frame); }
requestAnimationFrame(frame);
};
// ── entry ──
__require("src/main.ts");
})();
</script>
</body>
</html>
<!-- agent-meta {"model":"openai/gpt-5.6-terra","provider":"openrouter","persona":"typescript","sessionId":"24d677be-d12f-4367-9ea6-7dc9c3a65a38","tokensIn":55574,"tokensOut":5684,"tokensTotal":61258,"turns":7,"toolCalls":9,"failedToolCalls":1,"timestamp":"2026-07-31T18:15:12.510Z"} -->