Models 44

Nemotron 3 Nano Omni (free)

by NVIDIAReasoning1 console error
Open in new window

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

How it went

Total time
42.8 s
Cost
$0
Output tokens
4,221
Spent thinking
0 tokens
Speed
99.5 tok/s
Console errors
1
First token after
364 ms
First visible text after
364 ms
Prompt tokens
531
Code size
18.0 KB
Finish reason
stop
Served by
Nvidia
Model id
nvidia/nemotron-3-nano-omni-30b-a3b-reasoning: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 'showParticles' 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 · 515 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Breakout Demo</title>
    <style>
        body { 
            margin: 0; 
            overflow: hidden; 
            background: #111; 
            display: flex; 
            justify-content: center; 
            align-items: center; 
            height: 100vh; 
            font-family: Arial, sans-serif; 
            color: #fff; 
        }
        canvas { 
            background: #000; 
            border: 2px solid #555; 
        }
        #overlay { 
            position: absolute; 
            top: 0; 
            left: 0; 
            width: 100%; 
            height: 100%; 
            display: flex; 
            flex-direction: column; 
            justify-content: center; 
            align-items: center; 
            pointer-events: none; 
            font-size: 24px; 
        }
        #start-btn { 
            margin-top: 20px; 
            padding: 10px 20px; 
            font-size: 18px; 
            background: #333; 
            color: #fff; 
            border: 1px solid #555; 
            cursor: pointer; 
        }
        #game-over, #victory { 
            position: absolute; 
            top: 0; 
            left: 0; 
            width: 100%; 
            height: 100%; 
            display: flex; 
            flex-direction: column; 
            justify-content: center; 
            align-items: center; 
            pointer-events: all; 
            font-size: 36px; 
            background: rgba(0,0,0,0.8); 
            color: #fff; 
        }
        #restart { 
            margin-top: 20px; 
            padding: 10px 20px; 
            font-size: 18px; 
            background: #333; 
            color: #fff; 
            border: 1px solid #555; 
            cursor: pointer; 
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="800" height="600"></canvas>
    <div id="overlay">
        <div id="start-btn">Click or press a key to start</div>
    </div>
    <div id="game-over" style="display:none;">Game Over<br><div id="restart">Restart</div></div>
    <div id="victory" style="display:none;">Victory!<br><div id="restart2">Restart</div></div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const overlay = document.getElementById('overlay');
        const startBtn = document.getElementById('start-btn');
        const gameOverOverlay = document.getElementById('game-over');
        const victoryOverlay = document.getElementById('victory');
        const restartBtn = document.getElementById('restart');
        const restartBtn2 = document.getElementById('restart2');

        const paddle = {
            width: 100,
            height: 20,
            x: 0,
            y: canvas.height - 30,
            speed: 8,
            dx: 0
        };

        const ball = {
            radius: 10,
            x: canvas.width / 2,
            y: canvas.height / 2,
            dx: 5,
            dy: 5,
            speed: 5
        };

        let bricks = [];
        let brickRowCount = 6;
        let brickColumnCount = 10;
        let brickWidth = 70;
        let brickHeight = 20;
        let brickPadding = 10;
        let brickOffsetTop = 70;
        let brickOffsetLeft = 30;
        let score = 0;
        let lives = 3;
        let gameRunning = false;
        let showParticles = false;
        let particles = [];
        let powerUps = [];
        let powerUpTimer = 0;
        let powerUpActive = false;
        let powerUpType = null;
        let powerUpDuration = 0;
        let particlesTimer = 0;

        // Create bricks with varying toughness
        for (let r = 0; r < brickRowCount; r++) {
            bricks[r] = [];
            for (let c = 0; c < brickColumnCount; c++) {
                const isTough = Math.random() < 0.3; // 30% tough bricks
                bricks[r][c] = { 
                    x: (c * (brickWidth + brickPadding)) + brickOffsetLeft,
                    y: (r * (brickHeight + brickPadding)) + brickOffsetTop,
                    status: isTough ? 2 : 1, // 2 = needs 2 hits, 1 = normal
                    cracked: false
                };
            }
        }

        function resetGame() {
            // Reset paddle
            paddle.x = (canvas.width - paddle.width) / 2;
            paddle.dx = 0;

            // Reset ball
            ball.x = canvas.width / 2;
            ball.y = canvas.height / 2;
            ball.dx = 5 * (Math.random() > 0.5 ? 1 : -1);
            ball.dy = 5;

            // Reset bricks
            for (let r = 0; r < brickRowCount; r++) {
                for (let c = 0; c < brickColumnCount; c++) {
                    bricks[r][c].status = isTough ? 2 : 1;
                    bricks[r][c].cracked = false;
                }
            }

            // Reset score, lives
            score = 0;
            lives = 3;

            // Clear particles and power-ups
            particles = [];
            powerUps = [];
            powerUpTimer = 0;
            powerUpActive = false;
            powerUpType = null;
            powerUpDuration = 0;

            // Hide overlays
            gameOverOverlay.style.display = 'none';
            victoryOverlay.style.display = 'none';
            overlay.style.display = 'flex';
            startBtn.style.display = 'block';
        }

        function drawPaddle() {
            ctx.fillStyle = '#0f0';
            ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
        }

        function drawBall() {
            ctx.beginPath();
            ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
            ctx.fillStyle = '#ff0';
            ctx.fill();
            ctx.closePath();
        }

        function drawBricks() {
            for (let r = 0; r < brickRowCount; r++) {
                for (let c = 0; c < brickColumnCount; c++) {
                    const brick = bricks[r][c];
                    if (brick.status > 0) {
                        ctx.fillStyle = brick.status === 2 && !brick.cracked ? '#a0522d' : '#8b4513';
                        ctx.fillRect(brick.x, brick.y, brickWidth, brickHeight);

                        // Draw crack if tough brick has been hit once
                        if (brick.status === 2 && brick.cracked) {
                            ctx.fillStyle = '#fff';
                            ctx.beginPath();
                            ctx.moveTo(brick.x, brick.y);
                            ctx.lineTo(brick.x + brickWidth, brick.y + brickHeight);
                            ctx.stroke();
                        }
                    }
                }
            }
        }

        function drawParticles() {
            particles.forEach((p, index) => {
                ctx.fillStyle = `rgba(255, 255, 255, ${p.alpha})`;
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
                ctx.fill();
                ctx.closePath();
                particles[index].alpha -= 0.02;
                if (particles[index].alpha <= 0) {
                    particles.splice(index, 1);
                }
            });
        }

        function drawPowerUps() {
            powerUps.forEach((pu, index) => {
                ctx.fillStyle = pu.type === 'wider' ? '#0f0' : '#ff0';
                ctx.beginPath();
                ctx.arc(pu.x, pu.y, 8, 0, Math.PI * 2);
                ctx.fill();
                ctx.closePath();
            });
        }

        function update() {
            // Move paddle
            if (paddle.dx !== 0) {
                paddle.x += paddle.dx;
                // Keep paddle on screen
                if (paddle.x < 0) paddle.x = 0;
                if (paddle.x + paddle.width > canvas.width) paddle.x = canvas.width - paddle.width;
            }

            // Move ball
            ball.x += ball.dx;
            ball.y += ball.dy;

            // Wall collisions
            if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) {
                ball.dx = -ball.dx;
            }
            if (ball.y - ball.radius < 0) {
                ball.dy = -ball.dy;
            }

            // Paddle collision
            if (ball.y + ball.radius > paddle.y && 
                ball.x > paddle.x && 
                ball.x < paddle.x + paddle.width) {
                
                // Calculate hit position relative to paddle center
                const paddleCenter = paddle.x + paddle.width / 2;
                const ballCenterX = ball.x;
                const hitPosition = (ballCenterX - paddleCenter) / (paddle.width / 2);
                
                // Set vertical velocity based on hit position
                ball.dy = -ball.speed * (1 + Math.abs(hitPosition));
                ball.dx = ball.speed * hitPosition;
                
                // Reset vertical speed if going down
                if (ball.dy > 0) ball.dy = -ball.dy;
            }

            // Brick collisions
            for (let r = 0; r < brickRowCount; r++) {
                for (let c = 0; c < brickColumnCount; c++) {
                    const brick = bricks[r][c];
                    if (brick.status > 0) {
                        if (ball.x + ball.radius > brick.x && 
                            ball.x - ball.radius < brick.x + brickWidth &&
                            ball.y - ball.radius < brick.y + brickHeight &&
                            ball.y + ball.radius > brick.y) {
                            
                            // Determine which side was hit
                            const ballLeft = ball.x - ball.radius;
                            const ballRight = ball.x + ball.radius;
                            const ballTop = ball.y - ball.radius;
                            const ballBottom = ball.y + ball.radius;
                            const brickTop = brick.y;
                            const brickBottom = brick.y + brickHeight;
                            const brickLeft = brick.x;
                            const brickRight = brick.x + brickWidth;

                            const hitVertical = (ballTop > brickTop && ballBottom < brickBottom);
                            const hitHorizontal = (ballLeft > brickLeft && ballRight < brickRight);

                            if (hitVertical && hitHorizontal) {
                                ball.dy = -ball.dy;
                            } else if (hitVertical) {
                                ball.dx = -ball.dx;
                            } else if (hitHorizontal) {
                                ball.dy = -ball.dy;
                            }

                            // Handle tough bricks
                            if (brick.status === 2) {
                                brick.cracked = true;
                                if (!brick.cracked) {
                                    // First hit: crack it but don't destroy
                                    score += 10;
                                    brick.status = 1; // Now acts as normal brick
                                }
                            } else {
                                // Normal brick
                                bricks[r][c].status = 0;
                                score += 100;
                                showParticles(brick.x + brickWidth / 2, brick.y + brickHeight / 2);
                            }
                            // Break out of loops
                            r = brickRowCount;
                            c = brickColumnCount;
                        }
                    }
                }
            }

            // Power-up collision
            for (let i = powerUps.length - 1; i >= 0; i--) {
                const pu = powerUps[i];
                if (ball.x + ball.radius > pu.x - 8 && 
                    ball.x - ball.radius < pu.x + 8 &&
                    ball.y + ball.radius > pu.y - 8 && 
                    ball.y - ball.radius < pu.y + 8) {
                    
                    // Apply power-up
                    if (pu.type === 'wider') {
                        paddle.width += 50;
                        powerUpActive = true;
                        powerUpType = 'wider';
                        powerUpDuration = 10 * 60; // 10 seconds at 60fps
                    } else if (pu.type === 'multi') {
                        // Multi-ball: create second ball
                        const newBall = {
                            x: ball.x,
                            y: ball.y + 10,
                            dx: ball.dx * 0.9,
                            dy: ball.dy * 0.9,
                            radius: ball.radius
                        };
                        // Add new ball to game (will be handled in next frame)
                        balls.push(newBall);
                    }
                    // Remove power-up
                    powerUps.splice(i, 1);
                    break;
                }
            }

            // Check if ball fell below paddle
            if (ball.y - ball.radius > canvas.height) {
                lives--;
                if (lives <= 0) {
                    gameRunning = false;
                    gameOverOverlay.style.display = 'flex';
                } else {
                    // Reset ball
                    ball.x = canvas.width / 2;
                    ball.y = canvas.height / 2;
                    ball.dx = 5 * (Math.random() > 0.5 ? 1 : -1);
                    ball.dy = 5;
                }
            }

            // Check for level completion
            let levelComplete = true;
            for (let r = 0; r < brickRowCount; r++) {
                for (let c = 0; c < brickColumnCount; c++) {
                    if (bricks[r][c].status > 0) {
                        levelComplete = false;
                        break;
                    }
                }
                if (!levelComplete) break;
            }

            if (levelComplete) {
                victoryOverlay.style.display = 'flex';
                gameRunning = false;
            }

            // Handle power-up timer
            if (powerUpActive) {
                powerUpTimer++;
                if (powerUpTimer >= powerUpDuration) {
                    // End power-up
                    powerUpActive = false;
                    powerUpTimer = 0;
                    if (powerUpType === 'wider') {
                        paddle.width = 100; // Reset to original
                    }
                }
            }

            // Spawn power-ups when bricks are broken
            for (let r = 0; r < brickRowCount; r++) {
                for (let c = 0; c < brickColumnCount; c++) {
                    const brick = bricks[r][c];
                    if (brick.status === 0 && Math.random() < 0.3) {
                        const type = Math.random() < 0.5 ? 'wider' : 'multi';
                        powerUps.push({
                            x: brick.x + brickWidth / 2,
                            y: brick.y + brickHeight / 2,
                            type: type,
                            collected: false
                        });
                    }
                }
            }

            // Update particles
            particlesTimer++;
            if (particlesTimer >= 5) { // Adjust as needed
                particlesTimer = 0;
                showParticles = false;
            }

            // Draw everything
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            drawPaddle();
            drawBall();
            drawBricks();
            drawParticles();
            drawPowerUps();

            // Draw score and lives
            ctx.fillStyle = '#fff';
            ctx.font = '16px Arial';
            ctx.fillText(`Score: ${score}`, 10, 20);
            ctx.fillText(`Lives: ${lives}`, 10, 40);

            // Check if game is running
            if (gameRunning) {
                requestAnimationFrame(update);
            }
        }

        function showParticles(x, y) {
            particles = [];
            const count = 10;
            for (let i = 0; i < count; i++) {
                particles.push({
                    x: x + (Math.random() - 0.5) * 20,
                    y: y + (Math.random() - 0.5) * 20,
                    radius: 2 + Math.random() * 3,
                    alpha: 1,
                    dx: (Math.random() - 0.5) * 4,
                    dy: (Math.random() - 0.5) * 4
                });
            }
            particlesTimer = 0;
            showParticles = true;
        }

        function startGame() {
            overlay.style.display = 'none';
            gameRunning = true;
            requestAnimationFrame(update);
        }

        startBtn.addEventListener('click', startGame);
        startBtn.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                startGame();
            }
        });

        restartBtn.addEventListener('click', resetGame);
        restartBtn2.addEventListener('click', resetGame);

        // Handle paddle movement with mouse
        canvas.addEventListener('mousemove', (e) => {
            if (gameRunning) {
                const rect = canvas.getBoundingClientRect();
                paddle.x = e.clientX - rect.left - paddle.width / 2;
                // Keep paddle on screen
                if (paddle.x < 0) paddle.x = 0;
                if (paddle.x + paddle.width > canvas.width) paddle.x = canvas.width - paddle.width;
            }
        });

        // Handle keyboard movement
        document.addEventListener('keydown', (e) => {
            if (!gameRunning) return;
            if (e.key === 'ArrowLeft') {
                paddle.dx = -paddle.speed;
            } else if (e.key === 'ArrowRight') {
                paddle.dx = paddle.speed;
            }
        });

        document.addEventListener('keyup', (e) => {
            if (!gameRunning) return;
            if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
                paddle.dx = 0;
            }
        });

        // Initialize game state
        resetGame();
    </script>
</body>
</html>