Canyon Run
GPT 6 Sol · full

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 31,035 bytes · SHA-256 3fdf8f86160f
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>AFTERLIGHT — Canyon Racer</title><script src="https://cdn.jsdelivr.net/npm/three@0.160.1/build/three.min.js"></script><style>
@import url('https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@400;500;600;700;800&family=DM+Mono:wght@400;500&display=swap');
:root{--cream:#ffe6c8;--orange:#ffaf62;--pale:#fff6e7}*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#160f22;color:var(--cream);font-family:'DM Mono',monospace}canvas{display:block}#stage,#fx{position:absolute;inset:0;width:100%;height:100%}#fx{pointer-events:none}#vignette{position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse 70% 60% at 50% 44%,transparent 32%,rgba(13,8,24,.48) 100%);mix-blend-mode:multiply}#grain{position:absolute;inset:0;pointer-events:none;opacity:.12;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.7' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.4'/%3E%3C/svg%3E")}#hud{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .5s}#hud.visible{opacity:1}.hud-top{position:absolute;top:28px;left:36px;right:36px;display:flex;align-items:flex-start;justify-content:space-between}.brand{font-family:'Barlow Condensed',sans-serif;font-size:23px;font-weight:800;letter-spacing:.23em;line-height:1}.brand span{color:var(--orange)}.brand small{display:block;font:10px 'DM Mono',monospace;letter-spacing:.22em;opacity:.58;margin-top:8px}.top-center{text-align:center;position:absolute;left:50%;transform:translateX(-50%);top:0}.label{font-size:9px;letter-spacing:.28em;color:#e7bcae;opacity:.78}.distance{font:600 31px 'Barlow Condensed',sans-serif;letter-spacing:.1em;margin-top:1px}.score-box{text-align:right}.score-box .number{font:700 37px 'Barlow Condensed',sans-serif;letter-spacing:.06em;line-height:1.1}.hud-bottom{position:absolute;bottom:33px;left:36px;right:36px;display:flex;align-items:end;justify-content:space-between;gap:25px}.meter-panel{width:220px}.meter-heading{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:11px}.meter-value{font:600 24px 'Barlow Condensed',sans-serif;letter-spacing:.04em}.track{height:3px;width:100%;background:rgba(255,226,203,.2);position:relative;overflow:visible}.track i{display:block;height:100%;width:50%;background:var(--orange);box-shadow:0 0 13px var(--orange);transition:width .12s linear}.track:after{content:'';position:absolute;right:0;top:-3px;width:1px;height:9px;background:rgba(255,226,203,.45)}.bottom-center{text-align:center;letter-spacing:.16em;color:#ffe0ca;font-size:10px;opacity:.72;padding-bottom:2px}.bottom-center b{color:#fff;font-weight:500}.resources{width:220px}.resource{margin-top:16px}.resource .meter-heading{margin-bottom:9px}.resource .track{height:3px}.resource .track i{background:#ffe7a5;box-shadow:0 0 12px #ffd987}#turboFill{background:#fe805d}.multiplier{position:absolute;right:36px;top:102px;text-align:right;font:700 52px 'Barlow Condensed',sans-serif;color:#ffe5b5;line-height:1;text-shadow:0 0 30px rgba(255,160,84,.5);transform-origin:right center;transition:transform .12s}.multiplier small{display:block;font:10px 'DM Mono',monospace;letter-spacing:.23em;color:#ffbb83;margin-top:5px}#notice{position:absolute;top:31%;left:50%;transform:translate(-50%,-50%);font:700 35px 'Barlow Condensed',sans-serif;letter-spacing:.18em;text-shadow:0 0 25px #ff8a4f;opacity:0;white-space:nowrap}#flash{position:absolute;inset:0;background:#ffddaa;opacity:0;pointer-events:none}#overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(90deg,rgba(18,12,29,.72),rgba(18,12,29,.22) 65%,rgba(18,12,29,.38));transition:opacity .45s;z-index:5}#overlay.hidden{opacity:0;pointer-events:none}.panel{width:min(550px,calc(100% - 48px));margin-left:-27%;padding:10px 0}.eyebrow{font-size:11px;letter-spacing:.35em;color:#ffbb86;margin-bottom:21px}.eyebrow:before{content:'';display:inline-block;width:26px;height:1px;background:#ffbb86;vertical-align:middle;margin-right:13px}.panel h1{font:800 clamp(74px,9vw,130px)/.78 'Barlow Condensed',sans-serif;letter-spacing:-.025em;margin:0;color:#fff3e5;text-shadow:0 8px 40px rgba(39,11,19,.4)}.panel h1 em{font-style:normal;color:#ffae70}.panel p{font-size:11px;line-height:1.9;letter-spacing:.045em;color:#e8cbbd;max-width:410px;margin:28px 0 25px}.rule{height:1px;background:linear-gradient(90deg,rgba(255,211,171,.45),transparent);margin:0 0 23px}.controls{display:flex;gap:24px;flex-wrap:wrap;font-size:10px;letter-spacing:.1em;color:#f4d4bf}.controls strong{font-weight:500;color:#fff7e9;border:1px solid rgba(255,224,193,.4);padding:5px 7px;margin-right:5px}.action{margin-top:35px;padding:15px 25px;border:1px solid #ffc28c;background:#ffb679;color:#281624;font:700 17px 'Barlow Condensed',sans-serif;letter-spacing:.2em;cursor:pointer;transition:transform .18s,background .18s,box-shadow .18s;box-shadow:0 8px 32px rgba(255,116,66,.26)}.action:hover{transform:translateY(-3px);background:#ffcf9b;box-shadow:0 10px 35px rgba(255,137,69,.45)}.action span{margin-left:35px}.foot{position:absolute;bottom:29px;left:36px;font-size:9px;letter-spacing:.18em;color:#e5c3ba;opacity:.7}.version{position:absolute;bottom:29px;right:36px;font-size:9px;letter-spacing:.15em;color:#e5c3ba;opacity:.7}#gameover .panel h1{font-size:clamp(67px,8vw,112px)}.results{display:flex;gap:42px;margin:30px 0}.result span{display:block;font-size:9px;color:#e5b7a3;letter-spacing:.2em;margin-bottom:6px}.result strong{font:700 36px 'Barlow Condensed',sans-serif;color:#fff1df}#gameover{display:none}.mobile-controls{display:none}@media(max-width:700px){.panel{margin-left:0;padding:0 23px}.panel h1{font-size:76px}.hud-top{left:18px;right:18px;top:17px}.brand{font-size:17px}.brand small{font-size:8px}.distance{font-size:22px}.score-box .number{font-size:26px}.hud-bottom{left:18px;right:18px;bottom:18px}.meter-panel,.resources{width:34%}.bottom-center{display:none}.multiplier{right:18px;top:85px;font-size:38px}.foot{left:23px;bottom:14px}.version{right:23px;bottom:14px}.mobile-controls{display:flex;position:absolute;inset:auto 0 92px;justify-content:space-between;padding:0 18px;pointer-events:auto}.mobile-controls button{border:1px solid #ffdfbd88;background:#27182966;color:#fff3e2;font:24px 'Barlow Condensed';width:57px;height:55px;touch-action:none}.mobile-controls .side{display:flex;gap:9px}}
</style></head><body><canvas id="stage"></canvas><canvas id="fx"></canvas><div id="vignette"></div><div id="grain"></div><div id="flash"></div>
<div id="hud"><div class="hud-top"><div class="brand">AFTER<span>LIGHT</span><small>THE LAST HORIZON</small></div><div class="top-center"><div class="label">DISTANCE</div><div class="distance" id="distance">00000 <span style="font-size:12px;opacity:.7">M</span></div></div><div class="score-box"><div class="label">SCORE</div><div class="number" id="score">000000</div></div></div><div class="multiplier" id="mult">x1.0<small>PROXIMITY BONUS</small></div><div id="notice">NEAR MISS +500</div><div class="hud-bottom"><div class="meter-panel"><div class="meter-heading"><span class="label">VELOCITY</span><span class="meter-value" id="speed">000 <small style="font:10px 'DM Mono'">KM/H</small></span></div><div class="track"><i id="speedFill"></i></div></div><div class="bottom-center"><b>← →</b> BANK / <b>↑ ↓</b> PITCH / <b>SPACE</b> BOOST</div><div class="resources"><div class="resource"><div class="meter-heading"><span class="label">SOLAR ENERGY</span><span class="label" id="energyNum">100%</span></div><div class="track"><i id="energyFill"></i></div></div><div class="resource"><div class="meter-heading"><span class="label">TURBO</span><span class="label" id="turboNum">0%</span></div><div class="track"><i id="turboFill"></i></div></div></div></div><div class="mobile-controls"><div class="side"><button data-key="ArrowLeft">◀</button><button data-key="ArrowRight">▶</button></div><div class="side"><button data-key="ArrowDown">▼</button><button data-key="ArrowUp">▲</button><button data-key="Space">⚡</button></div></div></div>
<div id="overlay"><div id="intro" class="panel"><div class="eyebrow">ENDLESS CANYON RUN / 01</div><h1>CHASE<br>THE <em>LAST</em><br>LIGHT.</h1><p>Skim the edge. Thread the impossible. Gather solar fragments to keep your engine alive — the closer you fly, the faster you score.</p><div class="rule"></div><div class="controls"><div><strong>← →</strong> BANK</div><div><strong>↑ ↓</strong> PITCH</div><div><strong>SPACE</strong> TURBO</div></div><button class="action" id="startBtn">INITIATE FLIGHT <span>↗</span></button></div><div id="gameover" class="panel"><div class="eyebrow">SIGNAL LOST / RUN COMPLETE</div><h1>THE SUN<br><em>SETS.</em></h1><div class="results"><div class="result"><span>FINAL SCORE</span><strong id="finalScore">0</strong></div><div class="result"><span>MAX SPEED</span><strong id="maxSpeed">0</strong></div></div><div class="rule"></div><button class="action" id="restartBtn">FLY AGAIN <span>↗</span></button></div><div class="foot">SURVIVE THE FALLING LIGHT</div><div class="version">BUILD 01 / ∞</div></div>
<script>
(()=>{'use strict';
const $=id=>document.getElementById(id),canvas=$('stage'),fx=$('fx'),fctx=fx.getContext('2d');let ctx=null;let W=0,H=0,dpr=1;const hasThree=!!window.THREE;let renderer,scene,camera,craft,engineGlow,sunMesh,worldGroup,orbGeo,rockGeo,mat={};let chunks=[],particles=[],keys={},audio=null,hum=null,humGain=null,noiseBuffer=null;
const S={mode:'menu',t:0,z:0,x:0,y:1.2,vx:0,vy:0,speed:32,energy:1,turbo:.12,boost:false,score:0,mult:1,maxSpeed:0,nearCooldown:0,shake:0,flash:0,notice:0,roll:0,pitch:0,straight:0,dist:0};
function rnd(n){let x=Math.sin(n*127.1+78.233)*43758.5453;return x-Math.floor(x)}
function center(z){return Math.sin(z*.006)*3+Math.sin(z*.014+1.7)*1.5}function width(z){return 10.8+Math.sin(z*.010+2)*1.5+Math.sin(z*.024)*.6-Math.min(2.3,S.z/550)}
function resize(){W=innerWidth;H=innerHeight;dpr=Math.min(devicePixelRatio||1,2);for(let c of [canvas,fx]){c.width=Math.round(W*dpr);c.height=Math.round(H*dpr);c.style.width=W+'px';c.style.height=H+'px'}if(ctx)ctx.setTransform(dpr,0,0,dpr,0,0);fctx.setTransform(dpr,0,0,dpr,0,0);if(renderer){renderer.setSize(W,H,false);renderer.setPixelRatio(dpr);camera.aspect=W/H;camera.updateProjectionMatrix()}}addEventListener('resize',resize);
function makeThree(){if(!hasThree)return;try{renderer=new THREE.WebGLRenderer({canvas,antialias:true,alpha:false,powerPreference:'high-performance'});renderer.setPixelRatio(dpr);renderer.setSize(W,H,false);renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=1.32;scene=new THREE.Scene();scene.background=new THREE.Color(0x9b5774);scene.fog=new THREE.FogExp2(0xc37f7d,.0085);camera=new THREE.PerspectiveCamera(76,W/H,.1,850);worldGroup=new THREE.Group();scene.add(worldGroup);scene.add(new THREE.HemisphereLight(0xffcfa8,0x342448,2.0));let sun=new THREE.DirectionalLight(0xffba76,2.8);sun.position.set(-65,65,100);scene.add(sun);let sunGeo=new THREE.SphereGeometry(25,24,12),sunMat=new THREE.MeshBasicMaterial({color:0xffd8a0,fog:false});sunMesh=new THREE.Mesh(sunGeo,sunMat);sunMesh.position.set(-44,24,420);scene.add(sunMesh);
mat.floor=new THREE.MeshLambertMaterial({color:0x704258,flatShading:true,side:THREE.DoubleSide});mat.wall=[0x75435a,0x89566a,0xa26671,0x59405b,0xc07874].map(c=>new THREE.MeshLambertMaterial({color:c,flatShading:true,side:THREE.DoubleSide}));mat.rock=new THREE.MeshLambertMaterial({color:0x3b344e,flatShading:true});mat.rock2=new THREE.MeshLambertMaterial({color:0x655067,flatShading:true});mat.orb=new THREE.MeshBasicMaterial({color:0xffe9aa});mat.ring=new THREE.MeshBasicMaterial({color:0xffc377,side:THREE.DoubleSide});mat.craft=new THREE.MeshLambertMaterial({color:0xeee6dc,flatShading:true,side:THREE.DoubleSide});mat.craftDark=new THREE.MeshLambertMaterial({color:0x343449,flatShading:true,side:THREE.DoubleSide});mat.engine=new THREE.MeshBasicMaterial({color:0xffae66});mat.shadow=new THREE.MeshBasicMaterial({color:0x2b213e,transparent:true,opacity:.28,depthWrite:false,side:THREE.DoubleSide});mat.glow=new THREE.SpriteMaterial({map:glowTexture(),color:0xffba74,transparent:true,blending:THREE.AdditiveBlending,depthWrite:false});orbGeo=new THREE.OctahedronGeometry(.68,0);rockGeo=new THREE.DodecahedronGeometry(1,0);
craft=new THREE.Group();scene.add(craft);function mesh(g,m,x,y,z){let a=new THREE.Mesh(g,m);a.position.set(x,y,z);craft.add(a);return a}let hull=new THREE.BufferGeometry();hull.setAttribute('position',new THREE.Float32BufferAttribute([0,.13,3.5,-.75,0,-1.25,.75,0,-1.25, 0,.13,3.5,0,.65,-.2,-.75,0,-1.25, 0,.13,3.5,.75,0,-1.25,0,.65,-.2, -.75,0,-1.25,0,.65,-.2,.75,0,-1.25],3));hull.computeVertexNormals();mesh(hull,mat.craft,0,0,0);let wing=new THREE.BufferGeometry();wing.setAttribute('position',new THREE.Float32BufferAttribute([-5.1,-.13,-1.2,-.5,.05,.55,-.62,0,-1.5, .62,0,-1.5,.5,.05,.55,5.1,-.13,-1.2, -5.1,-.13,-1.2,-.62,0,-1.5,-3.8,-.14,-2.05, .62,0,-1.5,5.1,-.13,-1.2,3.8,-.14,-2.05],3));wing.computeVertexNormals();mesh(wing,mat.craft,0,0,0);mesh(new THREE.BoxGeometry(.8,.24,1.4),mat.craftDark,0,.28,-.5);for(let x of [-2.7,2.7]){mesh(new THREE.BoxGeometry(.18,.25,.95),mat.engine,x,-.06,-1.25)}engineGlow=mesh(new THREE.ConeGeometry(.26,1.8,5),new THREE.MeshBasicMaterial({color:0xff9b52,transparent:true,opacity:.86}),0,-.08,-2.2);engineGlow.rotation.x=-Math.PI/2;
}catch(e){console.warn('WebGL unavailable, using canvas renderer',e);renderer=null;}}
function canyonMesh(start){let group=new THREE.Group();let vert=[],cols=[],floor=[];for(let i=0;i<8;i++){let z=start+i*4,z2=z+4;let c=center(z),c2=center(z2),w=width(z),w2=width(z2);let l=c-w,r=c+w,l2=c2-w2,r2=c2+w2;floor.push(l,-2.85,z,r,-2.85,z,l2,-2.85,z2,r,-2.85,z,l2,-2.85,z2,r2,-2.85,z2);for(let side of [-1,1]){let a=c+side*w,b=c2+side*w2;for(let layer=0;layer<3;layer++){let d0=layer===0?0:layer===1?2.7:7,d1=layer===0?2.7:layer===1?7:16;let h0=layer===0?-2.85:layer===1?-.3:4.8,h1=layer===0?-.3:layer===1?4.8:11;let x0=a+side*d0,x1=a+side*d1,x02=b+side*d0,x12=b+side*d1;let jitter=Math.sin(z*.31+side*5+layer*7)*.7;vert.push(x0,h0,z,x1+jitter,h1,z,x02,h0,z2,x1+jitter,h1,z,x12-jitter,h1,z2,x02,h0,z2);}}}let g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(vert,3));g.computeVertexNormals();let mesh=new THREE.Mesh(g,mat.wall[(Math.floor(start/28)%5)]);group.add(mesh);let fg=new THREE.BufferGeometry();fg.setAttribute('position',new THREE.Float32BufferAttribute(floor,3));fg.computeVertexNormals();group.add(new THREE.Mesh(fg,mat.floor));let shadows=[];for(let side of [-1,1]){let zz=start+2,cc=center(zz),ww=width(zz),xx=cc+side*(ww-1);shadows.push(xx,-2.825,zz,xx-side*(ww*.9),-2.825,zz+14,xx+side*.4,-2.825,zz+24)}let sg=new THREE.BufferGeometry();sg.setAttribute('position',new THREE.Float32BufferAttribute(shadows,3));sg.computeVertexNormals();group.add(new THREE.Mesh(sg,mat.shadow));return group}
function buildChunk(index){let start=index*28,ch={index,start,end:start+28,objects:[],group:null};if(index>=3){let difficulty=Math.min(1,(S.z/1100));let n=rnd(index*2.3)<.33+difficulty*.25?2:1;for(let j=0;j<n;j++){let z=start+8+j*12+rnd(index*9+j)*5;let c=center(z),w=width(z);let kind=rnd(index*12+j*7);if(kind<.31){let gapX=c+(rnd(index*4+j*5)-.5)*w*.55;let gap=4.8-difficulty*1.2;for(let side of [-1,1]){let boundary=side<0?c-w: c+w;let edge=gapX+side*gap/2;let x=(boundary+edge)/2;ch.objects.push({type:'gate',x,y:1.3,z,hw:Math.abs(boundary-edge)/2,hh:4.1,depth:1.1,near:false});}}else{let x=c+(rnd(index*33+j*13)-.5)*w*1.3;ch.objects.push({type:'rock',x,y:.4+rnd(index+j)*1.2,z,hw:1.3+rnd(index+j*17)*.6,hh:2.4,depth:1.4,near:false});}let oz=z+(j?5:3);ch.objects.push({type:'orb',x:c+(rnd(index*18+j*4)-.5)*w*1.05,y:.8+rnd(index*6+j)*2.6,z:oz,hw:.8,hh:.8,depth:.8,taken:false});}}if(renderer){let group=canyonMesh(start);for(let o of ch.objects){if(o.type==='orb'){let m=new THREE.Group();let core=new THREE.Mesh(orbGeo,mat.orb);m.add(core);let ring=new THREE.Mesh(new THREE.TorusGeometry(1.05,.055,5,24),mat.ring);ring.rotation.y=.3;m.add(ring);let light=new THREE.Sprite(mat.glow);light.scale.set(5,5,1);m.add(light);m.position.set(o.x,o.y,o.z);group.add(m);o.mesh=m}else{let m;if(o.type==='gate'){m=new THREE.Mesh(new THREE.BoxGeometry(o.hw*2,o.hh*2,o.depth*2),mat.rock);m.position.set(o.x,o.y,o.z);let cap=new THREE.Mesh(new THREE.BoxGeometry(o.hw*2+.15,.15,o.depth*2+.3),mat.rock2);cap.position.y=o.hh; m.add(cap)}else{m=new THREE.Mesh(rockGeo,mat.rock);m.position.set(o.x,o.y,o.z);m.scale.set(o.hw,o.hh,o.depth);m.rotation.y=rnd(o.z)*3}group.add(m);o.mesh=m}}worldGroup.add(group);ch.group=group}chunks.push(ch)}
let glowTex;function glowTexture(){if(glowTex)return glowTex;let c=document.createElement('canvas');c.width=c.height=64;let x=c.getContext('2d'),g=x.createRadialGradient(32,32,2,32,32,32);g.addColorStop(0,'rgba(255,255,220,1)');g.addColorStop(.17,'rgba(255,196,116,.75)');g.addColorStop(1,'rgba(255,149,75,0)');x.fillStyle=g;x.fillRect(0,0,64,64);glowTex=new THREE.CanvasTexture(c);return glowTex}
function ensureChunks(){let max=Math.floor((S.z+290)/28);let last=chunks.length?chunks[chunks.length-1].index:-1;for(let i=last+1;i<=max;i++)buildChunk(i);while(chunks.length&&chunks[0].end<S.z-35){let ch=chunks.shift();if(ch.group){worldGroup.remove(ch.group);ch.group.traverse(a=>{if(a.geometry&&a.geometry!==orbGeo&&a.geometry!==rockGeo)a.geometry.dispose()})}}}
function initAudio(){try{if(!audio){audio=new (window.AudioContext||window.webkitAudioContext)();let osc=audio.createOscillator(),filter=audio.createBiquadFilter();humGain=audio.createGain();osc.type='sawtooth';osc.frequency.value=65;filter.type='lowpass';filter.frequency.value=160;humGain.gain.value=.0001;osc.connect(filter).connect(humGain).connect(audio.destination);osc.start();hum=osc}audio.resume()}catch(e){}}
function tone(freq,duration,type='sine',vol=.08,slide=1){if(!audio)return;let o=audio.createOscillator(),g=audio.createGain(),t=audio.currentTime;o.type=type;o.frequency.setValueAtTime(freq,t);o.frequency.exponentialRampToValueAtTime(Math.max(20,freq*slide),t+duration);g.gain.setValueAtTime(vol,t);g.gain.exponentialRampToValueAtTime(.001,t+duration);o.connect(g).connect(audio.destination);o.start(t);o.stop(t+duration+.01)}
function reset(){S.mode='playing';S.t=0;S.z=0;S.x=center(0);S.y=1.2;S.vx=S.vy=0;S.speed=32;S.energy=1;S.turbo=.12;S.boost=false;S.score=0;S.mult=1;S.maxSpeed=0;S.nearCooldown=0;S.shake=0;S.flash=0;S.notice=0;S.roll=0;S.pitch=0;S.straight=0;S.dist=0;for(let ch of chunks)if(ch.group){worldGroup.remove(ch.group);ch.group.traverse(a=>{if(a.geometry&&a.geometry!==orbGeo&&a.geometry!==rockGeo)a.geometry.dispose()})}chunks=[];particles=[];ensureChunks();$('intro').style.display='none';$('gameover').style.display='none';$('overlay').classList.add('hidden');$('hud').classList.add('visible');initAudio();tone(330,.2,'sine',.07,1.8)}
function end(reason){if(S.mode!=='playing')return;S.mode='over';S.shake=1.3;S.flash=.55;tone(120,.7,'sawtooth',.12,.16);$('finalScore').textContent=Math.floor(S.score).toLocaleString();$('maxSpeed').textContent=Math.floor(S.maxSpeed*8)+' KM/H';$('gameover').style.display='block';$('overlay').classList.remove('hidden');$('hud').classList.remove('visible');if(humGain)humGain.gain.setTargetAtTime(.0001,audio.currentTime,.15)}
$('startBtn').onclick=reset;$('restartBtn').onclick=reset;addEventListener('keydown',e=>{if(['ArrowUp','ArrowDown','ArrowLeft','ArrowRight','Space'].includes(e.code))e.preventDefault();keys[e.code]=true;if((e.code==='Enter'||e.code==='Space')&&S.mode!=='playing')reset()});addEventListener('keyup',e=>keys[e.code]=false);for(let b of document.querySelectorAll('[data-key]')){let key=b.dataset.key;b.addEventListener('pointerdown',e=>{e.preventDefault();keys[key]=true;b.setPointerCapture(e.pointerId)});b.addEventListener('pointerup',()=>keys[key]=false);b.addEventListener('pointercancel',()=>keys[key]=false)}
function nearMiss(){S.mult=Math.min(8,S.mult+.5);S.score+=Math.round(350*S.mult);S.turbo=Math.min(1,S.turbo+.095);S.notice=1.15;S.flash=Math.max(S.flash,.12);S.shake=Math.max(S.shake,.22);S.nearCooldown=.45;tone(125,.26,'triangle',.065,2.7)}function collect(o){o.taken=true;if(o.mesh)o.mesh.visible=false;S.energy=Math.min(1,S.energy+.25);S.turbo=Math.min(1,S.turbo+.17);S.score+=Math.round(250*S.mult);S.notice=.9;S.flash=.18;tone(660,.36,'sine',.11,2.2);setTimeout(()=>tone(990,.2,'sine',.045,1.4),85)}
function update(dt){S.t+=dt;if(S.mode!=='playing'){if(S.mode==='menu'){S.z+=dt*8;S.x=center(S.z);S.y=1.15;ensureChunks()}S.shake=Math.max(0,S.shake-dt*2);return}let left=keys.ArrowLeft||keys.KeyA,right=keys.ArrowRight||keys.KeyD,up=keys.ArrowUp||keys.KeyW,down=keys.ArrowDown||keys.KeyS;let steer=(right?1:0)-(left?1:0),pitch=(up?1:0)-(down?1:0);S.boost=!!(keys.Space&&S.turbo>.02);let target=37+Math.min(23,S.score/10000)+(S.boost?34:0)+(pitch<0?4:0)-(pitch>0?2:0);S.speed+=(target-S.speed)*Math.min(1,dt*(S.boost?2.8:1.1));S.maxSpeed=Math.max(S.maxSpeed,S.speed);S.vx+=(steer*(24+S.speed*.16)-S.vx*3.5)*dt;S.vy+=(pitch*14-S.vy*3.8)*dt;S.x+=S.vx*dt;S.y=Math.max(-1.55,Math.min(7.2,S.y+S.vy*dt));S.z+=S.speed*dt;S.dist+=S.speed*dt;S.roll+=(-steer*.62-S.vx*.012-S.roll)*Math.min(1,dt*7);S.pitch+=(-pitch*.23-S.pitch)*Math.min(1,dt*5);S.energy-=dt*(.035+(S.boost?.044:0));if(S.boost)S.turbo=Math.max(0,S.turbo-dt*.24);else{S.straight=steer?0:S.straight+dt;if(S.straight>1.4&&S.speed>34)S.turbo=Math.min(1,S.turbo+dt*.024)}S.mult=Math.max(1,S.mult-dt*.11);S.nearCooldown-=dt;S.notice-=dt;S.flash=Math.max(0,S.flash-dt*1.5);S.shake=Math.max(0,S.shake-dt*1.6);S.score+=S.speed*dt*.32*S.mult;ensureChunks();let clearance=width(S.z)-Math.abs(S.x-center(S.z))-.75;if(clearance<0){end('wall');return}if(S.y<=-1.5){end('ground');return}let closest=clearance;for(let ch of chunks){if(ch.start>S.z+8||ch.end<S.z-8)continue;for(let o of ch.objects){if(o.taken)continue;let dz=Math.abs(S.z-o.z);if(dz>6)continue;let dx=Math.abs(S.x-o.x),dy=Math.abs(S.y-o.y);if(o.type==='orb'){if(dz<2.25&&dx<1.5&&dy<1.5)collect(o)}else{let sepX=dx-o.hw-.55,sepY=dy-o.hh-.24,sepZ=dz-o.depth-1.2;if(sepX<0&&sepY<0&&sepZ<0){end('collision');return}if(sepZ<1.2){let gap=Math.max(sepX,sepY);if(gap>=0)closest=Math.min(closest,gap);if(!o.near&&dz<1.8&&gap>=0&&gap<2.25){o.near=true;nearMiss()}}}}}if(clearance<2.3&&S.nearCooldown<=0)nearMiss();if(closest<2)S.shake=Math.max(S.shake,(2-closest)*.08);if(S.boost)S.shake=Math.max(S.shake,.13);if(S.energy<=0)end('energy');if(hum&&audio){hum.frequency.setTargetAtTime(55+S.speed*1.25,audio.currentTime,.09);humGain.gain.setTargetAtTime(S.mode==='playing'?.025+S.speed*.00025:.0001,audio.currentTime,.1)}for(let ch of chunks)for(let o of ch.objects)if(o.type==='orb'&&o.mesh&&!o.taken){o.mesh.rotation.y+=dt*1.3;o.mesh.children[0].rotation.z+=dt*.8;o.mesh.position.y=o.y+Math.sin(S.t*3+o.z)*.19}}
function project(x,y,z){let dz=z-S.z+13;if(dz<.2)return null;let focal=Math.min(W*.92,H*1.19);let scale=focal/(dz+15);let camX=S.x*.48,camY=S.y+3.5;return {x:W/2+(x-camX)*scale,y:H*.55-(y-camY)*scale+Math.sin(S.t*.3)*2,s:scale,d:dz}}
function poly(points,fill,stroke){if(points.some(p=>!p))return;ctx.beginPath();ctx.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)ctx.lineTo(points[i].x,points[i].y);ctx.closePath();ctx.fillStyle=fill;ctx.fill();if(stroke){ctx.strokeStyle=stroke;ctx.lineWidth=1;ctx.stroke()}}
function fallback(){let sky=ctx.createLinearGradient(0,0,0,H);sky.addColorStop(0,'#322441');sky.addColorStop(.36,'#80506d');sky.addColorStop(.68,'#efa47d');sky.addColorStop(1,'#9c6269');ctx.fillStyle=sky;ctx.fillRect(0,0,W,H);let sunX=W*.38,sunY=H*.42;let halo=ctx.createRadialGradient(sunX,sunY,1,sunX,sunY,H*.43);halo.addColorStop(0,'rgba(255,229,178,.65)');halo.addColorStop(.25,'rgba(255,176,124,.28)');halo.addColorStop(1,'rgba(255,180,120,0)');ctx.fillStyle=halo;ctx.fillRect(0,0,W,H);ctx.fillStyle='#ffe1a8';ctx.beginPath();ctx.arc(sunX,sunY,Math.min(W,H)*.105,0,Math.PI*2);ctx.fill();ctx.fillStyle='#bd7680';for(let i=0;i<10;i++){let bx=i*W/8-W*.1,h=H*(.05+rnd(i*12)*.12);poly([{x:bx,y:H*.51},{x:bx+W*.13,y:H*.51-h},{x:bx+W*.3,y:H*.51}],i%2?'#a9667a':'#af6c7a')}
let far=Math.floor((S.z+290)/7)*7,near=Math.floor((S.z-14)/7)*7;for(let z=far;z>=near;z-=7){let z2=z+7,c=center(z),w=width(z),c2=center(z2),w2=width(z2),p=(x,y,a)=>project(x,y,a);let fade=Math.min(1,Math.max(0,(z-S.z)/260));let floorColor=z%14===0?'#764760':'#6c425b';poly([p(c-w,-2.9,z),p(c+w,-2.9,z),p(c2+w2,-2.9,z2),p(c2-w2,-2.9,z2)],floorColor);for(let side of [-1,1]){let x=c+side*w,x2=c2+side*w2;poly([p(x,-2.9,z),p(x+side*3,.2,z),p(x2+side*3,.2,z2),p(x2,-2.9,z2)],side<0?'#8a5268':'#644157');poly([p(x+side*3,.2,z),p(x+side*8,5,z),p(x2+side*8,5,z2),p(x2+side*3,.2,z2)],side<0?'#9d6170':'#70465f');poly([p(x+side*8,5,z),p(x+side*17,11,z),p(x2+side*17,11,z2),p(x2+side*8,5,z2)],side<0?'#b77378':'#865269');let a=p(x,.1,z),b=p(x2,.1,z2);if(a&&b){ctx.strokeStyle='rgba(255,180,130,.15)';ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(a.x,a.y);ctx.lineTo(b.x,b.y);ctx.stroke()}}}
let objects=[];for(let ch of chunks)for(let o of ch.objects)if(!o.taken&&o.z>S.z-10&&o.z<S.z+250)objects.push(o);objects.sort((a,b)=>b.z-a.z);for(let o of objects){let p=project(o.x,o.y,o.z);if(!p)continue;let sc=p.s;if(o.type==='orb'){let rr=Math.max(2,sc*.72);let glow=ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,rr*4.5);glow.addColorStop(0,'rgba(255,250,202,.9)');glow.addColorStop(.23,'rgba(255,186,100,.5)');glow.addColorStop(1,'rgba(255,158,81,0)');ctx.fillStyle=glow;ctx.fillRect(p.x-rr*5,p.y-rr*5,rr*10,rr*10);ctx.save();ctx.translate(p.x,p.y);ctx.rotate(S.t*1.5);ctx.strokeStyle='#ffde9e';ctx.lineWidth=Math.max(1,sc*.07);ctx.strokeRect(-rr*1.1,-rr*1.1,rr*2.2,rr*2.2);ctx.fillStyle='#fff5ca';ctx.beginPath();ctx.moveTo(0,-rr);ctx.lineTo(rr,0);ctx.lineTo(0,rr);ctx.lineTo(-rr,0);ctx.fill();ctx.restore()}else{let hw=o.hw*sc,hh=o.hh*sc,dep=Math.max(3,o.depth*sc*.6);let x=p.x,y=p.y;poly([{x:x-hw,y:y-hh},{x:x+hw,y:y-hh},{x:x+hw,y:y+hh},{x:x-hw,y:y+hh}],'#3c344d');poly([{x:x-hw,y:y-hh},{x:x-hw+dep,y:y-hh-dep},{x:x+hw+dep,y:y-hh-dep},{x:x+hw,y:y-hh}],'#ad7479');poly([{x:x+hw,y:y-hh},{x:x+hw+dep,y:y-hh-dep},{x:x+hw+dep,y:y+hh-dep},{x:x+hw,y:y+hh}],'#69516b')}}
// Camera-facing craft: crisp angular silhouette with glowing twin engines.
let cx=W*.5+S.x*.05,cy=H*.72+S.y*.8,unit=Math.min(W,H)/720;ctx.save();ctx.translate(cx,cy);ctx.rotate(-S.roll*.6);ctx.scale(unit,unit);let eg=ctx.createRadialGradient(0,25,3,0,25,85);eg.addColorStop(0,S.boost?'rgba(255,236,180,.9)':'rgba(255,154,90,.55)');eg.addColorStop(1,'rgba(255,147,80,0)');ctx.fillStyle=eg;ctx.fillRect(-100,-40,200,150);poly([{x:-35,y:15},{x:-155,y:40},{x:-106,y:49},{x:-24,y:42},{x:0,y:-25},{x:24,y:42},{x:106,y:49},{x:155,y:40},{x:35,y:15}], '#e7d9cf');poly([{x:0,y:-25},{x:-24,y:42},{x:0,y:29}], '#fff1dc');poly([{x:0,y:-25},{x:0,y:29},{x:24,y:42}], '#ad9ba4');poly([{x:-23,y:37},{x:0,y:23},{x:23,y:37},{x:0,y:52}],'#3b394b');for(let side of [-1,1]){ctx.fillStyle='#ffb970';ctx.shadowBlur=25;ctx.shadowColor='#ff9f58';ctx.fillRect(side*88-6,44,12,S.boost?28:13);ctx.shadowBlur=0}ctx.restore()}
function drawFX(dt){fctx.clearRect(0,0,W,H);if(S.mode==='menu')return;if(S.mode==='playing'){for(let side of [-1,1]){let ex,ey;if(renderer){let v=new THREE.Vector3(S.x+side*2.7,S.y-.06,S.z-.2).project(camera);ex=(v.x+1)*W/2;ey=(1-v.y)*H/2}else{ex=W*.5+side*Math.min(W,H)*.14;ey=H*.74}particles.push({x:ex+(Math.random()-.5)*4,y:ey,dx:(Math.random()-.5)*22+side*8,dy:65+Math.random()*105+(S.boost?140:0),life:1,size:S.boost?5:3})}}for(let i=particles.length-1;i>=0;i--){let p=particles[i];p.x+=p.dx*dt;p.y+=p.dy*dt;p.life-=dt*(S.boost?1.9:2.7);if(p.life<=0){particles.splice(i,1);continue}let g=fctx.createRadialGradient(p.x,p.y,0,p.x,p.y,p.size*5*p.life);g.addColorStop(0,`rgba(255,241,184,${p.life*.8})`);g.addColorStop(.3,`rgba(255,149,83,${p.life*.5})`);g.addColorStop(1,'rgba(255,125,63,0)');fctx.fillStyle=g;fctx.fillRect(p.x-p.size*5,p.y-p.size*5,p.size*10,p.size*10)}let speedRatio=S.speed/75,amount=Math.round(8+speedRatio*17+(S.boost?18:0));fctx.lineCap='round';for(let i=0;i<amount;i++){let seed=i*19.73,phase=(S.t*(.35+speedRatio*.6)+rnd(seed))%1;let x=W/2+(rnd(seed+1)-.5)*W*1.65*phase,y=H*.52+(rnd(seed+2)-.5)*H*1.45*phase;let dx=(x-W/2)*(.025+speedRatio*.07),dy=(y-H*.52)*(.025+speedRatio*.07);fctx.strokeStyle=`rgba(255,220,185,${(.05+phase*.18)*(S.boost?1.8:1)})`;fctx.lineWidth=phase*1.6+.3;fctx.beginPath();fctx.moveTo(x,y);fctx.lineTo(x+dx,y+dy);fctx.stroke()}let n=$('notice');n.style.opacity=S.notice>0?Math.min(1,S.notice*2):0;n.style.transform=`translate(-50%,-50%) scale(${1+(1.15-S.notice)*.06})`;$('flash').style.opacity=S.flash*.65}
function updateHUD(){if(S.mode!=='playing')return;$('score').textContent=String(Math.floor(S.score)).padStart(6,'0');$('distance').innerHTML=String(Math.floor(S.dist)).padStart(5,'0')+' <span style="font-size:12px;opacity:.7">M</span>';$('speed').innerHTML=String(Math.floor(S.speed*8)).padStart(3,'0')+' <small style="font:10px DM Mono">KM/H</small>';$('speedFill').style.width=Math.min(100,S.speed/78*100)+'%';$('energyFill').style.width=Math.max(0,S.energy*100)+'%';$('energyNum').textContent=Math.max(0,Math.round(S.energy*100))+'%';$('turboFill').style.width=S.turbo*100+'%';$('turboNum').textContent=Math.round(S.turbo*100)+'%';$('mult').innerHTML='x'+S.mult.toFixed(1)+'<small>PROXIMITY BONUS</small>';$('mult').style.transform=`scale(${S.notice>0?1.12:1})`;$('energyFill').style.background=S.energy<.25?'#ff686e':'#ffe7a5'}
function render(){if(renderer){sunMesh.position.z=S.z+420;let shake=S.shake;camera.position.set(S.x*.48+(Math.random()-.5)*shake*.16,S.y+3.5+(Math.random()-.5)*shake*.12,S.z-13);camera.lookAt(S.x*.42,S.y+.3,S.z+42);camera.fov+=((S.boost?91:76)-camera.fov)*.055;camera.updateProjectionMatrix();craft.position.set(S.x,S.y,S.z+1.1);craft.rotation.set(S.pitch,0,S.roll);engineGlow.scale.y=S.boost?2.1:1;renderer.render(scene,camera)}else fallback()}
resize();makeThree();if(!renderer){ctx=canvas.getContext('2d');ctx.setTransform(dpr,0,0,dpr,0,0)}ensureChunks();let last=performance.now();function frame(now){let dt=Math.min(.05,(now-last)/1000||.016);last=now;update(dt);render();drawFX(dt);updateHUD();requestAnimationFrame(frame)}requestAnimationFrame(frame);
})();
</script></body></html>
<!-- agent-meta {"model":"openai/gpt-6-sol","provider":"openrouter","persona":"full","sessionId":"9f862539-2584-4a65-bc9e-03ba631ecddf","tokensIn":568052,"tokensOut":17332,"tokensTotal":585384,"cost":0.3607389999999999,"turns":25,"toolCalls":24,"failedToolCalls":0,"timestamp":"2026-09-23T14:24:32.498Z"} -->