Models 44

Gemma 4 31B

by Googlereasoning default1 console error
Open in new window

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

How it went

Total time
22.3 s
Cost
$0.0009
Output tokens
2,456
Spent thinking
0 tokens
Speed
112.3 tok/s
Console errors
1
First token after
448 ms
First visible text after
448 ms
Prompt tokens
466
Code size
8.5 KB
Finish reason
stop
Served by
CoreWeave
Model id
google/gemma-4-31b-it
Reasoning sent
model default
Max output
16,384 tokens
Generated
Nov 13, 2026

Console errors

Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.

THREE.TriangleGeometry is not a constructor

What it was asked

The prompt
“a 3D aquarium with Three.js where the fish swim away when I move the mouse near them (Load Three.js only through this import map: <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>)”
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 · 236 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Interactive Aquarium</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background-color: #001b3d;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        #ui {
            position: absolute;
            top: 20px;
            left: 20px;
            color: white;
            pointer-events: none;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
        }
        .instruction {
            font-size: 1.2rem;
            opacity: 0.8;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <div id="ui">
        <h1>Digital Aquarium</h1>
        <p class="instruction">Move your mouse to scare the fish!</p>
    </div>

    <script type="importmap">
        {
            "imports": {
                "three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
                "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
            }
        }
    </script>

    <script type="module">
        import * as THREE from 'three';

        // --- Configuration ---
        const FISH_COUNT = 40;
        const AQUARIUM_SIZE = 20;
        const REPEL_DISTANCE = 4;
        const REPEL_STRENGTH = 0.15;
        const RETURN_SPEED = 0.02;

        let scene, camera, renderer, clock;
        let fishArray = [];
        let mouse = new THREE.Vector2(-1000, -1000);
        let raycaster = new THREE.Raycaster();

        init();
        animate();

        function init() {
            // Scene & Camera
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x001b3d);
            scene.fog = new THREE.Fog(0x001b3d, 10, 50);

            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(0, 2, 25);

            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setPixelRatio(window.devicePixelRatio);
            document.body.appendChild(renderer.domElement);

            clock = new THREE.Clock();

            // Lights
            const ambientLight = new THREE.AmbientLight(0x404040, 2);
            scene.add(ambientLight);

            const pointLight = new THREE.PointLight(0xffffff, 100);
            pointLight.position.set(0, 10, 0);
            scene.add(pointLight);

            const blueLight = new THREE.PointLight(0x00ffff, 50);
            blueLight.position.set(-10, -5, 5);
            scene.add(blueLight);

            // Aquarium Box (Glass effect)
            const boxGeo = new THREE.BoxGeometry(AQUARIUM_SIZE, AQUARIUM_SIZE, AQUARIUM_SIZE);
            const boxMat = new THREE.MeshPhongMaterial({
                color: 0xaaaaff,
                transparent: true,
                opacity: 0.1,
                side: THREE.BackSide
            });
            const aquarium = new THREE.Mesh(boxGeo, boxMat);
            scene.add(aquarium);

            // Sand/Floor
            const floorGeo = new THREE.PlaneGeometry(AQUARIUM_SIZE, AQUARIUM_SIZE);
            const floorMat = new THREE.MeshPhongMaterial({ color: 0xc2b280 });
            const floor = new THREE.Mesh(floorGeo, floorMat);
            floor.rotation.x = -Math.PI / 2;
            floor.position.y = -AQUARIUM_SIZE / 2;
            scene.add(floor);

            // Create Fish
            const colors = [0xff6600, 0xffff00, 0x00ffcc, 0xff00ff, 0xffaa00];
            
            for (let i = 0; i < FISH_COUNT; i++) {
                createFish(colors[Math.floor(Math.random() * colors.length)]);
            }

            window.addEventListener('resize', onWindowResize);
            window.addEventListener('mousemove', onMouseMove);
        }

        function createFish(color) {
            const group = new THREE.Group();

            // Body - Simple elongated sphere/cone
            const bodyGeo = new THREE.ConeGeometry(0.3, 1, 8);
            bodyGeo.rotateX(Math.PI / 2);
            const bodyMat = new THREE.MeshPhongMaterial({ color: color });
            const body = new THREE.Mesh(bodyGeo, bodyMat);
            group.add(body);

            // Tail
            const tailGeo = new THREE.TriangleGeometry(); // Mocked by scaled plane
            const tailMesh = new THREE.Mesh(
                new THREE.PlaneGeometry(0.4, 0.4),
                bodyMat
            );
            tailMesh.position.z = -0.6;
            tailMesh.rotation.y = Math.PI;
            group.add(tailMesh);

            // Random starting position
            group.position.set(
                (Math.random() - 0.5) * (AQUARIUM_SIZE * 0.8),
                (Math.random() - 0.5) * (AQUARIUM_SIZE * 0.8),
                (Math.random() - 0.5) * (AQUARIUM_SIZE * 0.8)
            );

            // Fish Logic
            const fish = {
                mesh: group,
                velocity: new THREE.Vector3(
                    (Math.random() - 0.5) * 0.1,
                    (Math.random() - 0.5) * 0.1,
                    (Math.random() - 0.5) * 0.1
                ),
                targetPos: new THREE.Vector3(
                    (Math.random() - 0.5) * AQUARIUM_SIZE,
                    (Math.random() - 0.5) * AQUARIUM_SIZE,
                    (Math.random() - 0.5) * AQUARIUM_SIZE
                ),
                phase: Math.random() * Math.PI * 2
            };

            scene.add(group);
            fishArray.push(fish);
        }

        function onMouseMove(event) {
            // Normalized device coordinates
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function animate() {
            requestAnimationFrame(animate);
            const time = clock.getElapsedTime();

            // Map mouse to 3D space via raycaster
            raycaster.setFromCamera(mouse, camera);
            const plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
            const mouseWorldPos = new THREE.Vector3();
            raycaster.ray.intersectPlane(plane, mouseWorldPos);

            fishArray.forEach(fish => {
                // 1. Natural movement towards target
                const toTarget = new THREE.Vector3().subVectors(fish.targetPos, fish.mesh.position).normalize();
                fish.velocity.addScaledVector(toTarget, 0.001);

                // 2. Repel from mouse
                const distToMouse = fish.mesh.position.distanceTo(mouseWorldPos);
                if (distToMouse < REPEL_DISTANCE) {
                    const repelDir = new THREE.Vector3().subVectors(fish.mesh.position, mouseWorldPos).normalize();
                    const force = (REPEL_DISTANCE - distToMouse) / REPEL_DISTANCE;
                    fish.velocity.addScaledVector(repelDir, force * REPEL_STRENGTH);
                }

                // 3. Boundary check (keep inside aquarium)
                const pos = fish.mesh.position;
                const limit = AQUARIUM_SIZE / 2;
                if (Math.abs(pos.x) > limit) fish.velocity.x *= -1;
                if (Math.abs(pos.y) > limit) fish.velocity.y *= -1;
                if (Math.abs(pos.z) > limit) fish.velocity.z *= -1;

                // 4. Apply physics
                fish.velocity.multiplyScalar(0.98); // friction
                fish.mesh.position.add(fish.velocity);

                // 5. Update rotation to look where it's swimming
                const lookTarget = new THREE.Vector3().addVectors(fish.mesh.position, fish.velocity);
                fish.mesh.lookAt(lookTarget);

                // 6. Tail animation (wobble)
                fish.mesh.children[1].rotation.y = Math.sin(time * 10 + fish.phase) * 0.5;

                // 7. Change target occasionally
                if (Math.random() < 0.01) {
                    fish.targetPos.set(
                        (Math.random() - 0.5) * AQUARIUM_SIZE,
                        (Math.random() - 0.5) * AQUARIUM_SIZE,
                        (Math.random() - 0.5) * AQUARIUM_SIZE
                    );
                }
            });

            renderer.render(scene, camera);
        }
    </script>
</body>
</html>