Nemotron 3.5 Lightning (free)
by NVIDIAReasoning1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 1 min 1 s
- Cost
- $0
- Output tokens
- 4,479
- Spent thinking
- 0 tokens
- Speed
- 73.2 tok/s
- Console errors
- 1
- First token after
- 286 ms
- First visible text after
- 286 ms
- Prompt tokens
- 531
- Code size
- 14.7 KB
- Finish reason
- stop
- Served by
- Nvidia
- Model id
nvidia/nemotron-3.5-lightning:free- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 9, 2026
Console errors
Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.
Identifier 'paddleWidth' has already been declared
What it was asked
The prompt
Build a polished Breakout (brick breaker) game in a single HTML file using vanilla JavaScript and a <canvas>. Requirements: - A paddle controlled with the mouse and with the left/right arrow keys. - The bounce angle off the paddle depends on where the ball hits it (center = straight up, edges = sharp angle). - One level with at least 6 rows of bricks, mixing normal bricks and tougher bricks that need 2 hits and visibly crack after the first one. - Some bricks visibly carry a power-up icon; when broken they drop it, and catching it with the paddle gives either a wider paddle (10 seconds) or multi-ball (3 balls). - The ball must never pass through bricks or the paddle. - Particles when a brick breaks. - 3 lives, score displayed. Game over and victory screens with a restart option.
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 · 372 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Breakout</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; background: #1a1a2e; }
canvas { display: block; }
#ui { position: absolute; top: 10px; left: 10px; right: 10px; display: flex; justify-content: space-between; align-items: flex-start; color: #e0e0e0; font-family: 'Segoe UI', system-ui, sans-serif; pointer-events: none; }
#ui > div { pointer-events: auto; }
#score { font-size: 1rem; }
#lives { font-size: 1rem; color: #ff5f57; }
#highscore { font-size: 0.8rem; color: #a0a0a0; }
#title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #e0e0e0; font-family: 'Segoe UI', system-ui, sans-serif; font-size: 2rem; text-align: center; pointer-events: none; }
#screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #1a1a2e; display: none; align-items: center; justify-content: center; flex-direction: column; gap: 1rem; pointer-events: auto; }
#screen.active { display: flex; }
button { background: #e94560; color: white; border: none; padding: 0.8rem 1.5rem; font-size: 1rem; cursor: pointer; border-radius: 4px; transition: background 0.2s; font-family: inherit; }
button:hover { background: #ff6b8a; }
button:focus { outline: 2px solid #fff; outline-offset: 2px; }
#start { top: 40%; }
#gameover { top: 40%; }
#victory { top: 40%; }
.powerup { position: absolute; width: 20px; height: 20px; border-radius: 3px; pointer-events: none; }
.powerup.fire { background: #ffd700; box-shadow: 0 0 8px #ffd700; }
.powerup.multi { background: #00bfff; box-shadow: 0 0 8px #00bfff; }
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="ui">
<div>
<span id="score">Score: 0</span>
<span id="highscore">High: 0</span>
</div>
<div>
<span id="lives">Lives: 3</span>
</div>
</div>
<div id="title">Breakout</div>
<div id="screen" class="start" role="dialog">
<button id="startBtn">Click or press a key to start</button>
</div>
<div id="screen" class="gameover" role="dialog">
<span>Game Over</span>
<button id="restartBtn">Restart</button>
</div>
<div id="screen" class="victory" role="dialog">
<span>Victory!</span>
<button id="restartBtn">Play Again</button>
</div>
<script>
(() => {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
const livesEl = document.getElementById('lives');
const highscoreEl = document.getElementById('highscore');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const screens = document.querySelectorAll('#screen');
let W, H, paddleWidth, paddleHeight, brickRowCount = 6, brickColumnCount, brickWidth, brickHeight, brickPadding, brickOffsetTop, brickOffsetLeft, score = 0, highScore = parseInt(localStorage.getItem('breakoutHigh') || '0'), lives = 3, gameState = 'title', keys = { left: false, right: false }, particles = [], powerUps = [], balls = [], activePowerUp = null, powerUpTimer = 0;
function resize() {
const maxW = 1280, maxH = 800;
let cW = window.innerWidth, cH = window.innerHeight;
if (cW > maxW) cW = maxW;
if (cH > maxH) cH = maxH;
const ratio = Math.min(cW / maxW, cH / maxH);
W = Math.floor(800 * ratio);
H = Math.floor(450 * ratio);
canvas.width = W;
canvas.height = H;
initGame();
}
window.addEventListener('resize', resize);
resize();
const bricks = [];
function initBricks() {
bricks.length = 0;
brickColumnCount = Math.floor((W - 40) / (brickWidth + brickPadding)) || 1;
brickRowCount = Math.min(brickRowCount, Math.floor((H - 80) / (brickHeight + brickPadding)) || 1);
brickWidth = (W - 40 - (brickColumnCount - 1) * brickPadding) / brickColumnCount;
brickHeight = 20;
brickPadding = 4;
brickOffsetTop = 50;
brickOffsetLeft = 20;
for (let c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (let r = 0; r < brickRowCount; r++) {
const hitCount = (r % 2 === 0) ? 1 : 2;
bricks[c][r] = { x: 0, y: 0, status: hitCount, hit: 0, type: hitCount > 1 ? 'tough' : 'normal' };
}
}
}
function drawBricks() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status <= 0) continue;
const b = bricks[c][r];
const x = c * (brickWidth + brickPadding) + brickOffsetLeft;
const y = r * (brickHeight + brickPadding) + brickOffsetTop;
ctx.fillStyle = b.type === 'tough' ? '#ff6b6b' : '#ffa3a3';
ctx.shadowColor = '#ff6b6b';
ctx.shadowBlur = 8;
ctx.fillRect(x, y, brickWidth, brickHeight);
ctx.shadowBlur = 0;
// power-up icon
if (Math.random() < 0.2 && b.status === b.hitCount) {
const icons = ['fire', 'multi'];
const icon = icons[Math.floor(Math.random() * icons.length)];
const ix = x + brickWidth / 2 - 5;
const iy = y + brickHeight / 2 - 5;
powerUps.push({ x: ix, y: iy, type: icon, width: 10, height: 10 });
}
// crack after first hit on tough bricks
if (b.type === 'tough' && b.hit >= 1) {
ctx.strokeStyle = 'rgba(255,255,255,0.3)';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(x + 4, y + 4);
ctx.lineTo(x + brickWidth - 4, y + brickHeight - 4);
ctx.moveTo(x + brickWidth - 4, y + 4);
ctx.lineTo(x + 4, y + brickHeight - 4);
ctx.stroke();
}
}
}
}
function drawPaddle() {
ctx.fillStyle = '#4ecdc4';
ctx.shadowColor = '#4ecdc4';
ctx.shadowBlur = 12;
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
ctx.shadowBlur = 0;
}
let paddleX = (W - 150) / 2, paddleY = H - 30, paddleWidth = 150, paddleHeight = 12;
function drawBall(ball) {
ctx.fillStyle = ball.color;
ctx.shadowColor = ball.color;
ctx.shadowBlur = 15;
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
function drawParticles() {
particles.forEach(p => {
ctx.fillStyle = p.color;
ctx.globalAlpha = p.alpha;
ctx.fillRect(p.x, p.y, p.w, p.h);
p.alpha -= 0.02;
p.x += p.vx;
p.y += p.vy;
});
particles = particles.filter(p => p.alpha > 0);
ctx.globalAlpha = 1;
}
function drawPowerUps() {
powerUps.forEach(p => {
const color = p.type === 'fire' ? '#ffd700' : '#00bfff';
ctx.fillStyle = color;
ctx.shadowColor = color;
ctx.shadowBlur = 8;
ctx.fillRect(p.x, p.y, p.width, p.height);
ctx.shadowBlur = 0;
});
}
function draw() {
ctx.clearRect(0, 0, W, H);
drawBricks();
drawParticles();
drawPowerUps();
drawPaddle();
balls.forEach(b => drawBall(b));
// UI
ctx.fillStyle = '#e0e0e0';
ctx.font = '16px Segoe UI';
ctx.fillText(`Score: ${score}`, 20, 30);
ctx.fillText(`Lives: ${lives}`, W - 100, 30);
}
function spawnBall(x, y, vx, vy, color = '#ffd700') {
balls.push({ x, y, r: 8, vx, vy, color, launched: false });
}
let ballX, ballY, ballVX, ballVY;
spawnBall(W / 2, H / 2, 3, -3);
function collisionDetection() {
// paddle
for (const ball of balls) {
if (ball.launched) {
if (ball.y + ball.r > paddleY && ball.y - ball.r < paddleY + paddleHeight && ball.x > paddleX && ball.x < paddleX + paddleWidth) {
const hitPos = (ball.x - paddleX) / paddleWidth;
const angle = (hitPos - 0.5) * Math.PI / 3;
ball.vx = Math.cos(angle) * 4;
ball.vy = -Math.sin(angle) * 4;
if (Math.abs(ball.vx) < 2) ball.vx = 2 * (ball.vx > 0 ? 1 : -1);
}
if (ball.y + ball.r > H) {
lives--;
livesEl.textContent = `Lives: ${lives}`;
if (lives <= 0) gameOver();
else {
ball.launched = false;
ballX = paddleX + paddleWidth / 2;
ballY = paddleY - 8;
}
}
// bricks
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status <= 0) continue;
const b = bricks[c][r];
const x = c * (brickWidth + brickPadding) + brickOffsetLeft;
const y = r * (brickHeight + brickPadding) + brickOffsetTop;
if (ball.x + ball.r > x && ball.x - ball.r < x + brickWidth && ball.y + ball.r > y && ball.y - ball.r < y + brickHeight) {
ball.vy = -ball.vy;
b.hit++;
b.status--;
// particles
for (let i = 0; i < 15; i++) {
particles.push({ x: b.x + brickWidth / 2, y: b.y + brickHeight / 2, w: 4, h: 4, color: b.type === 'tough' ? '#ff6b6b' : '#ffa3a3', alpha: 1, vx: (Math.random() - 0.5) * 6, vy: (Math.random() - 0.5) * 6 });
}
// power-up drop
if (Math.random() < 0.3 && b.type === 'normal') {
const puType = Math.random() < 0.5 ? 'fire' : 'multi';
powerUps.push({ x: b.x + brickWidth / 2 - 5, y: b.y + brickHeight / 2 - 5, type: puType, width: 10, height: 10 });
}
if (b.status <= 0) {
score += 10;
scoreEl.textContent = `Score: ${score}`;
}
break;
}
}
}
}
}
// power-up catch
powerUps.forEach((pu, pi) => {
for (const ball of balls) {
if (ball.launched && ball.x > pu.x && ball.x < pu.x + pu.width && ball.y + ball.r > pu.y && ball.y - ball.r < pu.y + pu.height) {
if (pu.type === 'fire') {
paddleWidth = Math.min(paddleWidth + 30, 300);
powerUpTimer = 1000;
activePowerUp = 'wide';
} else if (pu.type === 'multi') {
// add two extra balls
const b1 = { x: ball.x, y: ball.y, r: 8, vx: ball.vx + (Math.random() - 0.5) * 2, vy: ball.vy, color: '#ffd700', launched: true };
const b2 = { x: ball.x, y: ball.y, r: 8, vx: ball.vx - (Math.random() - 0.5) * 2, vy: ball.vy, color: '#ffd700', launched: true };
balls.push(b1, b2);
}
powerUps.splice(pi, 1);
}
}
});
// wall collisions
for (const ball of balls) {
if (ball.x + ball.r > W - 20) { ball.vx = -Math.abs(ball.vx); ball.x = W - 20 - ball.r; }
if (ball.x - ball.r < 20) { ball.vx = Math.abs(ball.vx); ball.x = 20 + ball.r; }
if (ball.y - ball.r < 20) { ball.vy = Math.abs(ball.vy); ball.y = 20 + ball.r; }
}
}
function gameLoop() {
if (gameState !== 'play') return;
// power-up timer
if (activePowerUp) {
powerUpTimer -= 16;
if (powerUpTimer <= 0) {
paddleWidth = Math.max(paddleWidth - 30, 150);
activePowerUp = null;
}
}
// move paddle with keys
if (keys.left) paddleX = Math.max(20, paddleX - 5);
if (keys.right) paddleX = Math.min(W - paddleWidth - 20, paddleX + 5);
// mouse
document.addEventListener('mousemove', e => {
const rect = canvas.getBoundingClientRect();
const mouseX = e.clientX - rect.left - canvas.clientLeft;
paddleX = mouseX - paddleWidth / 2;
paddleX = Math.max(20, Math.min(W - paddleWidth - 20, paddleX));
});
// move balls
balls.forEach(ball => {
if (!ball.launched) {
ball.x = paddleX + paddleWidth / 2;
ball.y = paddleY - ball.r;
if (gameState === 'play') ball.launched = true;
} else {
ball.x += ball.vx;
ball.y += ball.vy;
}
});
collisionDetection();
draw();
requestAnimationFrame(gameLoop);
}
function startGame() {
gameState = 'play';
lives = 3;
score = 0;
livesEl.textContent = `Lives: ${lives}`;
scoreEl.textContent = `Score: ${score}`;
initBricks();
balls.length = 0;
powerUps.length = 0;
particles.length = 0;
paddleWidth = 150;
activePowerUp = null;
powerUpTimer = 0;
balls.push({ x: W / 2, y: H / 2, r: 8, vx: 3, vy: -3, color: '#ffd700', launched: false });
gameScreen('none');
}
function gameOver() {
gameState = 'over';
highScore = Math.max(score, highScore);
localStorage.setItem('breakoutHigh', highScore);
highscoreEl.textContent = `High: ${highScore}`;
gameScreen('flex');
}
function victory() {
gameState = 'win';
highScore = Math.max(score, highScore);
localStorage.setItem('breakoutHigh', highScore);
highscoreEl.textContent = `High: ${highScore}`;
gameScreen('flex');
}
function gameScreen(display) {
screens.forEach(s => s.style.display = 'none');
document.getElementById(gameState === 'over' ? 'gameover' : gameState === 'win' ? 'victory' : 'start').style.display = display;
}
// events
startBtn.addEventListener('click', () => { startGame(); });
restartBtn.addEventListener('click', startGame);
document.addEventListener('keydown', e => {
if (e.key === 'ArrowLeft') keys.left = true;
if (e.key === 'ArrowRight') keys.right = true;
if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); if (gameState === 'title') startGame(); }
});
document.addEventListener('keyup', e => {
if (e.key === 'ArrowLeft') keys.left = false;
if (e.key === 'ArrowRight') keys.right = false;
});
// init
let brickWidth, brickHeight, brickPadding;
initBricks();
gameLoop();
})();
</script>
</body>
</html>