← Worms results

Worms

GPT 5.6 Luna · composer

Initial view of Worms

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 21,963 bytes · SHA-256 7e61ee19dfd8
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WINDWORM // Artillery Royale</title>
<style>
/* ── css: base ── */
@import url('https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@400;600;700;800;900&family=Space+Mono:wght@400;700&display=swap');*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#09131c;color:#f2f4e9;font-family:'Barlow Condensed',sans-serif}#game{position:relative;width:100%;height:100%;overflow:hidden;background:#101b29}canvas{position:absolute;inset:0;width:100%;height:100%}#vignette{position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 48%,rgba(2,8,14,.56) 100%);z-index:2}.eyebrow{font:700 10px 'Space Mono';letter-spacing:2px;color:#89a5ad}.panel{background:rgba(9,19,28,.78);border:1px solid rgba(203,228,205,.16);box-shadow:0 10px 32px #02070c88;backdrop-filter:blur(8px)}button{font:800 14px 'Barlow Condensed';letter-spacing:1px;color:#edf3dc;border:0;cursor:pointer}button:hover{filter:brightness(1.25);transform:translateY(-1px)}
/* ── css: hud ── */
#topbar{position:absolute;z-index:4;top:0;left:0;right:0;height:75px;display:flex;align-items:center;padding:0 34px;background:linear-gradient(#07121cdd,transparent);gap:30px}.brand{display:flex;gap:11px;align-items:center;min-width:240px}.mark{font-size:30px;color:#ffce5c;text-shadow:0 0 18px #ff9d34}.brand b{display:block;letter-spacing:4px;font-size:19px}.brand small{display:block;color:#78929d;font:9px 'Space Mono';letter-spacing:2px}.round{margin-left:auto;color:#78929d;font:11px 'Space Mono';letter-spacing:1px}.round b{color:#f1eee2;font-size:19px;margin-left:8px}.round:before{content:'LIVE MATCH';color:#ff6958;border:1px solid #ff695855;padding:3px 6px;margin-right:15px;font-size:9px}#match{display:flex;gap:14px;align-items:center;color:#c0d4c7;font:11px 'Space Mono'}#match i{width:5px;height:5px;background:#ffcf63;border-radius:50%;box-shadow:0 0 12px #ffc33d}.match{}#leftHud{position:absolute;z-index:4;top:104px;left:28px;width:194px}.objective{padding:14px 16px 12px;position:relative}.objective strong{display:block;font-size:22px;color:#ffcf63;letter-spacing:1px;margin:4px 0 10px}.meter{height:4px;background:#253542;overflow:hidden}.meter i{display:block;height:100%;width:100%;background:#ffcf63;box-shadow:0 0 10px #ffcf63}.timer{display:flex;align-items:baseline;gap:8px;margin-top:5px}.timer b{font:700 24px 'Space Mono';color:#f2f4e9}.timer span{font:9px 'Space Mono';color:#6f8790}.teams{margin-top:9px;padding:10px 13px}.teamrow{display:flex;align-items:center;gap:8px;padding:7px 0;border-bottom:1px solid #ffffff0d;font-size:14px}.teamrow:last-child{border:0}.dot{width:9px;height:9px;border-radius:50%;box-shadow:0 0 12px currentColor}.teamrow small{margin-left:auto;color:#93a4a4;font:10px 'Space Mono'}.hp{height:3px;background:#24343b;flex:1}.hp i{display:block;height:100%}#weaponBar{position:absolute;z-index:4;left:50%;bottom:25px;transform:translateX(-50%);height:84px;display:flex;align-items:center;gap:13px;padding:9px 12px;background:#0a1823dd;border:1px solid #b7d6c626;box-shadow:0 9px 30px #0009}.weaponTitle{width:125px}.weaponTitle b{display:block;color:#ffcf63;font-size:18px}.weaponTitle small{color:#81979d;font-size:11px}#weapons{display:flex;gap:6px}.weapon{width:51px;height:57px;position:relative;background:#172b36;border:1px solid #41616a;color:#acc4ba;font-size:20px}.weapon em{position:absolute;bottom:3px;right:4px;font:9px 'Space Mono';font-style:normal}.weapon.active{border-color:#ffcf63;background:#4b3b27;color:#ffdb79;box-shadow:0 0 16px #ffbe3d44}.weapon.lock{opacity:.42}#fireBtn{height:57px;padding:0 19px;background:#e45e46;box-shadow:inset 0 -4px #a13b38,0 0 18px #f15b4533}.weaponTitle+ #weapons{}#aimReadout{position:absolute;z-index:4;right:35px;bottom:119px;font:10px 'Space Mono';color:#91a6a5;display:flex;gap:8px;align-items:center}#aimReadout b{color:#ffcf63;font-size:13px}.help{display:none}#help{position:absolute;z-index:4;right:28px;bottom:32px;color:#789099;font:9px 'Space Mono';letter-spacing:.6px}#toast{position:absolute;z-index:5;top:100px;left:50%;transform:translateX(-50%);font:700 15px 'Space Mono';letter-spacing:1px;color:#ffdc78;text-shadow:0 2px 8px #000;opacity:0;transition:.3s}.floatText{position:absolute;z-index:5;font:900 22px 'Space Mono';color:#ff8064;text-shadow:0 2px #17202a;pointer-events:none;animation:float 1.1s ease-out forwards}@keyframes float{to{transform:translateY(-50px);opacity:0}}
/* ── css: modal ── */
#overlay{position:absolute;z-index:10;inset:0;display:grid;place-items:center;background:linear-gradient(120deg,#08131de8,#162938dd)}.modal{width:640px;padding:42px 48px 34px;border:1px solid #b9d9ca33;background:#0b1a26ee;box-shadow:0 30px 80px #000b;position:relative}.modal:after{content:'';position:absolute;inset:9px;border:1px solid #ffffff0b;pointer-events:none}.modalKicker{font:11px 'Space Mono';letter-spacing:4px;color:#ffcf63}.modal h1{font-size:76px;line-height:.85;margin:13px 0 12px;letter-spacing:5px}.modal h1 span{color:#ffcf63}.modal p{font:14px 'Space Mono';color:#91aaad;margin:0 0 30px}.choices{display:flex;gap:8px}.choices button{flex:1;text-align:left;padding:14px;background:#172c36;border:1px solid #4a6870;color:#d4e1d4}.choices button:first-child{background:#36432f;border-color:#a4bd74}.choices small{display:block;color:#8da29a;font:10px 'Space Mono';margin-top:4px}.setup{display:flex;align-items:center;justify-content:space-between;margin-top:28px;padding-top:19px;border-top:1px solid #ffffff15}.setup label{font:10px 'Space Mono';color:#91aaad}.setup select{background:#162b35;color:#f3dd9a;border:1px solid #527079;padding:8px 15px;margin-left:9px;font:12px 'Space Mono'}.setup button{background:#ffcf63;color:#17202a;padding:13px 22px;box-shadow:0 3px #ad783b}.setup button:hover{background:#ffe395}
/* ── css: responsive ── */
@media(max-width:700px){#topbar{padding:0 15px;height:60px}.brand{min-width:0}.brand b{font-size:15px}.brand small,.round:before,#match{display:none}.round{font-size:9px}.round b{font-size:16px}.round{margin-left:auto}#leftHud{top:72px;left:12px;width:155px}.objective{padding:10px}.objective strong{font-size:18px}.teams{display:none}#weaponBar{left:8px;right:8px;bottom:12px;transform:none;height:74px;gap:5px;padding:6px}.weaponTitle{display:none}#weapons{flex:1;justify-content:center}.weapon{width:39px;height:53px}.weapon em{font-size:8px}#fireBtn{height:53px;padding:0 10px;font-size:12px}#aimReadout{right:13px;bottom:97px;font-size:8px}#help{display:none}.modal{width:calc(100vw - 28px);padding:28px 20px 22px}.modal h1{font-size:52px}.modal p{font-size:11px;margin-bottom:19px}.choices{flex-direction:column;gap:5px}.choices button{padding:10px}.setup{margin-top:18px;gap:10px}.setup label{font-size:9px}.setup select{padding:6px 8px;margin-left:3px}.setup button{padding:11px 12px;font-size:12px}.modal:after{inset:6px}}
</style>
</head>
<body>
<main id="game"><canvas id="world"></canvas><div id="vignette"></div><header id="topbar"><div class="brand"><span class="mark">✦</span><div><b>WINDWORM</b><small>ARTILLERY ROYALE</small></div></div><div id="match"><span id="shapeLabel">ISLANDS</span><i></i><span id="windLabel">WIND +0</span></div><div class="round">ROUND <b id="roundLabel">01</b></div></header><aside id="leftHud"><div class="panel objective"><span class="eyebrow">MISSION</span><strong id="statusText">YOUR TURN</strong><div class="meter"><i id="timeMeter"></i></div><div class="timer"><b id="timerLabel">30</b><span>SECONDS</span></div></div><div class="panel teams" id="teamsPanel"></div></aside><section id="weaponBar"><div class="weaponTitle"><span class="eyebrow">LOADOUT</span><b id="activeWeaponName">BAZOOKA</b><small id="weaponHint">Heavy arc • blast radius</small></div><div id="weapons"></div><button id="fireBtn">FIRE <span>⏎</span></button></section><div id="aimReadout">ANGLE <b id="angleLabel">42°</b><span></span>POWER <b id="powerLabel">72%</b></div><div id="toast"></div><div id="help">A / D MOVE  W JUMP  MOUSE AIM  SPACE FIRE  Q / E WEAPONS</div><div id="overlay"><div class="modal"><div class="modalKicker">TACTICAL SANDBOX</div><h1>WIND<span>WORM</span></h1><p>Build a legend. Break the island.</p><div class="choices"><button data-shape="islands">TWO ISLANDS<small>balanced duel</small></button><button data-shape="cave">CAVE WORLD<small>close quarters</small></button><button data-shape="single">LONE ISLAND<small>high ground</small></button></div><div class="setup"><label>TEAMS <select id="teamCount"><option>2</option><option>3</option><option>4</option></select></label><button id="startBtn">START BATTLE →</button></div></div></div></main>
<script>
'use strict';

// ── const: GAME ──
const GAME = { canvas:null, ctx:null, W:1400, H:760, terrain:[], waterY:650, shape:'islands', teams:2, units:[], particles:[], texts:[], shots:[], debris:[], wind:0, active:0, round:1, time:30, running:false, paused:0, camera:{x:0,y:0,zoom:1}, mouse:{x:800,y:350}, keys:{}, weapon:0, weapons:[{name:'BAZOOKA',icon:'➶',hint:'Heavy arc • blast radius',kind:'indirect',power:8,r:54},{name:'ZAP RIFLE',icon:'ϟ',hint:'Instant hit • pierces',kind:'direct',power:35,r:4},{name:'CLUSTER',icon:'✣',hint:'Splits into 5 bomblets',kind:'indirect',power:13,r:30},{name:'NAPALM',icon:'♨',hint:'Burning ground • area denial',kind:'aoe',power:18,r:34},{name:'DRILL',icon:'◈',hint:'Tunnels through terrain',kind:'aoe',power:45,r:42},{name:'WINDMILL',icon:'✦',hint:'Launches units skyward',kind:'utility',power:0,r:0}], colors:['#ff6f61','#60d5c5','#b48cff','#ffcf63'], init(){this.canvas=document.querySelector('#world');this.ctx=this.canvas.getContext('2d');this.resize();addEventListener('resize',()=>this.resize());this.bind();this.makeTerrain('islands');this.draw();},resize(){this.canvas.width=innerWidth*devicePixelRatio;this.canvas.height=innerHeight*devicePixelRatio;this.ctx.setTransform(devicePixelRatio,0,0,devicePixelRatio,0,0);this.vw=innerWidth;this.vh=innerHeight;},makeTerrain(shape){this.shape=shape;this.terrain=[];let seed=shape==='cave'?2:shape==='single'?8:5;for(let x=0;x<=this.W;x+=6){let y=565+Math.sin(x*.012+seed)*24+Math.sin(x*.027)*13+Math.sin(x*.004)*25;if(shape==='islands'){if(x>180&&x<480)y-=85*Math.sin((x-180)/300*Math.PI);if(x>760&&x<1220)y-=100*Math.sin((x-760)/460*Math.PI);if(x>480&&x<760)y=675;}if(shape==='single'){y-=155*Math.sin((x-100)/1200*Math.PI);if(x<110||x>1290)y=675;}if(shape==='cave'){y=520+Math.sin(x*.011)*22; if(x>250&&x<1150)y=520+Math.sin(x*.013)*35;}this.terrain.push(Math.max(350,Math.min(690,y)));}if(shape==='cave'){this.waterY=700;}else this.waterY=650;},ground(x){x=Math.max(0,Math.min(this.W,x));let i=Math.floor(x/6),a=this.terrain[i]??680,b=this.terrain[i+1]??a;return a+(b-a)*((x/6)%1);},makeTeams(n){this.teams=n;this.units=[];let spots=this.shape==='islands'?[220,330,850,1010]:[150,350,850,1100];for(let t=0;t<n;t++)for(let j=0;j<4;j++){let x=spots[(t*4+j)%spots.length]+(j%2)*18-9; if(n>2)x=(t/(n-1))*1080+150+j*12;this.units.push({x,y:this.ground(x)-18,vx:0,vy:0,r:15,hp:100,team:t,alive:true,name:['BOLT','MOSS','PIXEL','GOBLIN'][j],onGround:false});}},start(shape){this.makeTerrain(shape);this.makeTeams(+document.querySelector('#teamCount').value);this.running=true;document.querySelector('#overlay').style.display='none';this.active=0;this.time=30;this.wind=(Math.random()*2-1)*7;this.toast('WIND SHIFT  '+(this.wind>0?'+':'')+this.wind.toFixed(1));this.updateTeams();},bind(){document.querySelectorAll('[data-shape]').forEach(b=>b.onclick=()=>{document.querySelectorAll('[data-shape]').forEach(x=>x.style.background='');b.style.background='#36432f';this.shape=b.dataset.shape;});document.querySelector('#startBtn').onclick=()=>this.start(this.shape);document.querySelector('#fireBtn').onclick=()=>this.fire();addEventListener('keydown',e=>{this.keys[e.key.toLowerCase()]=true;if(e.key===' ')this.fire();if(e.key.toLowerCase()==='q')this.select((this.weapon+5)%6);if(e.key.toLowerCase()==='e')this.select((this.weapon+1)%6);if(e.key.toLowerCase()==='w'&&this.current()?.onGround)this.current().vy=-10;});addEventListener('keyup',e=>this.keys[e.key.toLowerCase()]=false);this.canvas.onmousemove=e=>{this.mouse.x=e.clientX;this.mouse.y=e.clientY;};this.canvas.onclick=()=>{if(this.running)this.fire();};document.querySelectorAll('.weapon').forEach((b,i)=>b.onclick=()=>this.select(i));},current(){return this.units[this.active];},select(i){this.weapon=i;this.renderWeapons();},renderWeapons(){let el=document.querySelector('#weapons');el.innerHTML=this.weapons.map((w,i)=>`<button class="weapon ${i===this.weapon?'active':''}" data-i="${i}">${w.icon}<em>${i+1}</em></button>`).join('');el.querySelectorAll('button').forEach(b=>b.onclick=()=>this.select(+b.dataset.i));let w=this.weapons[this.weapon];document.querySelector('#activeWeaponName').textContent=w.name;document.querySelector('#weaponHint').textContent=w.hint;},aim(){let u=this.current();if(!u)return {a:-.7,p:.7};let dx=this.mouse.x-this.vw/2-(u.x-this.camera.x);let dy=this.mouse.y-this.vh/2-(u.y-this.camera.y);let a=Math.atan2(dy,dx);if(dx<0)a=Math.PI-a;return {a:Math.max(-2.8,Math.min(-.2,a)),p:Math.min(1,Math.max(.25,Math.hypot(dx,dy)/430))};},fire(){if(!this.running||this.paused||!this.current()?.alive)return;let u=this.current(),w=this.weapons[this.weapon],q=this.aim();if(w.kind==='direct'){this.laser(u,q);this.endTurn();return}let speed=9+q.p*10;this.shots.push({x:u.x+Math.cos(q.a)*22,y:u.y+Math.sin(q.a)*22,vx:Math.cos(q.a)*speed,vy:Math.sin(q.a)*speed,team:u.team,weapon:this.weapon,life:300});this.toast(w.name+' AWAY');this.paused=0;this.endTurn(1);},laser(u,q){let x=u.x,y=u.y,hit=null;for(let d=0;d<1400;d+=8){x+=Math.cos(q.a)*8;y+=Math.sin(q.a)*8;if(y>this.ground(x)){hit={x,y};break}for(let v of this.units)if(v.alive&&v.team!==u.team&&Math.hypot(v.x-x,v.y-y)<18)hit={x:v.x,y:v.y};}this.burst(hit?.x||x,hit?.y||y,'#7fffe0',18);if(hit)this.damage(hit.x,hit.y,35,22);},endTurn(fired=0){if(fired)this.time=Math.max(8,this.time-1);this.active=this.nextAlive(this.active);this.time=30;this.wind+=(Math.random()-.5)*2;this.round++;this.renderWeapons();if(this.units[this.active]?.team>0){setTimeout(()=>this.ai(),500)}},nextAlive(i){for(let n=1;n<=this.units.length;n++){let k=(i+n)%this.units.length;if(this.units[k].alive)return k}return i;},ai(){if(!this.running)return;let u=this.current();if(!u||u.team===0)return;let target=this.units.filter(x=>x.alive&&x.team!==u.team).sort((a,b)=>Math.abs(a.x-u.x)-Math.abs(b.x-u.x))[0];if(!target){this.win();return}let dx=target.x-u.x,dy=target.y-u.y;this.mouse.x=this.vw/2+dx;this.mouse.y=this.vh/2+dy-150;this.weapon=(Math.floor(Math.random()*4));this.select(this.weapon);setTimeout(()=>this.fire(),700);},damage(x,y,amount,r){for(let u of this.units){let d=Math.hypot(u.x-x,u.y-y);if(u.alive&&d<r+u.r){let dmg=Math.max(5,amount*(1-d/(r+u.r)));u.hp-=dmg;this.texts.push({x:u.x,y:u.y,t:'-'+Math.round(dmg),c:'#ff8064',life:70});if(u.hp<=0){u.alive=false;this.burst(u.x,u.y,'#ff705d',25);}}}this.updateTeams();},explode(x,y,w){let r=w.r;this.damage(x,y,w.power,r);if(w.name==='DRILL'||w.name==='NAPALM')for(let i=Math.max(0,Math.floor((x-r)/6));i<Math.min(this.terrain.length,Math.ceil((x+r)/6));i++){let dx=i*6-x;if(Math.abs(dx)<r)this.terrain[i]=Math.min(695,this.terrain[i]+Math.sqrt(r*r-dx*dx)*.65)}this.burst(x,y,w.name==='DRILL'?'#7bd4c3':'#ff9b50',34);this.paused=w.r>45?8:0;},burst(x,y,c,n){for(let i=0;i<n;i++){let a=Math.random()*Math.PI*2,s=Math.random()*6+1;this.particles.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s-2,life:30+Math.random()*30,c});}},toast(s){let t=document.querySelector('#toast');t.textContent=s;t.style.opacity=1;clearTimeout(this.tt);this.tt=setTimeout(()=>t.style.opacity=0,1300);},updateTeams(){let el=document.querySelector('#teamsPanel');el.innerHTML='<span class="eyebrow">SQUADS / VITALS</span>'+Array.from({length:this.teams},(_,t)=>{let us=this.units.filter(u=>u.team===t),hp=us.reduce((a,u)=>a+(u.alive?u.hp:0),0);return `<div class="teamrow"><i class="dot" style="color:${this.colors[t]}"></i>TEAM ${t+1}<small>${Math.round(hp)}</small><div class="hp"><i style="width:${hp/(us.length*100)*100}%;background:${this.colors[t]}"></i></div></div>`}).join('');},physics(){for(let u of this.units)if(u.alive){if(u===this.current()){if(this.keys.a)u.vx-=.18;if(this.keys.d)u.vx+=.18;if(this.keys.w&&u.onGround)u.vy=-10;}u.vy+=.35;u.vx+=this.wind*.003;u.vx*=.91;u.x+=u.vx;u.y+=u.vy;let g=this.ground(u.x);u.onGround=u.y+u.r>=g;if(u.onGround){if(u.vy>9)this.damage(u.x,g,Math.min(35,u.vy*2),28);u.y=g-u.r;u.vy=0;u.vx*=.72}if(u.y>this.waterY+40){u.alive=false;this.texts.push({x:u.x,y:this.waterY,t:'SPLASH!',c:'#72dbe3',life:65});this.burst(u.x,this.waterY,'#72dbe3',18);}}for(let s of this.shots){s.vy+=.25;s.vx+=this.wind*.012;s.x+=s.vx;s.y+=s.vy;s.life--;if(s.y>=this.ground(s.x)||s.life<0||s.x<0||s.x>this.W){this.explode(s.x,s.y,this.weapons[s.weapon]);s.dead=true}}this.shots=this.shots.filter(s=>!s.dead);for(let p of this.particles){p.x+=p.vx;p.y+=p.vy;p.vy+=.13;p.vx*=.98;p.life--}this.particles=this.particles.filter(p=>p.life>0);for(let t of this.texts){t.y-=.4;t.life--}this.texts=this.texts.filter(t=>t.life>0);},draw(){let c=this.ctx,w=this.vw,h=this.vh;c.clearRect(0,0,w,h);let g=c.createLinearGradient(0,0,0,h);g.addColorStop(0,'#142b48');g.addColorStop(.55,'#395b6d');g.addColorStop(1,'#dd956b');c.fillStyle=g;c.fillRect(0,0,w,h);c.fillStyle='#d9ce9c';c.globalAlpha=.12;for(let i=0;i<16;i++)c.fillRect((i*137-this.camera.x*.12)%w,100+(i%4)*55,2,2);c.globalAlpha=1;let zx=this.camera.zoom,ox=w/2-(this.camera.x)*zx,oy=h/2-this.camera.y*zx;c.save();c.translate(ox,oy);c.scale(zx,zx);c.fillStyle='#173244';c.beginPath();c.moveTo(0,this.H);for(let x=0;x<=this.W;x+=6)c.lineTo(x,this.ground(x));c.lineTo(this.W,this.H);c.fill();c.fillStyle='#254d4d';c.beginPath();c.moveTo(0,this.H);for(let x=0;x<=this.W;x+=6)c.lineTo(x,this.ground(x)+5);c.lineTo(this.W,this.H);c.fill();c.strokeStyle='#7da48d';c.lineWidth=3;c.beginPath();for(let x=0;x<=this.W;x+=6)c.lineTo(x,this.ground(x));c.stroke();c.fillStyle='#4d9cac';c.globalAlpha=.7;c.fillRect(0,this.waterY,this.W,this.H-this.waterY);c.globalAlpha=1;for(let u of this.units)if(u.alive)this.unit(u);for(let s of this.shots){c.fillStyle='#ffe398';c.shadowBlur=18;c.shadowColor='#ffac48';c.beginPath();c.arc(s.x,s.y,5,0,7);c.fill();c.shadowBlur=0}for(let p of this.particles){c.globalAlpha=Math.max(0,p.life/50);c.fillStyle=p.c;c.fillRect(p.x,p.y,3,3)}c.restore();let u=this.current();if(u){this.camera.x+=(u.x-this.camera.x)*.08;this.camera.y+=(u.y-this.camera.y)*.08;this.camera.zoom+=(1.05-this.camera.zoom)*.03}this.updateHud();requestAnimationFrame(()=>this.loop());},unit(u){let c=this.ctx;c.save();c.translate(u.x,u.y);c.fillStyle=this.colors[u.team];c.shadowBlur=12;c.shadowColor=this.colors[u.team];c.beginPath();c.arc(0,0,u.r,0,7);c.fill();c.shadowBlur=0;c.fillStyle='#13212b';c.beginPath();c.arc(-5,-3,3,0,7);c.arc(5,-3,3,0,7);c.fill();c.strokeStyle='#f5e8bc';c.lineWidth=2;c.beginPath();c.arc(0,3,6,0,Math.PI);c.stroke();c.restore();},updateHud(){if(!this.running)return;let q=this.aim(),sec=Math.ceil(this.time);document.querySelector('#timerLabel').textContent=sec;document.querySelector('#timeMeter').style.width=(sec/30*100)+'%';document.querySelector('#windLabel').textContent='WIND '+(this.wind>0?'+':'')+this.wind.toFixed(1);document.querySelector('#angleLabel').textContent=Math.round(-q.a*180/Math.PI)+'°';document.querySelector('#powerLabel').textContent=Math.round(q.p*100)+'%';document.querySelector('#roundLabel').textContent=String(Math.ceil(this.round/this.units.length)).padStart(2,'0');},loop(){if(this.running){if(!this.paused)this.physics();else this.paused--;if(this.current()?.team>0&&this.time--<0)this.endTurn();}this.draw();},win(){this.running=false;this.toast('BATTLE COMPLETE');},startLoop(){this.loop();}};

// ── main ──
GAME.init();GAME.renderWeapons();GAME.audio=null;GAME.beep=function(freq=220,dur=.08){try{this.audio??=new (window.AudioContext||window.webkitAudioContext)();let o=this.audio.createOscillator(),g=this.audio.createGain();o.type='square';o.frequency.value=freq;g.gain.setValueAtTime(.035,this.audio.currentTime);g.gain.exponentialRampToValueAtTime(.001,this.audio.currentTime+dur);o.connect(g);g.connect(this.audio.destination);o.start();o.stop(this.audio.currentTime+dur)}catch(e){}};const oldFire=GAME.fire.bind(GAME);GAME.fire=function(){this.beep(this.weapon===1?650:180,.1);oldFire()};const oldSelect=GAME.select.bind(GAME);GAME.select=function(i){this.beep(330+i*50,.045);oldSelect(i)};const oldHud=GAME.updateHud.bind(GAME);GAME.updateHud=function(){oldHud();let k=Math.max(0,(30-this.time)/30);document.querySelector('.objective').style.transform='scale('+(1+k*.045)+')';document.querySelector('#timeMeter').style.background=this.time<8?'#ff6558':'#ffcf63'};const baseDraw=GAME.draw.bind(GAME);GAME.draw=function(){baseDraw();if(!this.running||!this.current()?.alive)return;let u=this.current(),q=this.aim(),w=this.weapons[this.weapon],x=u.x,y=u.y,v=9+q.p*10,c=this.ctx;c.save();c.strokeStyle=w.kind==='direct'?'#9bffe1aa':'#ffdb7a99';c.setLineDash([5,7]);c.lineWidth=2;c.beginPath();for(let i=0;i<28;i++){let t=i*.12,px=x+Math.cos(q.a)*v*t+this.wind*.006*t*t*30,py=y+Math.sin(q.a)*v*t+.125*t*t*100,sx=this.vw/2+(px-this.camera.x)*this.camera.zoom,sy=this.vh/2+(py-this.camera.y)*this.camera.zoom;if(i===0)c.moveTo(sx,sy);else c.lineTo(sx,sy);if(py>this.ground(px))break}c.stroke();c.restore()};GAME.startLoop();
</script>
</body>
</html>
<!-- agent-meta {"model":"openai/gpt-5.6-luna","provider":"openrouter","persona":"composer","sessionId":"bfa80b05-650f-438c-ab99-dcecdfc4fe11","tokensIn":168932,"tokensOut":9614,"tokensTotal":178546,"turns":16,"toolCalls":19,"failedToolCalls":1,"timestamp":"2026-07-14T03:32:50.378Z"} -->