Models 44

GPT-6 Luna

by OpenAIReasoningClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
43.2 s
Cost
$0.0020
Output tokens
3,923
Spent thinking
242 tokens
Speed
157.6 tok/s
Console errors
0
First token after
18.3 s
First visible text after
20.9 s
Prompt tokens
357
Code size
10.3 KB
Finish reason
stop
Served by
OpenAI
Model id
openai/gpt-6-luna
Reasoning sent
{"effort":"low"}
Max output
64,000 tokens
Generated
Nov 10, 2026

What it was asked

The prompt
“i want a breakout game where the paddle is a hamburger and every brick you break explodes into tons of little hearts”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 261 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Heartbreaker — Burger Breakout</title>
<style>
  :root { color-scheme: dark; }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    min-height: 100vh;
    background:
      radial-gradient(ellipse at 50% 42%, rgba(112, 40, 62, .24), transparent 56%),
      #100d13;
    color: #fff5ec;
    font-family: ui-rounded, "Trebuchet MS", system-ui, sans-serif;
    display: flex;
    justify-content: center;
    overflow-x: hidden;
  }
  .page {
    width: min(1120px, calc(100% - 48px));
    padding: 32px 0 22px;
  }
  header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0 4px 20px;
  }
  .brand { display: flex; align-items: center; gap: 13px; }
  .brand-mark {
    width: 46px; height: 46px; display: grid; place-items: center;
    border-radius: 15px; font-size: 25px;
    background: linear-gradient(145deg, #ffb34d, #f45c62);
    box-shadow: 0 7px 25px #ff6a4e35;
  }
  h1 { margin: 0; font-size: clamp(22px, 3vw, 30px); letter-spacing: -.8px; }
  .subtitle { color: #a89aa4; font-size: 12px; margin-top: 3px; letter-spacing: .12em; text-transform: uppercase; }
  .stats { display: flex; gap: 10px; }
  .stat {
    min-width: 104px; padding: 9px 14px; border: 1px solid #ffffff12;
    background: #ffffff08; border-radius: 12px;
  }
  .stat small { display: block; color: #958995; font-size: 10px; letter-spacing: .13em; }
  .stat strong { display: block; font-size: 18px; margin-top: 2px; font-variant-numeric: tabular-nums; }
  .stat strong.pink { color: #ff7894; }
  .game-shell {
    position: relative; padding: 10px; border-radius: 21px;
    background: linear-gradient(135deg, #ffffff16, #ffffff05);
    border: 1px solid #ffffff15; box-shadow: 0 24px 80px #0008;
  }
  canvas {
    display: block; width: 100%; aspect-ratio: 1000 / 600;
    border-radius: 13px; background: #18121b;
  }
  .hint {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    padding: 10px 16px; border: 1px solid #ffffff24; border-radius: 999px;
    color: #fff4ea; background: #160f19c9; backdrop-filter: blur(8px);
    font-size: 13px; white-space: nowrap; pointer-events: none;
    box-shadow: 0 5px 30px #0006;
  }
  .hint b { color: #ff9a9f; font-weight: 700; }
  footer {
    display: flex; justify-content: space-between; align-items: center;
    color: #8f818d; padding: 14px 5px 0; font-size: 12px;
  }
  footer span:last-child { color: #c7a8b2; }
  @media (max-width: 600px) {
    .page { width: calc(100% - 24px); padding-top: 20px; }
    header { align-items: flex-start; margin-bottom: 14px; gap: 8px; }
    .brand { gap: 9px; }
    .brand-mark { width: 38px; height: 38px; border-radius: 12px; font-size: 21px; }
    .subtitle { font-size: 9px; letter-spacing: .08em; }
    .stats { gap: 5px; }
    .stat { min-width: 62px; padding: 7px 8px; }
    .stat small { font-size: 8px; }
    .stat strong { font-size: 15px; }
    .game-shell { padding: 6px; border-radius: 15px; }
    canvas { border-radius: 10px; }
    footer { font-size: 10px; }
    .hint { font-size: 11px; padding: 8px 12px; }
  }
</style>
</head>
<body>
<main class="page">
  <header>
    <div class="brand">
      <div class="brand-mark">🍔</div>
      <div>
        <h1>Heartbreaker</h1>
        <div class="subtitle">A very smashable love story</div>
      </div>
    </div>
    <div class="stats">
      <div class="stat"><small>SCORE</small><strong id="score">00000</strong></div>
      <div class="stat"><small>HEARTS</small><strong class="pink" id="hearts">∞</strong></div>
    </div>
  </header>
  <div class="game-shell">
    <canvas id="game" width="1000" height="600" aria-label="Breakout game"></canvas>
    <div class="hint" id="hint"><b>Click or press a key</b> to take the spatula</div>
  </div>
  <footer>
    <span>Move with ← → or your mouse</span>
    <span>Break a brick. Make it rain hearts. ♥</span>
  </footer>
</main>
<script>
(() => {
  const canvas = document.getElementById('game');
  const ctx = canvas.getContext('2d');
  const scoreEl = document.getElementById('score');
  const hint = document.getElementById('hint');
  const W = 1000, H = 600;
  const colors = ['#ff7187', '#ff9b66', '#ffd064', '#bd8cff', '#68d7d0'];
  let bricks = [], particles = [], score = 0, running = false, mouseX = W / 2;
  const paddle = { x: W / 2, y: 548, w: 112, h: 30 };
  const ball = { x: W / 2, y: 430, vx: 4.1, vy: -5.4, r: 9 };
  const keys = {};
  function makeBricks() {
    bricks = [];
    const cols = 10, rows = 5, bw = 82, bh = 25, gap = 9;
    const left = (W - (cols * bw + (cols - 1) * gap)) / 2;
    for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) {
      bricks.push({ x: left + c * (bw + gap), y: 94 + r * (bh + gap), w: bw, h: bh, color: colors[r], alive: true });
    }
  }
  makeBricks();

  function heart(x, y, size, color, alpha = 1) {
    ctx.save(); ctx.translate(x, y); ctx.scale(size / 18, size / 18);
    ctx.globalAlpha = alpha; ctx.fillStyle = color;
    ctx.beginPath(); ctx.moveTo(0, 7);
    ctx.bezierCurveTo(-19, -5, -10, -15, 0, -7);
    ctx.bezierCurveTo(10, -15, 19, -5, 0, 7);
    ctx.fill(); ctx.restore();
  }
  function burst(x, y, color) {
    for (let i = 0; i < 27; i++) {
      const a = Math.random() * Math.PI * 2, speed = 1.2 + Math.random() * 5;
      particles.push({
        x, y, vx: Math.cos(a) * speed, vy: Math.sin(a) * speed - 1.2,
        size: 7 + Math.random() * 11, color: Math.random() < .26 ? '#fff0e7' : color,
        life: 55 + Math.random() * 40, max: 95, spin: (Math.random() - .5) * .12
      });
    }
  }
  function roundRect(x, y, w, h, r, fill) {
    ctx.fillStyle = fill; ctx.beginPath(); ctx.roundRect(x, y, w, h, r); ctx.fill();
  }
  function drawBurger() {
    const x = paddle.x - paddle.w / 2, y = paddle.y;
    ctx.save();
    ctx.shadowColor = '#ff9b49'; ctx.shadowBlur = 17;
    // bottom bun
    roundRect(x, y + 17, paddle.w, 12, 7, '#c97932');
    // lettuce
    ctx.fillStyle = '#60c96a'; ctx.beginPath();
    ctx.moveTo(x + 3, y + 17);
    for (let i = 0; i <= 9; i++) ctx.lineTo(x + i * 12, y + (i % 2 ? 20 : 14));
    ctx.lineTo(x + paddle.w - 2, y + 20); ctx.lineTo(x + 2, y + 20); ctx.fill();
    // patty
    roundRect(x + 5, y + 10, paddle.w - 10, 9, 4, '#75402f');
    // cheese
    ctx.fillStyle = '#ffc94f'; ctx.beginPath();
    ctx.moveTo(x + 13, y + 9); ctx.lineTo(x + paddle.w - 5, y + 9);
    ctx.lineTo(x + paddle.w - 15, y + 17); ctx.lineTo(x + 22, y + 15); ctx.fill();
    // bun top
    ctx.fillStyle = '#f5a94e'; ctx.beginPath();
    ctx.ellipse(paddle.x, y + 9, paddle.w / 2, 12, 0, Math.PI, 0); ctx.fill();
    ctx.fillRect(x, y + 8, paddle.w, 5);
    ctx.fillStyle = '#ffe2a1';
    [[-25,5],[-9,2],[10,5],[28,2]].forEach(([dx,dy]) => {
      ctx.beginPath(); ctx.ellipse(paddle.x + dx, y + dy, 2.2, 1, -.3, 0, Math.PI * 2); ctx.fill();
    });
    ctx.restore();
  }
  function draw() {
    ctx.clearRect(0, 0, W, H);
    const bg = ctx.createLinearGradient(0, 0, 0, H);
    bg.addColorStop(0, '#211522'); bg.addColorStop(1, '#15121b');
    ctx.fillStyle = bg; ctx.fillRect(0, 0, W, H);
    // soft background glow
    const glow = ctx.createRadialGradient(W/2, 250, 30, W/2, 250, 470);
    glow.addColorStop(0, '#59243a33'); glow.addColorStop(1, '#59243a00');
    ctx.fillStyle = glow; ctx.fillRect(0, 0, W, H);
    ctx.strokeStyle = '#ffffff0a'; ctx.lineWidth = 1;
    for (let x = 32; x < W; x += 48) { ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, H); ctx.stroke(); }
    bricks.forEach(b => {
      if (!b.alive) return;
      ctx.shadowColor = b.color; ctx.shadowBlur = 12;
      roundRect(b.x, b.y, b.w, b.h, 7, b.color);
      ctx.shadowBlur = 0;
      roundRect(b.x + 3, b.y + 3, b.w - 6, 5, 3, '#ffffff38');
      heart(b.x + b.w/2, b.y + b.h/2 + 1, 11, '#fff4e7', .85);
    });
    particles.forEach(p => heart(p.x, p.y, p.size, p.color, Math.min(1, p.life / 18)));
    // ball
    ctx.shadowColor = '#fff1b0'; ctx.shadowBlur = 18;
    ctx.fillStyle = '#fff2c5'; ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2); ctx.fill();
    ctx.shadowBlur = 0;
    drawBurger();
  }
  function update() {
    if (running) {
      let target = ball.x;
      if (keys.ArrowLeft || keys.a) target = paddle.x - 9;
      if (keys.ArrowRight || keys.d) target = paddle.x + 9;
      if (Math.abs(mouseX - W/2) > 1 && !keys.ArrowLeft && !keys.ArrowRight && !keys.a && !keys.d) target = mouseX;
      paddle.x += (target - paddle.x) * .17;
      paddle.x = Math.max(paddle.w/2 + 8, Math.min(W - paddle.w/2 - 8, paddle.x));
      ball.x += ball.vx; ball.y += ball.vy;
      if (ball.x < ball.r || ball.x > W - ball.r) ball.vx *= -1;
      if (ball.y < 26) ball.vy = Math.abs(ball.vy);
      if (ball.vy > 0 && ball.y + ball.r >= paddle.y && ball.y < paddle.y + 35 &&
          ball.x > paddle.x - paddle.w/2 && ball.x < paddle.x + paddle.w/2) {
        ball.vy = -Math.abs(ball.vy);
        ball.vx = ((ball.x - paddle.x) / (paddle.w/2)) * 5.2;
        ball.y = paddle.y - ball.r;
      }
      if (ball.y > H + 20) { ball.x = paddle.x; ball.y = 440; ball.vy = -5.4; }
      for (const b of bricks) {
        if (!b.alive) continue;
        if (ball.x + ball.r > b.x && ball.x - ball.r < b.x + b.w &&
            ball.y + ball.r > b.y && ball.y - ball.r < b.y + b.h) {
          b.alive = false; ball.vy *= -1; score += 100;
          scoreEl.textContent = String(score).padStart(5, '0');
          burst(b.x + b.w/2, b.y + b.h/2, b.color);
          break;
        }
      }
      if (bricks.every(b => !b.alive)) makeBricks();
    }
    particles = particles.filter(p => p.life-- > 0);
    particles.forEach(p => { p.x += p.vx; p.y += p.vy; p.vy += .055; p.vx *= .992; });
    draw();
    requestAnimationFrame(update);
  }
  function start() { if (!running) { running = true; hint.style.display = 'none'; } }
  canvas.addEventListener('pointermove', e => {
    const r = canvas.getBoundingClientRect();
    mouseX = (e.clientX - r.left) / r.width * W;
    if (e.buttons) start();
  });
  canvas.addEventListener('pointerdown', start);
  window.addEventListener('keydown', e => {
    if (['ArrowLeft','ArrowRight',' '].includes(e.key)) e.preventDefault();
    keys[e.key] = true; start();
  });
  window.addEventListener('keyup', e => { keys[e.key] = false; });
  // The demo is already in motion; the prompt invites the viewer to take control.
  running = true;
  update();
})();
</script>
</body>
</html>
Reasoning trace (242 tokens)
**Producing a game demo**

I need to create an HTML polished game demo that's self-playing and demonstrates actions effectively. It’ll include animations on a canvas, featuring elements like a hamburger paddle, brick explosions, and a landscape that's 1280x800 and responsive. The game should start with a self-play demo overlay that instructs the user to click or press start. I’ll ensure clear visuals, including crisp drawings for bricks, the paddle, heart-shaped particles, and proper physics for a smooth experience. I'll aim for a stylish render.**Setting up canvas dimensions**

I need to set up the canvas to fill a container of 1000x600 while maintaining the aspect ratio using CSS. The main page should be designed to fit a 1280x800 layout, ensuring that both header and footer are included. This will create a clean and responsive design for the game demo, allowing for the canvas to adapt dynamically within the overall page structure. It’s important to keep everything aligned and visually appealing!