← Flight Simulator results

Flight Simulator

GPT 6 Sol · full

◈Preview unavailable — try playing the result

Browser check: Preview unavailable or timed out. 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 37,256 bytes · SHA-256 becb3f5a914a
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>APEX AERO — Flight Simulator</title><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{--cyan:#a8e9ed;--lime:#d8fa9c;--white:#f3f5ee;--muted:#a3b4b8;--dark:#071218}*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#081720;color:var(--white);font-family:'Barlow Condensed',Arial,sans-serif}canvas{position:fixed;inset:0;width:100%;height:100%;display:block}#world{z-index:0}#shade{position:fixed;inset:0;pointer-events:none;z-index:1;background:linear-gradient(90deg,rgba(4,17,23,.7) 0%,rgba(4,17,23,.25) 45%,transparent 85%),linear-gradient(0deg,rgba(3,12,19,.68),transparent 34%);transition:opacity .6s}#grain{position:fixed;inset:0;pointer-events:none;z-index:3;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='.72' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.34'/%3E%3C/svg%3E")}#app{position:fixed;inset:0;z-index:4;pointer-events:none}.mono{font-family:'DM Mono',monospace}.topbar{position:absolute;top:0;left:0;right:0;height:70px;display:flex;align-items:center;justify-content:space-between;padding:0 46px;border-bottom:1px solid rgba(224,248,246,.17);background:linear-gradient(180deg,rgba(4,17,24,.55),transparent);pointer-events:auto}.brand{display:flex;align-items:center;gap:12px;font-weight:800;font-size:25px;letter-spacing:.13em;line-height:1}.brand svg{width:31px;height:31px;fill:var(--lime)}.brand small{display:block;font-family:'DM Mono';font-weight:400;font-size:8px;letter-spacing:.26em;color:var(--cyan);margin-top:6px}.topright{display:flex;align-items:center;gap:22px;font:10px 'DM Mono',monospace;letter-spacing:.13em;color:#d8e8e8}.live{display:flex;gap:8px;align-items:center}.dot{width:7px;height:7px;border-radius:50%;background:var(--lime);box-shadow:0 0 12px var(--lime)}.topright .divider{height:18px;width:1px;background:#ffffff40}.intro{position:absolute;left:6%;top:70px;width:min(510px,52vw);transform:scale(.82);transform-origin:top left;transition:opacity .45s,transform .45s;pointer-events:auto}.intro h1{margin-top:15px;margin-bottom:10px}.intro .subtitle{margin-bottom:12px}.intro .rule{margin:12px 0}.intro .mode{min-height:60px}.intro .plane{padding-top:6px;padding-bottom:6px}.intro .actionrow{margin-top:12px}.eyebrow{font:11px 'DM Mono',monospace;letter-spacing:.22em;color:var(--lime);display:flex;align-items:center;gap:11px}.eyebrow:before{content:'';width:26px;height:1px;background:var(--lime)}h1{font-weight:700;font-size:clamp(77px,9.3vw,144px);line-height:.77;letter-spacing:-.037em;margin:27px 0 21px;text-transform:uppercase;text-shadow:0 8px 35px #07151c77}h1 span{color:var(--lime)}.subtitle{font-size:18px;letter-spacing:.105em;font-weight:500;line-height:1.35;margin-bottom:28px;color:#e7f1eb}.desc{max-width:425px;font-size:15px;line-height:1.52;letter-spacing:.025em;color:#c4d2d2;font-family:Arial,sans-serif;font-weight:400}.rule{height:1px;background:linear-gradient(90deg,#c9eddf70,transparent);margin:24px 0}.sectionlabel{font:10px 'DM Mono',monospace;color:var(--cyan);letter-spacing:.2em;margin-bottom:12px}.modegrid{display:flex;gap:9px}.mode{flex:1;min-height:75px;text-align:left;border:1px solid #bfdbdc50;color:#eaf1e9;background:#102530b8;padding:12px 13px;cursor:pointer;transition:.2s;font-family:inherit}.mode:hover,.plane:hover{border-color:var(--lime);background:#1b3741e8}.mode.active{background:#d8fa9c;color:#12252a;border-color:#d8fa9c}.mode .num{font:9px 'DM Mono',monospace;opacity:.65;display:block;margin-bottom:5px}.mode strong{font-size:18px;letter-spacing:.07em;font-weight:700}.fleet{display:flex;gap:8px}.plane{flex:1;min-width:0;text-align:left;border:1px solid #bfdbdc50;background:#102530b8;color:white;padding:10px 10px 9px;cursor:pointer;font-family:inherit;transition:.2s}.plane.active{border-color:var(--lime);box-shadow:inset 0 0 0 1px var(--lime);background:#243d40}.plane .pno{display:block;color:var(--lime);font:9px 'DM Mono',monospace;margin-bottom:6px}.plane strong{display:block;font-size:17px;letter-spacing:.035em;white-space:nowrap}.plane .type{display:block;color:#a7baba;font:9px 'DM Mono',monospace;margin-top:5px;white-space:nowrap}.actionrow{display:flex;align-items:center;gap:19px;margin-top:23px}#launch{height:53px;border:0;background:var(--lime);color:#10282d;padding:0 23px;min-width:190px;display:flex;align-items:center;justify-content:space-between;font:700 19px 'Barlow Condensed',sans-serif;letter-spacing:.1em;cursor:pointer;transition:transform .2s,background .2s}#launch:hover{transform:translateY(-3px);background:white}#launch span{font:23px Arial}.actionrow>span{font:10px/1.5 'DM Mono',monospace;letter-spacing:.055em;color:#b5c9c7}.sideinfo{position:absolute;right:5%;top:22%;width:210px;text-align:right;color:#e9f4eb;transition:opacity .4s}.sideinfo .line{height:1px;background:#dfecdf78;margin:12px 0 14px}.sideinfo .tag{font:10px 'DM Mono',monospace;letter-spacing:.16em;color:var(--lime)}.sideinfo .big{font-size:56px;line-height:1;font-weight:600;margin-top:10px}.sideinfo .unit{font:10px 'DM Mono',monospace;color:#c2d5d6;letter-spacing:.1em}.sideinfo .detail{font:11px/1.8 'DM Mono',monospace;color:#cad9d5;letter-spacing:.04em}.bottom{position:absolute;bottom:0;left:0;right:0;min-height:48px;border-top:1px solid #e4f6e530;background:#07151ab0;display:flex;align-items:center;justify-content:space-between;padding:8px 46px;color:#b8cdcd;font:10px 'DM Mono',monospace;letter-spacing:.09em}.bottom b{color:var(--lime);font-weight:400}.hud{opacity:0;visibility:hidden;transition:opacity .5s;position:absolute;inset:0}.playing .hud{opacity:1;visibility:visible}.playing .intro,.playing .sideinfo{opacity:0;transform:translateY(15px);pointer-events:none}.playing #shade{opacity:.35}.hudTop{position:absolute;top:89px;left:46px;right:46px;display:flex;justify-content:space-between;align-items:flex-start}.missionChip{border-left:2px solid var(--lime);padding-left:13px;text-shadow:0 1px 5px #06121e}.missionChip .tiny{font:10px 'DM Mono',monospace;color:var(--lime);letter-spacing:.17em}.missionChip strong{display:block;font-size:24px;letter-spacing:.08em;margin:3px 0}.missionChip span{font:11px 'DM Mono',monospace;color:#d4e3dd}.flightStats{display:flex;gap:8px}.stat{min-width:105px;background:#071b21ad;border:1px solid #bce8d449;padding:9px 13px;backdrop-filter:blur(4px)}.stat label{display:block;color:#b6d4cf;font:9px 'DM Mono',monospace;letter-spacing:.13em}.stat strong{font:500 30px 'Barlow Condensed',sans-serif;line-height:1.1}.stat em{font:9px 'DM Mono',monospace;color:var(--lime);font-style:normal;margin-left:4px}.crosshair{position:absolute;left:50%;top:50%;width:56px;height:56px;transform:translate(-50%,-50%);opacity:.75}.crosshair:before,.crosshair:after{content:'';position:absolute;background:var(--lime);box-shadow:0 0 5px #071921}.crosshair:before{height:1px;width:22px;left:17px;top:27px}.crosshair:after{height:22px;width:1px;left:27px;top:17px}.crosshair i{position:absolute;inset:0;border:1px solid #d8fa9c95;border-radius:50%;transform:scale(.48)}.horizon{position:absolute;top:50%;left:50%;width:280px;height:1px;transform:translate(-50%,40px);display:flex;justify-content:space-between}.horizon:before,.horizon:after{content:'';width:75px;border-top:1px solid #d8fa9ca0}.hudBottom{position:absolute;bottom:70px;left:46px;right:46px;display:flex;justify-content:space-between;align-items:flex-end}.readout{min-width:180px;border-left:1px solid #d8fa9c8a;padding-left:13px;text-shadow:0 1px 5px #06121e}.readout .label{color:var(--lime);font:10px 'DM Mono',monospace;letter-spacing:.17em}.readout strong{font:500 31px 'Barlow Condensed',sans-serif}.readout small{font:10px 'DM Mono',monospace;color:#daebe3}.throttleBox{text-align:right}.throttleBar{height:6px;width:180px;border:1px solid #c1e7d0aa;background:#091c1c;display:inline-block;vertical-align:middle;margin-top:8px}.throttleBar div{height:100%;background:var(--lime);width:24%}.status{position:absolute;left:50%;bottom:103px;transform:translateX(-50%);padding:8px 16px;background:#0d2428bb;color:var(--lime);border:1px solid #d8fa9c88;font:11px 'DM Mono',monospace;letter-spacing:.09em;text-align:center;white-space:nowrap}.pausepanel{position:absolute;inset:0;background:#07171cc9;display:none;align-items:center;justify-content:center;pointer-events:auto}.paused .pausepanel{display:flex}.pausecard{width:350px;background:#142a30;border:1px solid #d8fa9c80;padding:27px}.pausecard h2{font-size:49px;line-height:1;margin:5px 0 12px}.pausecard p{font:12px/1.8 'DM Mono',monospace;color:#c0d6d4}.pausecard button{width:100%;height:42px;margin-top:8px;border:1px solid var(--lime);background:var(--lime);color:#14282a;font:700 17px 'Barlow Condensed',sans-serif;letter-spacing:.1em;cursor:pointer}.pausecard button.secondary{background:transparent;color:var(--lime)}.warn{color:#ffbc91!important}@media(max-width:850px){.topbar{padding:0 20px}.topright .extra{display:none}.intro{left:5%;top:13%;width:70vw}.sideinfo{display:none}h1{font-size:clamp(75px,13vw,120px)}.bottom{padding:9px 20px;font-size:8px}.bottom span:last-child{display:none}.hudTop{left:20px;right:20px}.hudBottom{left:20px;right:20px}.stat{min-width:75px;padding:7px}.stat strong{font-size:23px}}@media(max-width:560px){.intro{width:90vw;top:12%}.subtitle{margin-bottom:10px}.desc{font-size:12px}.rule{margin:12px 0}.mode{min-height:58px;padding:6px}.mode strong{font-size:15px}.plane{padding:7px}.plane strong{font-size:14px}.plane .type{font-size:7px}.actionrow{margin-top:14px}.topbar{height:56px}.bottom{min-height:35px}.flightStats{gap:3px}.stat{min-width:60px;padding:5px}.stat strong{font-size:19px}.stat label,.stat em{font-size:7px}.missionChip strong{font-size:16px}.hudTop{top:65px}.hudBottom{bottom:48px}.readout strong{font-size:24px}.readout{min-width:105px}.throttleBar{width:95px}}
</style></head><body><canvas id="world"></canvas><div id="shade"></div><div id="grain"></div><div id="app"><header class="topbar"><div class="brand"><svg viewBox="0 0 36 36"><path d="M18 2 34 29l-16-7L2 29 18 2Zm0 8-7 13 7-4 7 4-7-13Z"/></svg><div>APEX AERO<small>FLIGHT SIMULATOR / 01</small></div></div><div class="topright"><span class="live"><i class="dot"></i> SYSTEMS ONLINE</span><span class="divider extra"></span><span class="extra">SIMULATION ENVIRONMENT // ALPINE COAST</span></div></header><section class="intro"><div class="eyebrow">THE SKY IS NOT A LIMIT</div><h1>TAKE<br><span>FLIGHT.</span></h1><div class="subtitle">A PRECISION FLIGHT EXPERIENCE</div><div class="desc">Feel every knot of airspeed. Read the wind, respect the stall, and earn your place above the clouds.</div><div class="rule"></div><div class="sectionlabel">01 / SELECT MISSION</div><div class="modegrid"><button class="mode active" data-mode="takeoff"><span class="num">01 — PRECISION</span><strong>TAKEOFF & LANDING ↗</strong></button><button class="mode" data-mode="dogfight"><span class="num">02 — COMBAT</span><strong>DOGFIGHT ↗</strong></button></div><div class="sectionlabel" style="margin-top:20px">02 / CHOOSE YOUR AIRCRAFT</div><div class="fleet"><button class="plane active" data-plane="0"><span class="pno">// 01</span><strong>KESTREL T-4</strong><span class="type">LIGHT TRAINER</span></button><button class="plane" data-plane="1"><span class="pno">// 02</span><strong>FALCON F-9</strong><span class="type">INTERCEPTOR</span></button><button class="plane" data-plane="2"><span class="pno">// 03</span><strong>ATLAS A-12</strong><span class="type">HEAVY STRIKE</span></button></div><div class="actionrow"><button id="launch">START FLIGHT <span>↗</span></button><span>W / S THROTTLE<br>ARROWS FLY · A / D RUDDER</span></div></section><aside class="sideinfo"><div class="tag">LIVE CONDITIONS / 06:42 UTC</div><div class="big">18<span style="font-size:25px;vertical-align:top">°</span></div><div class="unit">CLEAR SKIES · NW 08 KTS</div><div class="line"></div><div class="detail">REGION // ALPINE COAST<br>FIELD ELEV // 012 M<br>VISIBILITY // 25 KM<br>RUNWAY // 27 / 09</div></aside><div class="hud"><div class="hudTop"><div class="missionChip"><div class="tiny">MISSION ACTIVE // <span id="missionCode">01</span></div><strong id="missionName">PRECISION TAKEOFF</strong><span id="objective">Accelerate, rotate and climb above 300 m</span></div><div class="flightStats"><div class="stat"><label>AIRSPEED</label><strong id="speedVal">000</strong><em>KT</em></div><div class="stat"><label>ALTITUDE</label><strong id="altVal">000</strong><em>M</em></div><div class="stat"><label>VERT SPEED</label><strong id="vsVal">+0</strong><em>M/S</em></div></div></div><div class="crosshair"><i></i></div><div class="horizon"></div><div class="status" id="status">THROTTLE UP · HOLD ↑ TO ROTATE</div><div class="hudBottom"><div class="readout"><div class="label">ATTITUDE / FLIGHT</div><strong id="attitudeVal">+00° / 00°</strong><br><small id="flightState">ON GROUND · FLAPS UP</small></div><div class="readout throttleBox"><div class="label">ENGINE / THRUST</div><strong id="rpmVal">24%</strong><br><small>THROTTLE <span id="throttleVal">24%</span> · <span id="gVal">1.0 G</span></small><br><div class="throttleBar"><div id="throttleFill"></div></div></div></div></div><div class="pausepanel"><div class="pausecard"><div class="eyebrow">SIMULATION PAUSED</div><h2>HOLD POSITION.</h2><p>ARROWS — PITCH / ROLL<br>A / D — YAW &nbsp; W / S — THROTTLE<br>SPACE — WHEEL BRAKES<br>F OR CLICK — FIRE (DOGFIGHT)<br>V — CAMERA &nbsp; M — AUDIO &nbsp; ESC — PAUSE</p><button id="resume">RESUME FLIGHT ↗</button><button class="secondary" id="hangar">RETURN TO HANGAR</button></div></div><footer class="bottom"><span><b>●</b> APEX AERO // PHYSICS-DRIVEN FLIGHT</span><span id="footerHint">SELECT YOUR AIRCRAFT & BEGIN</span><span>V 01.04 &nbsp; / &nbsp; BUILT FOR THE SKY</span></footer></div><script>
const canvas=document.getElementById('world'),ctx=canvas.getContext('2d');let W=innerWidth,H=innerHeight,dpr=Math.min(devicePixelRatio||1,2);function size(){W=innerWidth;H=innerHeight;dpr=Math.min(devicePixelRatio||1,2);canvas.width=W*dpr;canvas.height=H*dpr;ctx.setTransform(dpr,0,0,dpr,0,0);if(renderer){renderer.setSize(W,H);camera.aspect=W/H;camera.updateProjectionMatrix()}}addEventListener('resize',size);
const fleet=[{name:'KESTREL T-4',mass:1200,area:19,thrust:3900,drag:.033,induced:.047,response:1.8,span:12,stall:23,max:105,color:0xd9e8db,accent:0xd8fa9c},{name:'FALCON F-9',mass:7500,area:28,thrust:68000,drag:.024,induced:.05,response:3.2,span:11,stall:55,max:340,color:0xb0c3c2,accent:0xf8ac75},{name:'ATLAS A-12',mass:15000,area:58,thrust:89000,drag:.041,induced:.058,response:1.15,span:19,stall:52,max:255,color:0x8faaaa,accent:0xe3d092}];let selected=0,mode='takeoff',playing=false,paused=false,keys={},pointer={active:false,x:0,y:0},time=0,elapsed=0,shots=0,hits=0,lastShot=0,landed=false,wasAirborne=false,message='',messageUntil=0,view=0,muted=false;let plane,enemy;const clamp=(v,a,b)=>Math.max(a,Math.min(b,v)),lerp=(a,b,t)=>a+(b-a)*t,rad=Math.PI/180;const V=(x=0,y=0,z=0)=>({x,y,z}),add=(a,b)=>V(a.x+b.x,a.y+b.y,a.z+b.z),sub=(a,b)=>V(a.x-b.x,a.y-b.y,a.z-b.z),mul=(a,k)=>V(a.x*k,a.y*k,a.z*k),dot=(a,b)=>a.x*b.x+a.y*b.y+a.z*b.z,cross=(a,b)=>V(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x),len=a=>Math.hypot(a.x,a.y,a.z),norm=a=>mul(a,1/(len(a)||1));function basis(p){let cy=Math.cos(p.yaw),sy=Math.sin(p.yaw),cp=Math.cos(p.pitch),sp=Math.sin(p.pitch),cr=Math.cos(p.roll),sr=Math.sin(p.roll);let f=V(sy*cp,sp,-cy*cp),r=V(cy,0,sy),u=cross(r,f);return {f,r:add(mul(r,cr),mul(u,-sr)),u:add(mul(u,cr),mul(r,sr))}}
function noise(x,z){return Math.sin(x*.0013+Math.sin(z*.0011)*1.4)*Math.cos(z*.0017)*.5+Math.sin(x*.0032+z*.0021)*Math.sin(z*.0029-x*.0009)*.24+Math.sin(x*.0071-z*.004)*.09}function ground(x,z){let distX=Math.abs(x),distZ=Math.max(0,z-620,-2300-z);let flatten=clamp((distX-190)/470,0,1)*clamp((distZ+680)/680,0,1);let h=(noise(x,z)*260+Math.pow(Math.max(0,Math.sin(x*.00063+z*.00031)+.28),2)*460+65)*flatten;let coast=clamp((x-1800)/1250,0,1);return h*(1-coast)-coast*35}function density(y){return 1.225*Math.exp(-Math.max(0,y)/8500)}function reset(){let a=fleet[selected];plane={pos:mode==='takeoff'?V(0,2.6,460):V(-240,820,1500),vel:mode==='takeoff'?V(0,0,0):V(0,1,-a.stall*2.7),pitch:mode==='takeoff'?0:.025,roll:0,yaw:0,pr:0,rr:0,yr:0,throttle:mode==='takeoff'?.24:.78,rpm:mode==='takeoff'?.24:.78,onGround:mode==='takeoff',aoa:0,g:1,stall:false};enemy={pos:V(0,880,-650),angle:0,health:100};elapsed=0;shots=0;hits=0;wasAirborne=false;landed=false;message='';messageUntil=0;view=0}
function setMessage(s,d=3){message=s;messageUntil=elapsed+d}function update(dt){if(!playing||paused)return;dt=Math.min(dt,.04);elapsed+=dt;time+=dt;let a=fleet[selected],p=plane;let pitchInput=(keys.ArrowUp?1:0)-(keys.ArrowDown?1:0),rollInput=(keys.ArrowRight?1:0)-(keys.ArrowLeft?1:0),yawInput=(keys.KeyD?1:0)-(keys.KeyA?1:0);if(pointer.active){pitchInput+=clamp((H*.5-pointer.y)/(H*.36),-1,1);rollInput+=clamp((pointer.x-W*.5)/(W*.35),-1,1)}p.throttle=clamp(p.throttle+((keys.KeyW?1:0)-(keys.KeyS?1:0))*dt*.37,0,1);p.rpm+= (p.throttle-p.rpm)*Math.min(1,dt*(a.name==='ATLAS A-12'?.75:1.5));let b=basis(p),speed=len(p.vel),forwardSpeed=dot(p.vel,b.f),q=.5*density(p.pos.y)*speed*speed;let control=clamp(q/1700,.12,1.35),authority=p.onGround?.42:control;p.pr+=(pitchInput*.53*a.response*authority-p.pr*(p.onGround?3.5:1.8))*dt;p.rr+=(rollInput*.75*a.response*authority-p.rr*2.4)*dt;p.yr+=(yawInput*.36*a.response*authority-p.yr*2.1)*dt;p.pitch=clamp(p.pitch+p.pr*dt,-1.35,1.35);p.roll=clamp(p.roll+p.rr*dt,-2.8,2.8);p.yaw+= (p.yr+Math.sin(p.roll)*Math.max(0,speed)*.0094/(1+Math.abs(p.roll)*.4))*dt; b=basis(p);let vdir=norm(speed>1?p.vel:b.f),aoa=Math.atan2(-dot(p.vel,b.u),Math.max(1,dot(p.vel,b.f)));p.aoa=aoa;let stallAngle=(a.name==='KESTREL T-4'?17:20)*rad,absAoA=Math.abs(aoa);let CL=clamp(.22+4.6*aoa,-1.2,1.65);if(absAoA>stallAngle)CL*=clamp(1-(absAoA-stallAngle)*1.35,.25,1);p.stall=!p.onGround&&speed<a.stall*.93&&absAoA>stallAngle*.5;let liftDir=norm(sub(b.u,mul(vdir,dot(b.u,vdir))));let lift=q*a.area*CL;let drag=q*a.area*(a.drag+a.induced*CL*CL);let thrust=a.thrust*p.rpm*(.75+.25*Math.sqrt(density(p.pos.y)/1.225));let force=add(add(mul(b.f,thrust),mul(liftDir,lift)),add(mul(vdir,-drag),V(0,-a.mass*9.81,0)));if(p.onGround){let h=ground(p.pos.x,p.pos.z)+2.6;p.pos.y=h;p.vel.y=0;let normal=Math.max(0,a.mass*9.81-lift);let friction=(keys.Space?1.15:.024)*normal;let horizontal=V(p.vel.x,0,p.vel.z),hs=len(horizontal);force=add(force,mul(norm(horizontal),-Math.min(friction,hs*a.mass/dt)));force.y=0;if(lift>a.mass*9.81*.96&&forwardSpeed>a.stall*.85&&p.pitch>.025){p.onGround=false;p.vel.y=Math.max(1,p.vel.y);setMessage('AIRBORNE · POSITIVE CLIMB',3)}}p.vel=add(p.vel,mul(force,dt/a.mass));p.pos=add(p.pos,mul(p.vel,dt));let terrain=ground(p.pos.x,p.pos.z)+2.6;if(!p.onGround&&p.pos.y<=terrain){let impact=-p.vel.y;p.pos.y=terrain;if(impact>7||Math.abs(p.roll)>.55||Math.abs(p.pitch)>.4){setMessage('HARD LANDING · AIRFRAME DAMAGED',6);p.vel=mul(p.vel,.48)}else if(wasAirborne&&mode==='takeoff'&&Math.abs(p.pos.x)<48&&p.pos.z<640&&p.pos.z>-2400&&len(p.vel)<a.stall*1.8){landed=true;setMessage('PRECISION LANDING COMPLETE ✓',12)}p.vel.y=0;p.onGround=true}if(!p.onGround)wasAirborne=true;p.g=clamp(lift/(a.mass*9.81),0,9);if(mode==='dogfight'){enemy.angle+=dt*.19;enemy.pos.x=570*Math.sin(enemy.angle)+150;enemy.pos.z=-820+530*Math.cos(enemy.angle*.84);enemy.pos.y=820+115*Math.sin(enemy.angle*1.7);if(keys.KeyF||keys.MouseFire)fire()}audioUpdate();updateHud()}
function fire(){if(elapsed-lastShot<.18||mode!=='dogfight')return;lastShot=elapsed;shots++;let b=basis(plane),toward=sub(enemy.pos,plane.pos),distance=len(toward),alignment=dot(norm(toward),b.f);if(distance<1900&&alignment>.987){hits++;enemy.health-=18;setMessage(enemy.health<=0?'TARGET NEUTRALIZED · MISSION COMPLETE ✓':'TARGET HIT · '+Math.max(0,enemy.health)+'% HULL',2);if(enemy.health<=0){enemy.health=100;enemy.angle+=2.2}}else setMessage('ROUNDS AWAY',.4);soundShot()}
function updateHud(){let p=plane;document.getElementById('speedVal').textContent=String(Math.round(len(p.vel)*1.94384)).padStart(3,'0');document.getElementById('altVal').textContent=String(Math.round(Math.max(0,p.pos.y-ground(p.pos.x,p.pos.z)))).padStart(3,'0');document.getElementById('vsVal').textContent=(p.vel.y>=0?'+':'')+p.vel.y.toFixed(1);document.getElementById('attitudeVal').textContent=(p.pitch>=0?'+':'')+Math.round(p.pitch/rad)+'° / '+Math.abs(Math.round(p.roll/rad))+'°';document.getElementById('rpmVal').textContent=Math.round(p.rpm*100)+'%';document.getElementById('throttleVal').textContent=Math.round(p.throttle*100)+'%';document.getElementById('throttleFill').style.width=(p.throttle*100)+'%';document.getElementById('gVal').textContent=p.g.toFixed(1)+' G';document.getElementById('flightState').textContent=p.onGround?'ON GROUND · '+(keys.Space?'BRAKES ON':'GEAR DOWN'):p.stall?'STALL WARNING · NOSE DOWN':'AIRBORNE · GEAR DOWN';document.getElementById('flightState').classList.toggle('warn',p.stall);let status=messageUntil>elapsed?message:mode==='dogfight'?'ACQUIRE TARGET · F OR CLICK TO FIRE':p.stall?'STALL · LOWER NOSE / INCREASE THRUST':landed?'LANDING COMPLETE':p.onGround?'THROTTLE UP · HOLD ↑ TO ROTATE':!wasAirborne?'CLIMB TO 300 M':'MAINTAIN AIRSPEED · RETURN TO RUNWAY';document.getElementById('status').textContent=status;document.getElementById('status').classList.toggle('warn',p.stall||status.includes('HARD'))}
let audioCtx,engineOsc,engineGain,windNode,windGain;function initAudio(){if(audioCtx){audioCtx.resume();return}try{audioCtx=new (window.AudioContext||window.webkitAudioContext)();engineOsc=audioCtx.createOscillator();engineOsc.type='sawtooth';let filter=audioCtx.createBiquadFilter();filter.type='lowpass';filter.frequency.value=220;engineGain=audioCtx.createGain();engineGain.gain.value=0;engineOsc.connect(filter).connect(engineGain).connect(audioCtx.destination);engineOsc.start();let buffer=audioCtx.createBuffer(1,audioCtx.sampleRate*2,audioCtx.sampleRate),data=buffer.getChannelData(0);for(let i=0;i<data.length;i++)data[i]=Math.random()*2-1;windNode=audioCtx.createBufferSource();windNode.buffer=buffer;windNode.loop=true;let windFilter=audioCtx.createBiquadFilter();windFilter.type='bandpass';windFilter.frequency.value=540;windFilter.Q.value=.4;windGain=audioCtx.createGain();windGain.gain.value=0;windNode.connect(windFilter).connect(windGain).connect(audioCtx.destination);windNode.start()}catch(e){}}function audioUpdate(){if(!audioCtx)return;let t=audioCtx.currentTime,p=plane;engineOsc.frequency.setTargetAtTime(42+p.rpm*(fleet[selected].name==='KESTREL T-4'?96:139),t,.12);engineGain.gain.setTargetAtTime(muted?0:(.012+p.rpm*.036)*(.8+.2*density(p.pos.y)/1.225),t,.12);windGain.gain.setTargetAtTime(muted?0:clamp(len(p.vel)/240,0,.075)+clamp(Math.abs(p.aoa),0,.4)*.04,t,.2)}function soundShot(){if(!audioCtx||muted)return;let o=audioCtx.createOscillator(),g=audioCtx.createGain();o.type='square';o.frequency.setValueAtTime(95,audioCtx.currentTime);o.frequency.exponentialRampToValueAtTime(35,audioCtx.currentTime+.12);g.gain.setValueAtTime(.08,audioCtx.currentTime);g.gain.exponentialRampToValueAtTime(.001,audioCtx.currentTime+.14);o.connect(g).connect(audioCtx.destination);o.start();o.stop(audioCtx.currentTime+.15)}
// Offline-safe perspective renderer: Three.js takes over this canvas when the library is available.
let camPos,camF,camR,camU;function setCamera(){let p=plane,b=basis(p),chase=view===0?add(add(p.pos,mul(b.f,-36)),V(0,13,0)):add(add(p.pos,mul(b.f,7)),V(0,3.1,0));let look=view===0?add(add(p.pos,mul(b.f,180)),V(0,10,0)):add(p.pos,mul(b.f,200));camPos=chase;camF=norm(sub(look,chase));camR=norm(cross(camF,V(0,1,0)));camU=norm(cross(camR,camF))}function proj(v){let d=sub(v,camPos),z=dot(d,camF);if(z<.5)return null;let scale=Math.min(W,H)*.91/z;return {x:W*.5+dot(d,camR)*scale,y:H*.5-dot(d,camU)*scale,z}}function poly3(points,fill,stroke){let ps=points.map(proj);if(ps.some(x=>!x))return;ctx.beginPath();ctx.moveTo(ps[0].x,ps[0].y);for(let i=1;i<ps.length;i++)ctx.lineTo(ps[i].x,ps[i].y);ctx.closePath();ctx.fillStyle=fill;ctx.fill();if(stroke){ctx.strokeStyle=stroke;ctx.lineWidth=.65;ctx.stroke()}}function line3(a,b,color,width=1){let x=proj(a),y=proj(b);if(!x||!y)return;ctx.beginPath();ctx.moveTo(x.x,x.y);ctx.lineTo(y.x,y.y);ctx.strokeStyle=color;ctx.lineWidth=width;ctx.stroke()}
function renderFallback(){let sky=ctx.createLinearGradient(0,0,0,H);sky.addColorStop(0,'#729baf');sky.addColorStop(.48,'#a9c9d1');sky.addColorStop(.72,'#e6d8bd');sky.addColorStop(1,'#9aac9e');ctx.fillStyle=sky;ctx.fillRect(0,0,W,H);setCamera();let sun=proj(V(-3400,2600,-7200));if(sun){let grad=ctx.createRadialGradient(sun.x,sun.y,3,sun.x,sun.y,Math.min(W,H)*.32);grad.addColorStop(0,'#fff9dbb0');grad.addColorStop(.1,'#fff4d069');grad.addColorStop(1,'#fff0c000');ctx.fillStyle=grad;ctx.fillRect(0,0,W,H)}let p=plane;let cx=Math.round(p.pos.x/180)*180,cz=Math.round(p.pos.z/180)*180,tiles=[];let range=14,step=180;for(let i=-range;i<range;i++)for(let j=-range;j<range;j++){let x=cx+i*step,z=cz+j*step,h1=ground(x,z),h2=ground(x+step,z),h3=ground(x+step,z+step),h4=ground(x,z+step);let mx=x+step*.5,mz=z+step*.5,dist=Math.hypot(mx-camPos.x,mz-camPos.z);if(dist>4100)continue;tiles.push({dist,pts:[V(x,h1,z),V(x+step,h2,z),V(x+step,h3,z+step),V(x,h4,z+step)],h:(h1+h2+h3+h4)/4,x,z})}tiles.sort((a,b)=>b.dist-a.dist);for(let t of tiles){let shade=Math.sin(t.x*.003+t.z*.007)*.5+.5,elev=clamp(t.h/650,0,1),fade=clamp((t.dist-1900)/2600,0,.58),r=lerp(53+shade*19,140,elev),g=lerp(93+shade*17,147,elev),bl=lerp(87+shade*13,137,elev);if(t.h<0){r=67;g=121;bl=137}r=lerp(r,173,fade);g=lerp(g,194,fade);bl=lerp(bl,191,fade);poly3(t.pts,`rgb(${r|0},${g|0},${bl|0})`)}// runway markings
let runwayY=ground(0,0)+.8;poly3([V(-42,runwayY,650),V(42,runwayY,650),V(42,runwayY,-2300),V(-42,runwayY,-2300)],'#414b4a','#c3d4c6');for(let z=610;z>-2250;z-=145){poly3([V(-1.2,runwayY+.1,z),V(1.2,runwayY+.1,z),V(1.2,runwayY+.1,z-70),V(-1.2,runwayY+.1,z-70)],'#d5d7bf')}for(let x of [-36,36])line3(V(x,runwayY+1,645),V(x,runwayY+1,-2280),'#e8e2c9',1.3);for(let z of [530,-2170])for(let x=-24;x<30;x+=10)poly3([V(x,runwayY+1,z),V(x+4,runwayY+1,z),V(x+4,runwayY+1,z-24),V(x,runwayY+1,z-24)],'#dfddd2');for(let i=0;i<23;i++){let x=Math.sin(i*18.37)*2100,z=-i*240+500;if(Math.abs(x)<220)x+=x>0?290:-290;let h=ground(x,z);let v=proj(V(x,h+35,z));if(v&&v.z<2800){ctx.globalAlpha=clamp((2800-v.z)/2500,0,.6);ctx.fillStyle='#263f38';ctx.beginPath();ctx.moveTo(v.x,v.y);ctx.lineTo(v.x-1000/v.z*32,v.y+1000/v.z*42);ctx.lineTo(v.x+1000/v.z*32,v.y+1000/v.z*42);ctx.fill()}}ctx.globalAlpha=1;
if(mode==='dogfight'){let target=proj(enemy.pos);if(target){let s=clamp(1250/target.z,10,53);ctx.strokeStyle='#ffbd8d';ctx.lineWidth=2;ctx.strokeRect(target.x-s/2,target.y-s/2,s,s);ctx.fillStyle='#ffdfb3';ctx.font='11px DM Mono,monospace';ctx.fillText('HOSTILE  '+Math.round(target.z)+' M',target.x+s/2+9,target.y-4);ctx.beginPath();ctx.ellipse(target.x,target.y,s*.6,s*.16,-.15,0,Math.PI*2);ctx.fillStyle='#263b3e';ctx.fill()}}if(view===0)drawPlane2D();else{let b=basis(p);line3(add(p.pos,mul(b.f,7)),add(p.pos,mul(b.f,60)),'#e9ffcf75',1)}let fog=ctx.createLinearGradient(0,0,0,H);fog.addColorStop(0,'#adcfdf06');fog.addColorStop(.8,'#edf3db00');fog.addColorStop(1,'#30423846');ctx.fillStyle=fog;ctx.fillRect(0,0,W,H)}
function drawPlane2D(){let p=plane,a=fleet[selected],b=basis(p),s=a.span/12;let point=(x,y,z)=>add(p.pos,add(add(mul(b.r,x*s),mul(b.u,y*s)),mul(b.f,z*s)));let col=a.name==='KESTREL T-4'?'#d9e6d8':a.name==='FALCON F-9'?'#aebfbe':'#9caba8',dark='#58706e',accent=a.name==='FALCON F-9'?'#edaa7f':'#d9ef9c';let faces=[{pts:[point(-1,0,-6),point(1,0,-6),point(1,0,9),point(-1,0,9)],c:col},{pts:[point(-a.span*.48,0,1),point(-1,0,-2),point(1,0,-2),point(a.span*.48,0,1),point(1.4,0,3),point(-1.4,0,3)],c:col},{pts:[point(-2.4,.05,6),point(2.4,.05,6),point(.8,.05,8),point(-.8,.05,8)],c:dark},{pts:[point(0,0,6),point(0,2.5,7),point(0,0,8)],c:accent},{pts:[point(-.7,.55,-1),point(.7,.55,-1),point(.65,.5,-3),point(-.65,.5,-3)],c:'#344e59'}];for(let f of faces)poly3(f.pts,f.c,'#283b3a');line3(point(-a.span*.48,0,1),point(-a.span*.48,0,2),accent,3);line3(point(a.span*.48,0,1),point(a.span*.48,0,2),accent,3)}
let renderer=null,scene=null,camera=null,airMesh=null,terrainMesh=null,enemyMesh=null,THREE=null;async function tryThree(){try{let T=await import('https://cdn.jsdelivr.net/npm/three@0.160.1/build/three.module.js');THREE=T;initThree()}catch(e){console.info('Offline renderer active. Three.js unavailable from CDN.')}}function initThree(){try{let T=THREE;renderer=new T.WebGLRenderer({antialias:true,alpha:false});renderer.setPixelRatio(Math.min(devicePixelRatio,1.7));renderer.setSize(W,H);renderer.toneMapping=T.ACESFilmicToneMapping;renderer.toneMappingExposure=1.05;renderer.outputColorSpace=T.SRGBColorSpace;renderer.domElement.style.cssText='position:fixed;inset:0;width:100%;height:100%;z-index:0';canvas.style.display='none';document.body.insertBefore(renderer.domElement,canvas);renderer.domElement.addEventListener('pointerdown',e=>{if(playing&&!paused){pointer.active=true;pointer.x=e.clientX;pointer.y=e.clientY;if(mode==='dogfight')fire()}});renderer.domElement.addEventListener('pointermove',e=>{pointer.x=e.clientX;pointer.y=e.clientY});renderer.domElement.addEventListener('pointerup',()=>pointer.active=false);scene=new T.Scene();scene.background=new T.Color(0x9cbdc9);scene.fog=new T.FogExp2(0xaac8c8,.00027);camera=new T.PerspectiveCamera(70,W/H,.5,12500);scene.add(new T.HemisphereLight(0xdceeff,0x607452,2.15));let sun=new T.DirectionalLight(0xffe9c2,3.1);sun.position.set(-1400,2200,-3000);scene.add(sun);let verts=[],cols=[],indices=[],N=148,step=130;let geo=new T.BufferGeometry();for(let j=0;j<=N;j++)for(let i=0;i<=N;i++){verts.push(0,0,0);cols.push(0,0,0)}for(let j=0;j<N;j++)for(let i=0;i<N;i++){let k=j*(N+1)+i;indices.push(k,k+N+1,k+1,k+1,k+N+1,k+N+2)}geo.setAttribute('position',new T.Float32BufferAttribute(verts,3));geo.setAttribute('color',new T.Float32BufferAttribute(cols,3));geo.setIndex(indices);geo.computeVertexNormals();terrainMesh=new T.Mesh(geo,new T.MeshStandardMaterial({vertexColors:true,roughness:1,side:T.DoubleSide}));scene.add(terrainMesh);let runway=new T.Mesh(new T.PlaneGeometry(84,2950),new T.MeshStandardMaterial({color:0x424b4b,roughness:.96}));runway.rotation.x=-Math.PI/2;runway.position.set(0,.55,-825);scene.add(runway);for(let z=590;z>-2240;z-=140){let m=new T.Mesh(new T.PlaneGeometry(2.3,70),new T.MeshBasicMaterial({color:0xe1dfc5}));m.rotation.x=-Math.PI/2;m.position.set(0,.67,z-35);scene.add(m)}for(let x of [-37,37]){let m=new T.Mesh(new T.PlaneGeometry(1.2,2900),new T.MeshBasicMaterial({color:0xe3dec7}));m.rotation.x=-Math.PI/2;m.position.set(x,.68,-825);scene.add(m)}airMesh=new T.Group();scene.add(airMesh);enemyMesh=new T.Group();scene.add(enemyMesh);buildThreePlane(airMesh,selected);buildThreePlane(enemyMesh,1);size();updateTerrainThree()}catch(e){console.warn(e);renderer=null;canvas.style.display='block'}}function buildThreePlane(group,index){let T=THREE,a=fleet[index];while(group.children.length)group.remove(group.children[0]);let metal=new T.MeshStandardMaterial({color:a.color,metalness:.58,roughness:.36,side:T.DoubleSide}),trim=new T.MeshStandardMaterial({color:a.accent,metalness:.45,roughness:.42,side:T.DoubleSide}),glass=new T.MeshStandardMaterial({color:0x284858,metalness:.65,roughness:.2});function box(w,h,d,x,y,z,mat=metal){let m=new T.Mesh(new T.BoxGeometry(w,h,d),mat);m.position.set(x,y,z);group.add(m);return m}let scale=a.span/12;group.scale.setScalar(scale);let hull=new T.Mesh(new T.CylinderGeometry(.35,.72,10,9),metal);hull.rotation.x=Math.PI/2;hull.position.z=0;group.add(hull);let nose=new T.Mesh(new T.ConeGeometry(.37,2,9),trim);nose.rotation.x=-Math.PI/2;nose.position.z=-6;group.add(nose);let wing=box(a.span, .16,2.5,0,0,.5);wing.rotation.y=index===1?0:.03;box(a.span*.37,.12,1.1,0,.1,4.2);box(.13,2,1.55,0,1.1,4.3,trim);let canopy=new T.Mesh(new T.SphereGeometry(1,12,8),glass);canopy.scale.set(.62,.48,1.55);canopy.position.set(0,.57,-1.35);group.add(canopy);for(let s of [-1,1]){box(.6,.1,.8,s*a.span*.47,.08,.6,trim);if(index===1)box(.8,.4,2.3,s*.8,-.27,2.5,trim)}if(index===0){let prop=box(3,.08,.08,0,0,-7.1,glass);prop.name='prop'}}function updateTerrainThree(){if(!terrainMesh||!plane)return;let g=terrainMesh.geometry,pos=g.attributes.position,col=g.attributes.color,N=148,step=130,cx=Math.round(plane.pos.x/step)*step,cz=Math.round(plane.pos.z/step)*step;for(let j=0;j<=N;j++)for(let i=0;i<=N;i++){let x=cx+(i-N/2)*step,z=cz+(j-N/2)*step,y=ground(x,z),k=j*(N+1)+i;pos.setXYZ(k,x,y,z);let h=clamp(y/620,0,1),n=noise(x*1.7,z*1.7),coast=y<0;col.setXYZ(k,coast?.19:lerp(.16,.52,h)+n*.025,coast?.37:lerp(.32,.53,h)+n*.025,coast?.44:lerp(.28,.5,h)+n*.025)}pos.needsUpdate=true;col.needsUpdate=true;g.computeVertexNormals()}function renderThree(){if(!renderer||!plane)return;let p=plane,b=basis(p);if(Math.hypot(p.pos.x-(terrainMesh.userData.x||0),p.pos.z-(terrainMesh.userData.z||0))>500){updateTerrainThree();terrainMesh.userData.x=p.pos.x;terrainMesh.userData.z=p.pos.z}airMesh.position.set(p.pos.x,p.pos.y,p.pos.z);let q=new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().makeBasis(new THREE.Vector3(b.r.x,b.r.y,b.r.z),new THREE.Vector3(b.u.x,b.u.y,b.u.z),new THREE.Vector3(-b.f.x,-b.f.y,-b.f.z)));airMesh.quaternion.copy(q);let prop=airMesh.getObjectByName('prop');if(prop)prop.rotation.z+=.6+p.rpm*.7;enemyMesh.visible=mode==='dogfight'&&playing;enemyMesh.position.set(enemy.pos.x,enemy.pos.y,enemy.pos.z);enemyMesh.rotation.y=Math.sin(enemy.angle)*.5;let c=view===0?add(add(p.pos,mul(b.f,-36)),V(0,13,0)):add(add(p.pos,mul(b.f,7)),V(0,3.1,0));let look=view===0?add(add(p.pos,mul(b.f,180)),V(0,10,0)):add(p.pos,mul(b.f,200));camera.position.set(c.x,c.y,c.z);camera.lookAt(look.x,look.y,look.z);renderer.render(scene,camera)}
function frame(t){let dt=(t-(frame.last||t))/1000;frame.last=t;if(!plane)reset();if(!playing){time+=dt*.3;plane.pos=V(0,140,300);plane.yaw=.45+Math.sin(time*.12)*.16;plane.pitch=.035;plane.roll=Math.sin(time*.23)*.035}update(dt);if(renderer)renderThree();else renderFallback();requestAnimationFrame(frame)}size();reset();requestAnimationFrame(frame);tryThree();
document.querySelectorAll('.mode').forEach(el=>el.onclick=()=>{document.querySelectorAll('.mode').forEach(x=>x.classList.remove('active'));el.classList.add('active');mode=el.dataset.mode});document.querySelectorAll('.plane').forEach(el=>el.onclick=()=>{document.querySelectorAll('.plane').forEach(x=>x.classList.remove('active'));el.classList.add('active');selected=+el.dataset.plane;if(airMesh)buildThreePlane(airMesh,selected)});function launch(){reset();playing=true;paused=false;document.getElementById('app').classList.add('playing');document.getElementById('app').classList.remove('paused');document.getElementById('missionCode').textContent=mode==='takeoff'?'01':'02';document.getElementById('missionName').textContent=mode==='takeoff'?'PRECISION FLIGHT':'INTERCEPT & ENGAGE';document.getElementById('objective').textContent=mode==='takeoff'?'Accelerate, rotate, climb and land safely':'Track the hostile aircraft · F or click to fire';document.getElementById('footerHint').textContent='W/S THROTTLE · ARROWS FLY · ESC PAUSE';initAudio();updateHud()}document.getElementById('launch').onclick=launch;document.getElementById('resume').onclick=()=>{paused=false;document.getElementById('app').classList.remove('paused');audioCtx?.resume()};document.getElementById('hangar').onclick=()=>{playing=false;paused=false;keys={};document.getElementById('app').classList.remove('playing','paused');document.getElementById('footerHint').textContent='SELECT YOUR AIRCRAFT & BEGIN';reset()};addEventListener('keydown',e=>{if(['ArrowUp','ArrowDown','ArrowLeft','ArrowRight','Space'].includes(e.code))e.preventDefault();keys[e.code]=true;if(e.repeat)return;if(e.code==='Escape'&&playing){paused=!paused;document.getElementById('app').classList.toggle('paused',paused)}if(e.code==='KeyV')view=1-view;if(e.code==='KeyM')muted=!muted;if(e.code==='KeyR'&&playing)reset()});addEventListener('keyup',e=>keys[e.code]=false);canvas.addEventListener('pointerdown',e=>{if(playing){pointer.active=true;pointer.x=e.clientX;pointer.y=e.clientY;if(mode==='dogfight')fire()}});addEventListener('pointermove',e=>{pointer.x=e.clientX;pointer.y=e.clientY});addEventListener('pointerup',()=>pointer.active=false);addEventListener('blur',()=>{keys={};pointer.active=false});
</script></body></html>
<!-- agent-meta {"model":"openai/gpt-6-sol","provider":"openrouter","persona":"full","sessionId":"52892148-10f8-4161-aae7-6a844bc9eaa6","tokensIn":522751,"tokensOut":20468,"tokensTotal":543219,"cost":0.37100820000000007,"turns":23,"toolCalls":22,"failedToolCalls":0,"timestamp":"2026-09-22T21:59:15.259Z"} -->