Worms
GPT 5.6 Luna · legacy

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 19,736 bytes · SHA-256 6f6bde38389f
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"><title>BLASTBURROW</title><style>
:root{--bg:#10172b;--panel:#172542e8;--line:#ffffff25;--lime:#b7ff6a;--orange:#ff8f5c;--cyan:#76e9ff;--pink:#ff6688}*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:var(--bg);color:#f4f7ff;font:14px system-ui,sans-serif}canvas{display:block;width:100%;height:100%}#game{position:fixed;inset:0;background:#121b35}.ui{position:fixed;inset:0;pointer-events:none}.top{position:absolute;top:14px;left:18px;right:18px;display:flex;justify-content:space-between;align-items:flex-start}.brand{color:var(--lime);letter-spacing:.18em;font-weight:800;text-shadow:0 0 13px #b7ff6a88}.info{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}.pill,.panel{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:9px 13px;box-shadow:0 8px 30px #03081655;backdrop-filter:blur(8px)}.pill b{color:#fff}.bottom{position:absolute;bottom:14px;left:18px;right:18px;display:flex;justify-content:space-between;align-items:flex-end}.weapons{display:flex;gap:6px;pointer-events:auto;max-width:70vw;overflow:auto}.weapon{min-width:108px;text-align:left;background:var(--panel);border:1px solid var(--line);border-radius:9px;color:#fff;padding:9px 10px;cursor:pointer}.weapon:hover,.weapon.active{border-color:var(--lime);background:#b7ff6a18}.weapon small{display:block;color:#9aaccc;font-size:10px;margin-top:3px}.weapon i{font-style:normal;color:var(--cyan);font-size:10px}.powerbox{width:170px;text-align:right}.powerline{height:8px;background:#ffffff16;border-radius:10px;overflow:hidden;margin:4px 0}.powerline i{display:block;height:100%;width:50%;background:linear-gradient(90deg,var(--cyan),var(--orange));border-radius:10px}.turnbox{text-align:right;min-width:165px}.turnbox strong{font-size:25px;color:var(--lime);display:block}.timer{height:5px;background:#ffffff1a;border-radius:5px;overflow:hidden}.timer i{display:block;height:100%;width:100%;background:var(--lime);transition:width .2s}.hint{color:#9aaccc;font-size:11px;margin-top:5px}.modal{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#090d1bd9;z-index:5}.card{width:min(730px,92vw);padding:30px;background:linear-gradient(135deg,#1e3151ee,#12192fe8);border:1px solid #ffffff35;border-radius:18px;box-shadow:0 20px 100px #020410aa;text-align:center}.card h1{font-size:clamp(34px,8vw,72px);letter-spacing:.13em;margin:0;color:#fff;text-shadow:0 0 25px #76e9ffaa}.card h2{color:var(--lime);letter-spacing:.08em}.card p{color:#aab9d5;line-height:1.55}.buttons{display:flex;justify-content:center;gap:10px;flex-wrap:wrap;margin:22px 0}.btn{background:#ffffff12;border:1px solid #ffffff3c;border-radius:8px;color:#fff;padding:12px 20px;cursor:pointer}.btn:hover{background:#b7ff6a22;border-color:var(--lime)}.btn.primary{background:linear-gradient(110deg,#6c9d5b,#5485a6);border-color:#d8ffaf}.hide{display:none}.toast{position:absolute;top:75px;left:50%;transform:translate(-50%,-10px);opacity:0;transition:.25s;background:#151f3af2;border:1px solid var(--cyan);padding:10px 17px;border-radius:9px;z-index:3}.toast.show{opacity:1;transform:translate(-50%,0)}.float{position:absolute;font-weight:900;font-size:21px;color:#fff;text-shadow:0 2px 5px #000;animation:up 1s forwards;pointer-events:none}@keyframes up{to{transform:translateY(-55px);opacity:0}}.danger{color:var(--pink)!important;transform:scale(1.08)}@media(max-width:650px){.top{left:9px;right:9px}.brand{font-size:11px}.pill{padding:6px;font-size:11px}.bottom{left:9px;right:9px;bottom:8px;display:block}.weapons{max-width:100%;margin-bottom:7px}.weapon{min-width:86px;padding:7px;font-size:11px}.powerbox{display:none}.turnbox{margin-left:auto}.hint{font-size:10px}}
</style></head><body><div id="game"></div><div class="ui"><div class="top"><div class="brand">BLASTBURROW // 04</div><div class="info"><div class="pill">WIND <b id="wind">→ 0</b></div><div class="pill">ROUND <b id="round">1</b></div><div class="pill">● <b id="alive">8</b></div><button class="btn" id="pause">MENU</button></div></div><div class="bottom"><div class="weapons" id="weapons"></div><div class="powerbox"><div>POWER <b id="powerVal">50%</b></div><div class="powerline"><i id="power"></i></div><div class="hint">A/D aim · W/S power · SPACE fire</div></div><div class="turnbox"><strong id="turnName">READY</strong><div class="timer"><i id="timer"></i></div><div class="hint" id="turnHint">Move / aim / fire</div></div></div><div id="toast" class="toast"></div></div><div id="menu" class="modal"><div class="card"><h1>BLASTBURROW</h1><p>Small creatures. Big ballistic problems.<br>A tactile hot-seat artillery brawl in a world that comes apart.</p><div class="buttons"><button class="btn primary" id="start2">2 TEAMS · HOT-SEAT</button><button class="btn" id="start3">3 TEAMS · HOT-SEAT</button><button class="btn" id="start4">4 TEAMS · HOT-SEAT</button><button class="btn" id="cpu">1P vs CPU</button></div><p style="font-size:11px">A/D aim · W/S adjust power · SPACE launch · arrows move/jump · 1–8 select weapon<br>Direct hits, cave-ins, water, wind, falling debris. Every crater is permanent.</p></div></div><script>
(()=>{'use strict';const $=s=>document.querySelector(s),rand=(a,b)=>a+Math.random()*(b-a),clamp=(v,a,b)=>Math.max(a,Math.min(b,v));let cvs,ctx,W,H,grid=[],terrain=[],water=[],debris=[],parts=[],texts=[],units=[],teams=[],active=0,turnTime=28,timeLeft=28,running=false,mode='hot',teamCount=2,round=1,last=0,shake=0,freeze=0,cam={x:0,y:0,z:1},keys={},aim=0,power=.5,weapon=0,wind=0,mouse={x:0,y:0},audio=null;
const weapons=[['Dirt Dart','indirect',24,1,'Small shell; reliable crater.'],['Twin Spit','indirect',16,2,'Two quick projectiles.'],['Beam Needle','direct',32,1,'Instant, piercing line.'],['Popper Box','aoe',26,1,'Drops five bouncing pops.'],['Skyquake','aoe',45,1,'Map-altering vertical blast.'],['Goo Balloon','utility',10,1,'Sticky gravity well slows foes.'],['Spring Snare','utility',0,1,'Launches a unit skyward.'],['Mend Mite','utility',-30,1,'Restores 30 health.']];
const colors=['#74d6ff','#ff7599','#c7ff68','#d598ff'];const names=['NIB','MOP','ZIG','BOK','PIP','GUM','DOT','KEX','WUB','LOO','NOD','FIZZ','JAX','BEE','MUR','TIK'];
function init(){cvs=document.createElement('canvas');ctx=cvs.getContext('2d');$('#game').appendChild(cvs);resize();window.addEventListener('resize',resize);window.addEventListener('keydown',e=>{keys[e.code]=true;if(['Space','ArrowLeft','ArrowRight','ArrowUp','ArrowDown'].includes(e.code))e.preventDefault();if(!running)return;if(e.code==='Space')fire();if(e.code==='Digit1'||e.code==='Digit2'||e.code==='Digit3'||e.code==='Digit4'||e.code==='Digit5'||e.code==='Digit6'||e.code==='Digit7'||e.code==='Digit8'){weapon=+e.code.slice(5)-1;renderWeapons()} });window.addEventListener('keyup',e=>keys[e.code]=false);$('#start2').onclick=()=>start(2,false);$('#start3').onclick=()=>start(3,false);$('#start4').onclick=()=>start(4,false);$('#cpu').onclick=()=>start(2,true);$('#pause').onclick=()=>pause();setInterval(()=>{if(audio&&running&&Math.random()<.3)beep(110+Math.random()*80,.03,'sine')},900);requestAnimationFrame(loop)}
function resize(){W=innerWidth;H=innerHeight;cvs.width=W*devicePixelRatio;cvs.height=H*devicePixelRatio;ctx.setTransform(devicePixelRatio,0,0,devicePixelRatio,0,0);if(running)draw()}
function start(n,cpu){audio=audio||new(window.AudioContext||window.webkitAudioContext)();audio.resume();teamCount=n;mode=cpu?'cpu':'hot';teams=[];units=[];active=0;round=1;debris=[];parts=[];texts=[];generateTerrain();for(let t=0;t<n;t++){teams.push({name:['AZURE','CORAL','CITRINE','VIOLET'][t],color:colors[t]});for(let q=0;q<4;q++){let x=120+(W-240)*(q+1)/5+rand(-25,25),y=surface(x)-17;units.push({x,y,vx:0,vy:0,r:11,hp:100,team:t,name:names[t*4+q],ground:false,dead:false,fall:0})}}running=true;$('#menu').classList.add('hide');selectActive();toast('Wind is '+(wind>0?'pushing right':'pushing left')+'. Make it count.');}
function generateTerrain(){let shape=Math.floor(Math.random()*3),gw=Math.max(180,Math.floor(W/4)),gh=Math.max(100,Math.floor(H/4));grid=Array.from({length:gw},()=>Array(gh).fill(false));water=Array.from({length:gw},()=>Array(gh).fill(false));let base=gh*.61;for(let x=0;x<gw;x++){let h=base+Math.sin(x*.12)*12+Math.sin(x*.027)*22+rand(-7,7);if(shape===0)h=base-10+Math.sin(x*.08)*27+Math.sin(x*.21)*9;if(shape===1)h=base+Math.abs(x-gw/2)*.09+Math.sin(x*.1)*13;if(shape===2){let gap=gw*.5;h=(x<gap-22||x>gap+22)?base+Math.sin(x*.08)*20:gh*.91}for(let y=Math.floor(h);y<gh;y++)grid[x][y]=true} // carve caves
if(shape===0)for(let i=0;i<9;i++){let cx=rand(20,gw-20),cy=rand(base+20,gh-12),rx=rand(8,20),ry=rand(7,14);for(let x=0;x<gw;x++)for(let y=0;y<gh;y++)if(((x-cx)/rx)**2+((y-cy)/ry)**2<1)grid[x][y]=false}
// water is an actual fluid channel in low points
let sea=Math.floor(gh*.83);for(let x=0;x<gw;x++)for(let y=sea;y<gh;y++)water[x][y]=!grid[x][y]||shape===2&&x>gw*.43&&x<gw*.57;terrain={gw,gh,scale:4,shape};wind=rand(-6,6);if(Math.abs(wind)<1)wind=3}
function at(x,y){let gx=Math.floor(x/terrain.scale),gy=Math.floor(y/terrain.scale);return gx>=0&&gx<terrain.gw&&gy>=0&&gy<terrain.gh?grid[gx][gy]:false}function inWater(x,y){let gx=Math.floor(x/4),gy=Math.floor(y/4);return gx>=0&&gx<terrain.gw&&gy>=0&&gy<terrain.gh&&water[gx][gy]&&!grid[gx][gy]&&y>H*.72}function surface(x){for(let y=0;y<H;y+=3)if(at(x,y))return y;return H-20}
function destroy(x,y,r){let gx=Math.floor(x/4),gy=Math.floor(y/4),rr=Math.ceil(r/4);for(let xx=-rr;xx<=rr;xx++)for(let yy=-rr;yy<=rr;yy++){let d=Math.hypot(xx,yy);if(d<rr&&gx+xx>=0&&gx+xx<terrain.gw&&gy+yy>=0&&gy+yy<terrain.gh){if(grid[gx+xx][gy+yy]){grid[gx+xx][gy+yy]=false;if(Math.random()<.18)debris.push({x:(gx+xx)*4,y:(gy+yy)*4,vx:rand(-2,2)+wind*.1,vy:rand(-2,1),life:rand(1,3),c:Math.random()<.5?'#846249':'#9d7656'})}}}for(let u of units)if(!u.dead&&Math.hypot(u.x-x,u.y-y)<r+14){let d=Math.max(0,Math.floor((r+14-Math.hypot(u.x-x,u.y-y))*1.2));hurt(u,d);u.vx+=(u.x>x?1:-1)*d*.12;u.vy-=d*.2}shake=Math.max(shake,r/12);burst(x,y,r>35?45:18,'#e5a75e')}
function hurt(u,n){if(!n)return;u.hp-=n;texts.push({x:u.x,y:u.y-22,s:'-'+n,c:n>35?'#ff6688':'#fff',life:1});if(u.hp<=0){u.hp=0;u.dead=true;burst(u.x,u.y,20,'#ff6688');beep(70,.2,'sawtooth')}}
function fire(){if(!running||timeLeft<=0)return;let u=units[active],w=weapons[weapon];if(!u||u.dead||u.flying)return;let ang=aim,spd=260+power*390;if(w[1]==='direct'){direct(u,ang,w[2]);endTurn();return}if(w[0]==='Mend Mite'){u.hp=clamp(u.hp+30,0,100);texts.push({x:u.x,y:u.y-20,s:'+30',c:'#b7ff6a',life:1});endTurn();return}if(w[0]==='Spring Snare'){u.vy=-520;u.flying=true;endTurn();return}let count=w[0]==='Twin Spit'?2:w[0]==='Popper Box'?5:1;for(let i=0;i<count;i++){let a=ang+(i-(count-1)/2)*.1;projectiles.push({x:u.x+Math.cos(a)*16,y:u.y-10+Math.sin(a)*16,vx:Math.cos(a)*spd,vy:Math.sin(a)*spd,kind:w[0],life:5,r:w[0]==='Skyquake'?8:6})}beep(w[1]==='aoe'?180:290,.11,'square');endTurn()}
let projectiles=[];
function direct(u,a,p){let x=u.x,y=u.y;for(let i=0;i<180;i++){x+=Math.cos(a)*4;y+=Math.sin(a)*4;if(at(x,y)){destroy(x,y,15);break}for(let q of units)if(!q.dead&&q.team!==u.team&&Math.hypot(q.x-x,q.y-y)<14){hurt(q,p);break}}burst(x,y,15,'#76e9ff');}
function endTurn(){if(projectiles.length)return;setTimeout(()=>{selectNext()},240)}
function selectNext(){for(let i=1;i<=units.length;i++){let n=(active+i)%units.length;if(!units[n].dead){active=n;timeLeft=turnTime;aim=units[n].team%2?Math.PI+.1: -.55;power=.5;selectActive();return}}finish()}
function selectActive(){if(!running)return;let u=units[active];if(!u||u.dead){selectNext();return}$('#turnName').textContent=teams[u.team].name+' · '+u.name;$('#turnName').style.color=teams[u.team].color;$('#turnHint').textContent=mode==='cpu'&&u.team>0?'CPU is calculating…':'Move / aim / fire';renderWeapons();updateHud();if(mode==='cpu'&&u.team>0)setTimeout(cpuTurn,650)}
function cpuTurn(){if(!running||units[active].team===0&&mode==='cpu')return;let u=units[active],targets=units.filter(x=>!x.dead&&x.team!==u.team);if(!targets.length)return finish();let target=targets.sort((a,b)=>Math.hypot(a.x-u.x,a.y-u.y)-Math.hypot(b.x-u.x,b.y-u.y))[0];let dx=target.x-u.x,dy=target.y-u.y;aim=Math.atan2(dy,dx);power=clamp(Math.hypot(dx,dy)/570,.35,.9);weapon=Math.random()<.3?4:(Math.random()<.25?2:0);renderWeapons();setTimeout(fire,500)}
function renderWeapons(){let box=$('#weapons');box.innerHTML=weapons.map((w,i)=>`<button class="weapon ${i===weapon?'active':''}" data-i="${i}"><b>${i+1}. ${w[0]}</b><small><i>${w[1]}</i> · ${w[2]===0?'UTILITY':w[2]+' DMG'}</small></button>`).join('');$$('.weapon').forEach(b=>b.onclick=()=>{weapon=+b.dataset.i;renderWeapons()})}
function physics(dt){let hadProjectiles=projectiles.length>0;for(let u of units){if(u.dead)continue;if(u===units[active]&&!u.flying&&!(mode==='cpu'&&u.team>0)){let side=(keys.KeyA||keys.ArrowLeft?-1:0)+(keys.KeyD||keys.ArrowRight?1:0);u.vx+=side*300*dt;if((keys.KeyW||keys.ArrowUp)&&u.ground){u.vy=-260;u.ground=false;beep(210,.05,'triangle')}}u.vy+=620*dt;u.vx*=Math.pow(.08,dt);u.vx+=wind*dt*3;u.x+=u.vx*dt;u.y+=u.vy*dt;u.x=clamp(u.x,12,W-12);if(at(u.x,u.y+12)){if(u.vy>270)hurt(u,Math.floor((u.vy-250)/7));u.y=surface(u.x)-12;u.vy=0;u.ground=true;u.flying=false}else u.ground=false;if(inWater(u.x,u.y)){u.vy=Math.min(u.vy,80);u.vx*=.92;u.fall+=dt;if(u.fall>3){u.dead=true;u.hp=0;texts.push({x:u.x,y:u.y,s:'SPLASH!',c:'#76e9ff',life:1});burst(u.x,u.y,18,'#76e9ff')}}else u.fall=0}
for(let p of projectiles){p.vy+=420*dt;p.vx+=wind*dt*8;p.x+=p.vx*dt;p.y+=p.vy*dt;p.life-=dt;if(p.x<0||p.x>W||p.y>H+20||p.life<0){p.life=0;continue}if(at(p.x,p.y)){impact(p);p.life=0;continue}for(let u of units)if(!u.dead&&Math.hypot(u.x-p.x,u.y-p.y)<u.r+p.r){impact(p);p.life=0;break}}projectiles=projectiles.filter(p=>p.life>0);if(hadProjectiles&&!projectiles.length)setTimeout(selectNext,260);for(let d of debris){d.vy+=500*dt;d.vx*=.99;d.x+=d.vx*dt;d.y+=d.vy*dt;d.life-=dt;if(at(d.x,d.y)){d.y=surface(d.x)-2;d.vy*=-.25;d.vx*=.6}}debris=debris.filter(d=>d.life>0);for(let p of parts){p.x+=p.vx*dt;p.y+=p.vy*dt;p.vy+=300*dt;p.life-=dt}parts=parts.filter(p=>p.life>0);for(let t of texts){t.y-=22*dt;t.life-=dt}texts=texts.filter(t=>t.life>0)}
function impact(p){let radius=p.kind==='Skyquake'?90:p.kind==='Popper Box'?38:p.kind==='Goo Balloon'?24:32;if(p.kind==='Goo Balloon'){for(let u of units)if(Math.hypot(u.x-p.x,u.y-p.y)<100)u.vx*=.2}destroy(p.x,p.y,radius);if(p.kind==='Popper Box'&&radius>0){for(let i=0;i<4;i++)projectiles.push({x:p.x,y:p.y,vx:rand(-240,240),vy:rand(-320,-100),kind:'Dirt Dart',life:2,r:5})}if(p.kind==='Skyquake'){for(let u of units)if(Math.abs(u.x-p.x)<120)hurt(u,Math.floor(45-Math.abs(u.x-p.x)*.2));freeze=.14}beep(radius>50?70:150,.16,'sawtooth')}
function burst(x,y,n,c){for(let i=0;i<n;i++)parts.push({x,y,vx:rand(-180,180),vy:rand(-230,40),life:rand(.35,1.1),c})}
function updateHud(){let u=units[active];$('#wind').textContent=(wind>0?'→ ':'← ')+Math.abs(wind).toFixed(1);$('#round').textContent=round;$('#alive').textContent=units.filter(x=>!x.dead).length;$('#powerVal').textContent=Math.floor(power*100)+'%';$('#power').style.width=power*100+'%';$('#timer').style.width=clamp(timeLeft/turnTime*100,0,100)+'%';if(timeLeft<7)$('#turnName').classList.add('danger');else $('#turnName').classList.remove('danger')}
function draw(){ctx.save();let u=units[active]||{x:W/2,y:H/2};let targetX=clamp(u.x-W/2,0,Math.max(0,W-W)),targetY=clamp(u.y-H/2,0,Math.max(0,H-H));cam.x+=(targetX-cam.x)*.04;cam.y+=(targetY-cam.y)*.04;ctx.translate(-cam.x+rand(-shake,shake),-cam.y+rand(-shake,shake));ctx.fillStyle='#111b39';ctx.fillRect(cam.x,cam.y,W,H);let sky=ctx.createLinearGradient(0,0,0,H);sky.addColorStop(0,'#203b65');sky.addColorStop(1,'#ed805d');ctx.fillStyle=sky;ctx.fillRect(cam.x,cam.y,W,H);ctx.fillStyle='#ffe1a2';ctx.globalAlpha=.2;ctx.beginPath();ctx.arc(W*.78,130,75,0,7);ctx.fill();ctx.globalAlpha=1; // terrain pixels
for(let x=0;x<terrain.gw;x++)for(let y=0;y<terrain.gh;y++)if(grid[x][y]){ctx.fillStyle=(y<terrain.gh*.72?'#6b4c3d':'#835d43');ctx.fillRect(x*4,y*4,4.5,4.5)}for(let x=0;x<terrain.gw;x++)for(let y=Math.floor(terrain.gh*.78);y<terrain.gh;y++)if(water[x][y]&&!grid[x][y]){ctx.fillStyle='#3e9bb0aa';ctx.fillRect(x*4,y*4,4,4)}for(let p of projectiles){ctx.fillStyle='#fff1bd';ctx.shadowBlur=12;ctx.shadowColor='#ff8f5c';ctx.beginPath();ctx.arc(p.x,p.y,5,0,7);ctx.fill();ctx.shadowBlur=0}for(let d of debris){ctx.fillStyle=d.c;ctx.fillRect(d.x,d.y,4,4)}for(let u2 of units)if(!u2.dead){ctx.fillStyle='#0008';ctx.beginPath();ctx.ellipse(u2.x,u2.y+17,18,5,0,0,7);ctx.fill();ctx.fillStyle=teams[u2.team].color;ctx.strokeStyle=u2===u?'#fff':'#15203a';ctx.lineWidth=3;ctx.beginPath();ctx.arc(u2.x,u2.y,11,0,7);ctx.fill();ctx.stroke();ctx.fillStyle='#17203b';ctx.beginPath();ctx.arc(u2.x-3,u2.y-2,2,0,7);ctx.arc(u2.x+4,u2.y-2,2,0,7);ctx.fill();ctx.fillStyle='#ffffffbb';ctx.font='10px system-ui';ctx.textAlign='center';ctx.fillText(u2.name,u2.x,u2.y-23);ctx.fillStyle='#161b2d';ctx.fillRect(u2.x-16,u2.y+14,32,4);ctx.fillStyle=u2.hp>40?'#b7ff6a':'#ff6688';ctx.fillRect(u2.x-16,u2.y+14,32*u2.hp/100,4)} // trajectory predictor
if(running&&!projectiles.length&&!u.dead&&!(mode==='cpu'&&u.team>0)){ctx.strokeStyle='#ffffff77';ctx.setLineDash([4,6]);ctx.beginPath();let x=u.x,y=u.y-12,vx=Math.cos(aim)*(260+power*390),vy=Math.sin(aim)*(260+power*390);ctx.moveTo(x,y);for(let i=0;i<35;i++){vx+=wind*.04;vy+=6;x+=vx*.04;y+=vy*.04;ctx.lineTo(x,y);if(at(x,y))break}ctx.stroke();ctx.setLineDash([])}ctx.globalAlpha=.85;for(let t of texts){ctx.fillStyle=t.c;ctx.font='bold 20px system-ui';ctx.fillText(t.s,t.x,t.y)}ctx.globalAlpha=1;ctx.restore();shake*=.88}
function pause(){if(!running)return;$('#menu').classList.remove('hide');$('.card h1').textContent='PAUSED // BURROW';$('.card p').innerHTML='The wind holds its breath.<br>Resume when ready.';$('#start2').textContent='RESUME';$('#start3').style.display='none';$('#start4').style.display='none';$('#cpu').style.display='none';$('#start2').onclick=()=>{$('#menu').classList.add('hide');$('#start2').textContent='2 TEAMS · HOT-SEAT';$('.card h1').textContent='BLASTBURROW';$('.card p').innerHTML='Small creatures. Big ballistic problems.<br>A tactile hot-seat artillery brawl in a world that comes apart.';$('#start3').style.display='';$('#start4').style.display='';$('#cpu').style.display='';};}
function finish(){running=false;$('#menu').classList.remove('hide');$('.card h1').textContent='BURROW COMPLETE';$('.card p').textContent='The last worm standing owns the horizon. Choose another skirmish.';$('#start2').textContent='REMATCH';$('#start3').style.display='';$('#start4').style.display='';$('#cpu').style.display='';}
function beep(f,d,type){if(!audio)return;let o=audio.createOscillator(),g=audio.createGain();o.type=type;o.frequency.value=f;g.gain.setValueAtTime(.045,audio.currentTime);g.gain.exponentialRampToValueAtTime(.001,audio.currentTime+d);o.connect(g);g.connect(audio.destination);o.start();o.stop(audio.currentTime+d)}
function loop(t){let dt=Math.min(.04,(t-last)/1000||.016);last=t;if(running){if(freeze>0)freeze-=dt;else{physics(dt);if(!projectiles.length&&!(mode==='cpu'&&units[active]?.team>0)){timeLeft-=dt;if(timeLeft<=0){toast('Time! The burrow chooses momentum.');endTurn()}}}if(!projectiles.length){let u=units[active];if(u&&!u.dead&&!(mode==='cpu'&&u.team>0)){if(keys.ArrowLeft||keys.KeyA)aim-=dt*.9;if(keys.ArrowRight||keys.KeyD)aim+=dt*.9;if(keys.ArrowUp||keys.KeyW)power=clamp(power+dt*.55,0,1);if(keys.ArrowDown||keys.KeyS)power=clamp(power-dt*.55,0,1)}}updateHud();draw()}requestAnimationFrame(loop)}init();
})();</script></body></html>