Run details
- Model
- gpt-6-luna
- Route
- Command Code CLI
- Reasoning
- provider default
- Limits
- 60 min
- Date
- 2 Oct 2026
- Time
- 85 s
- Size
- 17 kB
- Tokens
- 96,079 in, 13,249 out
- List price
- $0.016 ($0.1 in / $0.5 out per M)
- Paid
- Not billed per run (CLI plan)
Exact prompt
Make a Breakout game I can play right now with the keyboard or the mouse. Give it several levels, a score and some juice. It must be one complete, self-contained HTML file: inline all CSS and JavaScript, and make no network requests of any kind (no CDNs, web fonts or remote images). Save it as index.html in the current directory, then stop. Do not ask questions.
Source
17 kB 31 lines Raw
<!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">
<meta name="theme-color" content="#080b18">
<title>NEON BREAKER</title>
<style>
:root{color-scheme:dark;--ink:#080b18;--muted:#8490ad;--cyan:#53f6e5;--pink:#ff58b8;--gold:#ffd66b}*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:var(--ink);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;color:#f5f7ff;user-select:none}body{display:grid;place-items:center;background:radial-gradient(ellipse at 50% 110%,#172243 0%,#0b1022 48%,#070914 100%)}.shell{width:min(100vw,calc(100vh * .72));height:min(100vh,calc(100vw / .72));max-height:100%;position:relative;display:flex;flex-direction:column;padding:clamp(14px,3vw,30px);gap:14px}.top{height:62px;display:flex;align-items:center;justify-content:space-between;flex:none}.brand{display:flex;align-items:center;gap:12px}.mark{width:36px;height:36px;border:1px solid rgba(83,246,229,.55);border-radius:11px;display:grid;place-items:center;color:var(--cyan);box-shadow:0 0 22px #53f6e52b,inset 0 0 14px #53f6e511;font-size:20px}.brand-name{font-size:clamp(13px,2vw,17px);font-weight:900;letter-spacing:.18em}.brand-sub{font-size:9px;letter-spacing:.2em;color:var(--muted);margin-top:4px}.sound{border:1px solid #ffffff20;border-radius:10px;background:#ffffff08;color:#cbd3e9;padding:9px 12px;font:inherit;font-size:10px;letter-spacing:.12em;cursor:pointer}.sound:hover{border-color:#53f6e588;color:var(--cyan)}.stats{height:70px;display:grid;grid-template-columns:1.15fr 1fr 1fr 1fr;gap:9px;flex:none}.stat{border:1px solid #b6c6ff19;background:linear-gradient(135deg,#ffffff0b,#ffffff03);border-radius:12px;padding:12px 14px;position:relative;overflow:hidden}.stat:first-child{border-color:#53f6e52b}.label{font-size:9px;letter-spacing:.18em;color:var(--muted)}.value{font-size:clamp(17px,3vw,24px);font-weight:800;margin-top:5px;letter-spacing:.04em}.value.cyan{color:var(--cyan)}.value.gold{color:var(--gold)}.life-dots{display:flex;gap:6px;margin-top:9px}.life-dot{width:15px;height:6px;border-radius:5px;background:var(--pink);box-shadow:0 0 9px #ff58b877}.life-dot.off{background:#ffffff17;box-shadow:none}.board{flex:1;min-height:0;position:relative;border:1px solid #b6c6ff24;border-radius:17px;overflow:hidden;background:#080d1b;box-shadow:0 18px 65px #0008,0 0 55px #59cbe20a,inset 0 0 45px #53f6e506}.board:before{content:"";pointer-events:none;position:absolute;inset:0;z-index:1;border-radius:inherit;box-shadow:inset 0 0 0 1px #ffffff08,inset 0 0 48px #0b102b99}.board canvas{display:block;width:100%;height:100%}.footer{display:flex;justify-content:space-between;align-items:center;flex:none;height:26px;color:#8490ad;font-size:9px;letter-spacing:.11em}.keys{display:flex;gap:15px}.keyhint{display:flex;gap:6px;align-items:center}.key{border:1px solid #ffffff24;background:#ffffff08;color:#c3cce0;border-radius:4px;padding:3px 5px;font-size:9px}.footer-right{color:#596581}.toast{position:absolute;inset:0;z-index:3;display:grid;place-items:center;background:linear-gradient(0deg,#080b1899,#080b1866);transition:opacity .25s,visibility .25s}.toast.hidden{opacity:0;visibility:hidden;pointer-events:none}.card{width:min(82%,360px);padding:31px 25px 27px;border:1px solid #53f6e544;border-radius:16px;background:linear-gradient(145deg,rgba(19,29,54,.96),rgba(10,15,32,.97));text-align:center;box-shadow:0 0 70px #53f6e512,0 22px 70px #0008}.eyebrow{font-size:9px;color:var(--cyan);letter-spacing:.24em}.card h1{font-size:clamp(24px,5vw,38px);line-height:1.04;letter-spacing:.07em;margin:12px 0 9px}.card p{font-family:system-ui,sans-serif;font-size:13px;line-height:1.55;color:#a7b1ca;margin:0 auto 21px;max-width:270px}.action{border:0;border-radius:8px;padding:13px 22px;min-width:180px;background:var(--cyan);color:#06131a;font:900 11px ui-monospace,monospace;letter-spacing:.16em;cursor:pointer;box-shadow:0 0 25px #53f6e536;transition:transform .15s,filter .15s}.action:hover{filter:brightness(1.12);transform:translateY(-2px)}.micro{margin-top:15px!important;margin-bottom:0!important;font:9px ui-monospace,monospace!important;color:#687490!important;letter-spacing:.08em}.float-score{position:absolute;pointer-events:none;z-index:2;font-size:13px;font-weight:900;text-shadow:0 0 12px currentColor;animation:float 750ms ease-out forwards}@keyframes float{to{transform:translateY(-32px);opacity:0}}@media(max-width:540px){.shell{padding:12px;gap:10px}.top{height:45px}.stats{height:60px;gap:6px}.stat{padding:9px 8px}.label{font-size:8px}.footer{font-size:8px}.footer-right{display:none}.keys{gap:9px}.mark{width:31px;height:31px}}
</style>
</head>
<body>
<main class="shell">
<header class="top"><div class="brand"><div class="mark">✳</div><div><div class="brand-name">NEON BREAKER</div><div class="brand-sub">ARCADE SYSTEMS // 01</div></div></div><button class="sound" id="soundBtn" aria-label="Toggle sound">♫ SOUND ON</button></header>
<section class="stats" aria-label="Game stats"><div class="stat"><div class="label">SCORE</div><div class="value cyan" id="score">000000</div></div><div class="stat"><div class="label">LEVEL</div><div class="value" id="level">01 / 05</div></div><div class="stat"><div class="label">COMBO</div><div class="value gold" id="combo">×1</div></div><div class="stat"><div class="label">LIVES</div><div class="life-dots" id="lives"></div></div></section>
<section class="board" id="board"><canvas id="game" aria-label="Breakout game"></canvas><div class="toast" id="toast"><div class="card"><div class="eyebrow" id="eyebrow">READY PLAYER ONE</div><h1 id="title">BREAK<br>THE GRID</h1><p id="message">Clear every neon brick. Keep the ball alive. Make it count.</p><button class="action" id="action">START GAME</button><p class="micro">MOVE WITH ← → OR A / D · MOUSE WORKS TOO</p></div></div></section>
<footer class="footer"><div class="keys"><span class="keyhint"><span class="key">←</span><span class="key">→</span> MOVE</span><span class="keyhint"><span class="key">SPACE</span> LAUNCH / PAUSE</span><span class="keyhint"><span class="key">M</span> SOUND</span></div><div class="footer-right">NO QUARTERS REQUIRED</div></footer>
</main>
<script>
(()=>{
const canvas=document.getElementById('game'),ctx=canvas.getContext('2d'),board=document.getElementById('board');const $=id=>document.getElementById(id);const scoreEl=$('score'),levelEl=$('level'),comboEl=$('combo'),livesEl=$('lives'),toast=$('toast');const W=720,H=900,COLORS=['#ff5e9c','#ff9b59','#ffd166','#70e1a1','#52d8f4','#aa87ff'];let dpr=1,scaleX=1,scaleY=1,last=0,screenShake=0,flash=0,score=0,level=0,lives=3,combo=1,comboTimer=0,state='ready',soundOn=true,audio=null,particles=[],stars=[],bricks=[],keys={},pointerX=null;const paddle={x:W/2,y:H-82,w:112,h:14,speed:780};const ball={x:W/2,y:H-106,r:8,vx:0,vy:0,speed:430,stuck:true};
function resize(){const r=board.getBoundingClientRect();dpr=Math.min(devicePixelRatio||1,2);canvas.width=Math.round(r.width*dpr);canvas.height=Math.round(r.height*dpr);scaleX=canvas.width/W;scaleY=canvas.height/H;ctx.setTransform(scaleX,0,0,scaleY,0,0)}new ResizeObserver(resize).observe(board);resize();for(let i=0;i<100;i++)stars.push({x:Math.random()*W,y:Math.random()*H,r:Math.random()*1.5+.3,a:Math.random()*.55+.15,p:Math.random()*6.3});
const patterns=[['1111111111','1222222221','1233333321','1234444321','1234554321','1234444321'],['0011111100','0122222210','1233333321','2344444432','3455555543','2344444432','1233333321'],['1111111111','1200000021','1233333321','1234004321','1234554321','1234004321','1233333321','1200000021'],['1000000001','2100000012','3210000123','4321001234','5432112345','4321001234','3210000123','2100000012'],['1122332211','1223443221','2344554432','3455665433','2344554432','1223443221','1122332211']];
function buildLevel(){bricks=[];let rows=patterns[level%patterns.length],cols=10,gap=7,bw=(W-68-gap*(cols-1))/cols,bh=23,startX=(W-(cols*bw+(cols-1)*gap))/2,startY=96;rows.forEach((row,ri)=>[...row].forEach((n,ci)=>{if(n!=='0')bricks.push({x:startX+ci*(bw+gap),y:startY+ri*(bh+gap),w:bw,h:bh,hp:level>1&&level%2===1&&n>='4'?2:1,color:COLORS[(Number(n)-1+level)%COLORS.length],alive:true})}))}function updateUI(){scoreEl.textContent=String(score).padStart(6,'0');levelEl.textContent=String(level+1).padStart(2,'0')+' / 05';comboEl.textContent='×'+combo;livesEl.innerHTML='';for(let i=0;i<3;i++){let d=document.createElement('i');d.className='life-dot'+(i>=lives?' off':'');livesEl.appendChild(d)}}function sound(freq=440,duration=.07,type='sine',volume=.035){if(!soundOn)return;try{audio??=new(window.AudioContext||window.webkitAudioContext)();let o=audio.createOscillator(),g=audio.createGain();o.type=type;o.frequency.value=freq;g.gain.setValueAtTime(volume,audio.currentTime);g.gain.exponentialRampToValueAtTime(.001,audio.currentTime+duration);o.connect(g);g.connect(audio.destination);o.start();o.stop(audio.currentTime+duration)}catch{}}function burst(x,y,color,count=10,power=190){for(let i=0;i<count;i++){let a=Math.random()*Math.PI*2,s=Math.random()*power+35;particles.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s,life:.35+Math.random()*.55,max:.9,size:Math.random()*3+1,color})}}function addScore(n,x,y){score+=n;updateUI();let el=document.createElement('div');el.className='float-score';el.style.left=(x/W*100)+'%';el.style.top=(y/H*100)+'%';el.style.color=COLORS[(level+2)%COLORS.length];el.textContent='+'+n+(combo>1?' ×'+combo:'');board.appendChild(el);setTimeout(()=>el.remove(),800)}function attachBall(){ball.stuck=true;ball.vx=0;ball.vy=0;ball.x=paddle.x;ball.y=paddle.y-ball.r-3}function launch(){if(state==='ready'){startGame();return}if(state==='serve'){state='playing';ball.stuck=false;let angle=(Math.random()-.5)*.7;ball.vx=Math.sin(angle)*ball.speed;ball.vy=-Math.cos(angle)*ball.speed;sound(520,.1,'triangle');hideToast()}}function startGame(){score=0;level=0;lives=3;combo=1;comboTimer=0;particles=[];paddle.x=W/2;buildLevel();attachBall();state='serve';updateUI();hideToast()}function showToast(eyebrow,title,message,button){$('eyebrow').textContent=eyebrow;$('title').innerHTML=title;$('message').textContent=message;$('action').textContent=button;toast.classList.remove('hidden')}function hideToast(){toast.classList.add('hidden')}$('action').addEventListener('click',()=>{if(state==='ready'||state==='over'||state==='won')startGame();else if(state==='serve')launch();else if(state==='paused')resume()});$('soundBtn').addEventListener('click',()=>{soundOn=!soundOn;$('soundBtn').textContent=soundOn?'♫ SOUND ON':'♫ SOUND OFF';if(soundOn)sound(660,.06)});function pause(){if(state==='playing'||state==='serve'){state='paused';showToast('SYSTEM PAUSED','TAKE A<br>BREATHER','Your run is safe. Jump back in when you’re ready.','RESUME')}}function resume(){state=ball.stuck?'serve':'playing';hideToast();last=performance.now()}function endGame(won){state=won?'won':'over';showToast(won?'GRID DEFEATED':'GAME OVER',won?'YOU ARE<br>THE BREAKER':'ONE MORE<br>ROUND?',won?'All five sectors cleared. Final score: '+String(score).padStart(6,'0')+'.':'Final score: '+String(score).padStart(6,'0')+'. The grid is waiting.','PLAY AGAIN');sound(won?880:180,.35,won?'triangle':'sawtooth',.045)}function nextLevel(){level++;if(level>=5){endGame(true);return}buildLevel();paddle.x=W/2;ball.speed=Math.min(580,430+level*34);attachBall();state='serve';combo=1;updateUI();sound(720,.2,'triangle');flash=.35;showToast('SECTOR '+String(level+1).padStart(2,'0'),'NEXT<br>WAVE','The grid is shifting. Ready for the next sector?','CONTINUE')}function loseLife(){lives--;combo=1;updateUI();burst(ball.x,ball.y,'#ff5e9c',24,240);screenShake=12;sound(130,.24,'sawtooth',.05);if(lives<=0){endGame(false);return}paddle.x=W/2;attachBall();state='serve';showToast('BALL LOST','STAY IN<br>THE GAME','You have '+lives+' '+(lives===1?'life':'lives')+' left. Reset and keep going.','CONTINUE')}
function inputMove(clientX){const r=board.getBoundingClientRect();pointerX=(clientX-r.left)/r.width*W;paddle.x=Math.max(paddle.w/2,Math.min(W-paddle.w/2,pointerX));if(ball.stuck)ball.x=paddle.x}board.addEventListener('pointermove',e=>inputMove(e.clientX));board.addEventListener('pointerdown',e=>{inputMove(e.clientX);if(state==='ready'||state==='serve')launch();else if(state==='paused')resume()});window.addEventListener('keydown',e=>{let k=e.key.toLowerCase();if(['arrowleft','arrowright',' ','a','d'].includes(k))e.preventDefault();keys[k]=true;if(k===' '){if(state==='paused')resume();else launch()}if(k==='escape'||k==='p')pause();if(k==='m')$('soundBtn').click()});window.addEventListener('keyup',e=>keys[e.key.toLowerCase()]=false);window.addEventListener('blur',()=>{keys={};if(state==='playing')pause()});function roundedRect(x,y,w,h,r){ctx.beginPath();ctx.roundRect(x,y,w,h,r)}
function draw(){ctx.clearRect(0,0,W,H);let sx=screenShake?(Math.random()-.5)*screenShake:0,sy=screenShake?(Math.random()-.5)*screenShake:0;ctx.save();ctx.translate(sx,sy);let bg=ctx.createLinearGradient(0,0,0,H);bg.addColorStop(0,'#0c1225');bg.addColorStop(.6,'#0a1020');bg.addColorStop(1,'#090d1a');ctx.fillStyle=bg;ctx.fillRect(-20,-20,W+40,H+40);for(const s of stars){let tw=(Math.sin(performance.now()*.001+s.p)+1)*.18;ctx.globalAlpha=s.a+tw;ctx.fillStyle='#b9d9ff';ctx.beginPath();ctx.arc(s.x,s.y,s.r,0,Math.PI*2);ctx.fill()}ctx.globalAlpha=1;ctx.strokeStyle='#8aa4dc0b';ctx.lineWidth=1;for(let y=35;y<H;y+=45){ctx.beginPath();ctx.moveTo(0,y);ctx.lineTo(W,y);ctx.stroke()}ctx.fillStyle='#94a8d622';ctx.font='10px ui-monospace,monospace';ctx.textAlign='center';ctx.fillText('SECTOR '+String(level+1).padStart(2,'0'),W/2,45);for(const b of bricks){if(!b.alive)continue;ctx.save();ctx.shadowColor=b.color;ctx.shadowBlur=10;let gr=ctx.createLinearGradient(b.x,b.y,b.x,b.y+b.h);gr.addColorStop(0,b.color);gr.addColorStop(1,b.color+'b8');ctx.fillStyle=gr;roundedRect(b.x,b.y,b.w,b.h,5);ctx.fill();ctx.shadowBlur=0;ctx.fillStyle='#ffffff4b';roundedRect(b.x+3,b.y+2,b.w-6,3,2);ctx.fill();if(b.hp>1){ctx.fillStyle='#fff';ctx.font='bold 10px ui-monospace,monospace';ctx.textAlign='center';ctx.fillText('◆',b.x+b.w/2,b.y+16)}ctx.restore()}ctx.save();ctx.shadowColor='#53f6e5';ctx.shadowBlur=22;let pg=ctx.createLinearGradient(paddle.x-paddle.w/2,paddle.y,paddle.x+paddle.w/2,paddle.y);pg.addColorStop(0,'#29bfb8');pg.addColorStop(.5,'#c4fff5');pg.addColorStop(1,'#29bfb8');ctx.fillStyle=pg;roundedRect(paddle.x-paddle.w/2,paddle.y-paddle.h/2,paddle.w,paddle.h,7);ctx.fill();ctx.restore();if(!ball.stuck&&state==='playing'){ctx.save();ctx.globalAlpha=.23;ctx.strokeStyle='#a8fff5';ctx.lineWidth=4;ctx.beginPath();ctx.moveTo(ball.x,ball.y);ctx.lineTo(ball.x-ball.vx*.035,ball.y-ball.vy*.035);ctx.stroke();ctx.restore()}ctx.save();ctx.shadowColor='#fff';ctx.shadowBlur=22;let bgra=ctx.createRadialGradient(ball.x-2,ball.y-3,1,ball.x,ball.y,ball.r*1.5);bgra.addColorStop(0,'#fff');bgra.addColorStop(.45,'#c8fff8');bgra.addColorStop(1,'#53f6e5');ctx.fillStyle=bgra;ctx.beginPath();ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2);ctx.fill();ctx.restore();for(const p of particles){ctx.globalAlpha=Math.max(0,p.life/p.max);ctx.fillStyle=p.color;ctx.shadowColor=p.color;ctx.shadowBlur=9;ctx.beginPath();ctx.arc(p.x,p.y,p.size,0,Math.PI*2);ctx.fill()}ctx.globalAlpha=1;ctx.shadowBlur=0;if(flash>0){ctx.globalAlpha=flash;ctx.fillStyle='#bffffa';ctx.fillRect(0,0,W,H);ctx.globalAlpha=1}ctx.restore()}
function update(dt){if(state==='playing'||state==='serve'){let dir=(keys.arrowleft||keys.a?-1:0)+(keys.arrowright||keys.d?1:0);if(pointerX===null||dir)paddle.x+=dir*paddle.speed*dt;paddle.x=Math.max(paddle.w/2,Math.min(W-paddle.w/2,paddle.x));if(ball.stuck){ball.x=paddle.x;ball.y=paddle.y-ball.r-3}if(state==='playing'){let steps=Math.max(1,Math.ceil(dt*ball.speed/7)),sub=dt/steps;for(let s=0;s<steps;s++){let ox=ball.x,oy=ball.y;ball.x+=ball.vx*sub;ball.y+=ball.vy*sub;if(ball.x<ball.r){ball.x=ball.r;ball.vx=Math.abs(ball.vx);sound(260,.035)}else if(ball.x>W-ball.r){ball.x=W-ball.r;ball.vx=-Math.abs(ball.vx);sound(260,.035)}if(ball.y<ball.r+12){ball.y=ball.r+12;ball.vy=Math.abs(ball.vy);sound(260,.035)}if(ball.vy>0&&ball.y+ball.r>=paddle.y-paddle.h/2&&ball.y-ball.r<=paddle.y+paddle.h/2&&ball.x>=paddle.x-paddle.w/2-ball.r&&ball.x<=paddle.x+paddle.w/2+ball.r){ball.y=paddle.y-paddle.h/2-ball.r;let hit=(ball.x-paddle.x)/(paddle.w/2);hit=Math.max(-.92,Math.min(.92,hit));let angle=hit*1.05;ball.vx=Math.sin(angle)*ball.speed;ball.vy=-Math.cos(angle)*ball.speed;sound(350+Math.abs(hit)*230,.07,'sine');burst(ball.x,ball.y,'#53f6e5',5,100);combo=1;comboTimer=1}for(const b of bricks){if(!b.alive)continue;let nx=Math.max(b.x,Math.min(ball.x,b.x+b.w)),ny=Math.max(b.y,Math.min(ball.y,b.y+b.h)),dx=ball.x-nx,dy=ball.y-ny;if(dx*dx+dy*dy<=ball.r*ball.r){let prevX=ox,prevY=oy;if(prevY+ball.r<=b.y||prevY-ball.r>=b.y+b.h)ball.vy*=-1;else if(prevX+ball.r<=b.x||prevX-ball.r>=b.x+b.w)ball.vx*=-1;else ball.vy*=-1;b.hp--;burst(ball.x,ball.y,b.color,b.hp?5:12,b.hp?90:170);sound(b.hp?500:680,.055,b.hp?'sine':'triangle');if(!b.hp){b.alive=false;combo=Math.min(combo+1,9);comboTimer=1.8;addScore(10*combo,b.x+b.w/2,b.y);flash=.07}else addScore(5,b.x+b.w/2,b.y);screenShake=Math.max(screenShake,b.hp?1.5:3);break}}if(ball.y>H+ball.r){loseLife();break}}if(state==='playing'&&bricks.every(b=>!b.alive))nextLevel();if(comboTimer>0){comboTimer-=dt;if(comboTimer<=0)combo=1;updateUI()}}}for(let i=particles.length-1;i>=0;i--){let p=particles[i];p.x+=p.vx*dt;p.y+=p.vy*dt;p.vx*=Math.pow(.12,dt);p.vy=p.vy*Math.pow(.12,dt)+45*dt;p.life-=dt;if(p.life<=0)particles.splice(i,1)}screenShake=Math.max(0,screenShake-dt*28);flash=Math.max(0,flash-dt*1.7)}function frame(t){let dt=Math.min((t-last)/1000||0,.033);last=t;update(dt);draw();requestAnimationFrame(frame)}buildLevel();updateUI();requestAnimationFrame(frame)
})();
</script>
</body>
</html>

