Models 44

Mistral Small 4

by MistralReasoning1 console error
Open in new window

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

How it went

Total time
24.4 s
Cost
$0.0030
Output tokens
4,789
Spent thinking
556 tokens
Speed
200.8 tok/s
Console errors
1
First token after
512 ms
First visible text after
3.9 s
Prompt tokens
585
Code size
15.8 KB
Finish reason
stop
Served by
Mistral
Model id
mistralai/mistral-small-2603
Reasoning sent
{"effort":"high"}
Max output
209,715 tokens
Generated
Nov 12, 2026

Console errors

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

noise.get is not a function

What it was asked

The prompt
Build a low-poly 3D scene of a campfire in a forest clearing at night, with Three.js in a single HTML file. Load Three.js only through this import map (do not use any other URL or version): <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> Requirements: - A ground with a few low-poly rocks and logs around a campfire in the center. - At least 30 low-poly trees placed randomly around the clearing (not on the fire). - The campfire has animated flames and a warm point light that flickers and casts shadows. - Sparks rising from the fire as a simple particle system. - A dark night sky with stars and a moon, plus fog that fades the distant trees. - OrbitControls to look around, with limits so the camera stays above the ground. - The renderer fills the window and handles resizing correctly.
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 · 437 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Low-Poly Campfire Scene</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: #000;
        }
        #info {
            position: absolute;
            top: 10px;
            left: 10px;
            color: white;
            background: rgba(0,0,0,0.5);
            padding: 10px;
            border-radius: 5px;
            font-family: Arial, sans-serif;
            pointer-events: none;
        }
        #start {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: white;
            background: rgba(0,0,0,0.7);
            padding: 20px;
            border-radius: 10px;
            font-family: Arial, sans-serif;
            text-align: center;
            pointer-events: none;
            font-size: 18px;
        }
    </style>
</head>
<body>
    <div id="info">Low-Poly Campfire Scene</div>
    <div id="start">Click or press a key to start</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';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';

        // Scene setup
        const scene = new THREE.Scene();
        scene.fog = new THREE.Fog(0x000022, 50, 150);

        // Camera
        const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 500);
        camera.position.set(0, 30, 50);

        // Renderer
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x000000);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.BasicShadowMap;
        document.body.appendChild(renderer.domElement);

        // Controls
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.minPolarAngle = Math.PI / 6;
        controls.maxPolarAngle = Math.PI / 2.2;
        controls.minDistance = 10;
        controls.maxDistance = 200;
        controls.target.set(0, 5, 0);

        // Lighting
        const ambientLight = new THREE.AmbientLight(0x222233, 0.3);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffeedd, 0.5);
        directionalLight.position.set(100, 200, 100);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.width = 1024;
        directionalLight.shadow.mapSize.height = 1024;
        directionalLight.shadow.camera.near = 0.5;
        directionalLight.shadow.camera.far = 500;
        scene.add(directionalLight);

        // Campfire light (will flicker)
        const fireLight = new THREE.PointLight(0xffaa33, 2, 50, 2);
        fireLight.castShadow = true;
        fireLight.shadow.mapSize.width = 512;
        fireLight.shadow.mapSize.height = 512;
        scene.add(fireLight);

        // Ground
        const groundGeometry = new THREE.PlaneGeometry(200, 200, 100, 100);
        const groundMaterial = new THREE.MeshStandardMaterial({
            color: 0x3a5f0b,
            roughness: 0.8,
            metalness: 0.1
        });
        const ground = new THREE.Mesh(groundGeometry, groundMaterial);
        ground.rotation.x = -Math.PI / 2;
        ground.receiveShadow = true;
        scene.add(ground);

        // Add some noise to ground for texture
        const groundVertices = ground.geometry.attributes.position;
        const noise = new ImprovedNoise();
        for (let i = 0; i < groundVertices.count; i++) {
            const x = groundVertices.getX(i);
            const z = groundVertices.getZ(i);
            const y = groundVertices.getY(i);
            const noiseValue = noise.get(x * 0.05, z * 0.05, 0) * 0.5;
            groundVertices.setY(i, y + noiseValue);
        }
        ground.geometry.computeVertexNormals();

        // Trees (at least 30)
        const trees = [];
        const treeCount = 35;
        const treeGeometry = new THREE.ConeGeometry(1, 4, 8);
        const treeMaterial = new THREE.MeshStandardMaterial({ color: 0x225522 });

        for (let i = 0; i < treeCount; i++) {
            const angle = Math.random() * Math.PI * 2;
            const distance = 30 + Math.random() * 80;
            const x = Math.cos(angle) * distance;
            const z = Math.sin(angle) * distance;

            // Avoid placing trees too close to campfire
            const distToCenter = Math.sqrt(x * x + z * z);
            if (distToCenter < 15) continue;

            const tree = new THREE.Group();

            // Trunk
            const trunk = new THREE.Mesh(treeGeometry, treeMaterial);
            trunk.position.y = 2;
            trunk.scale.y = 0.8;
            trunk.castShadow = true;
            trunk.receiveShadow = true;
            tree.add(trunk);

            // Foliage (cone)
            const foliage = new THREE.Mesh(
                new THREE.ConeGeometry(2.5, 5, 8),
                new THREE.MeshStandardMaterial({ color: 0x337733 })
            );
            foliage.position.y = 4.5;
            foliage.castShadow = true;
            foliage.receiveShadow = true;
            tree.add(foliage);

            tree.position.set(x, 0, z);
            tree.rotation.y = Math.random() * Math.PI * 2;
            tree.castShadow = true;
            tree.receiveShadow = true;

            scene.add(tree);
            trees.push(tree);
        }

        // Campfire
        const campfireGroup = new THREE.Group();
        campfireGroup.position.set(0, 0, 0);
        scene.add(campfireGroup);

        // Fire base
        const fireBase = new THREE.Mesh(
            new THREE.CylinderGeometry(3, 3, 1, 12),
            new THREE.MeshStandardMaterial({ color: 0x552200 })
        );
        fireBase.position.y = 0.5;
        fireBase.castShadow = true;
        fireBase.receiveShadow = true;
        campfireGroup.add(fireBase);

        // Fire logs
        const logGeometry = new THREE.CylinderGeometry(0.5, 0.5, 4, 8);
        const logMaterial = new THREE.MeshStandardMaterial({ color: 0x663311 });

        for (let i = 0; i < 5; i++) {
            const log = new THREE.Mesh(logGeometry, logMaterial);
            log.position.set(
                (Math.random() - 0.5) * 4,
                1 + Math.random() * 0.5,
                (Math.random() - 0.5) * 4
            );
            log.rotation.x = Math.random() * Math.PI;
            log.rotation.z = Math.random() * Math.PI;
            log.castShadow = true;
            log.receiveShadow = true;
            campfireGroup.add(log);
        }

        // Fire flames (particle system)
        const flameParticles = [];
        const flameGeometry = new THREE.PlaneGeometry(1, 2);
        const flameMaterial = new THREE.MeshBasicMaterial({
            color: 0xffaa33,
            transparent: true,
            opacity: 0.8,
            side: THREE.DoubleSide
        });

        for (let i = 0; i < 20; i++) {
            const flame = new THREE.Mesh(flameGeometry, flameMaterial.clone());
            flame.position.set(
                (Math.random() - 0.5) * 2,
                0.5 + Math.random() * 2,
                (Math.random() - 0.5) * 2
            );
            flame.rotation.x = Math.random() * Math.PI;
            flame.rotation.y = Math.random() * Math.PI;
            flame.userData = {
                speed: 0.05 + Math.random() * 0.05,
                scale: 0.5 + Math.random() * 0.5,
                opacity: 0.7 + Math.random() * 0.3
            };
            flame.castShadow = true;
            campfireGroup.add(flame);
            flameParticles.push(flame);
        }

        // Sparks particle system
        const sparkCount = 100;
        const sparkGeometry = new THREE.BufferGeometry();
        const sparkPositions = new Float32Array(sparkCount * 3);
        const sparkColors = new Float32Array(sparkCount * 3);
        const sparkSizes = new Float32Array(sparkCount);
        const sparkSpeeds = new Float32Array(sparkCount);
        const sparkLifetimes = new Float32Array(sparkCount);
        const sparkMaxLifetime = 3;

        for (let i = 0; i < sparkCount; i++) {
            const i3 = i * 3;
            sparkPositions[i3] = 0;
            sparkPositions[i3 + 1] = 0;
            sparkPositions[i3 + 2] = 0;

            const hue = 0.08 + Math.random() * 0.04; // Yellow to orange
            const rgb = new THREE.Color().setHSL(hue, 0.9, 0.5);
            sparkColors[i3] = rgb.r;
            sparkColors[i3 + 1] = rgb.g;
            sparkColors[i3 + 2] = rgb.b;

            sparkSizes[i] = 0.1 + Math.random() * 0.2;
            sparkSpeeds[i] = 0.05 + Math.random() * 0.1;
            sparkLifetimes[i] = Math.random() * sparkMaxLifetime;
        }

        sparkGeometry.setAttribute('position', new THREE.BufferAttribute(sparkPositions, 3));
        sparkGeometry.setAttribute('color', new THREE.BufferAttribute(sparkColors, 3));
        sparkGeometry.setAttribute('size', new THREE.BufferAttribute(sparkSizes, 1));
        sparkGeometry.setAttribute('speed', new THREE.BufferAttribute(sparkSpeeds, 1));
        sparkGeometry.setAttribute('lifetime', new THREE.BufferAttribute(sparkLifetimes, 1));

        const sparkMaterial = new THREE.PointsMaterial({
            size: 0.1,
            vertexColors: true,
            transparent: true,
            opacity: 0.8,
            sizeAttenuation: true,
            blending: THREE.AdditiveBlending
        });

        const sparks = new THREE.Points(sparkGeometry, sparkMaterial);
        campfireGroup.add(sparks);

        // Moon
        const moonGeometry = new THREE.SphereGeometry(8, 16, 16);
        const moonMaterial = new THREE.MeshStandardMaterial({
            color: 0xffffcc,
            emissive: 0x444422,
            emissiveIntensity: 0.5
        });
        const moon = new THREE.Mesh(moonGeometry, moonMaterial);
        moon.position.set(120, 100, -80);
        moon.castShadow = false;
        scene.add(moon);

        // Stars
        const starGeometry = new THREE.BufferGeometry();
        const starPositions = new Float32Array(500 * 3);
        const starSizes = new Float32Array(500);
        const starColors = new Float32Array(500 * 3);

        for (let i = 0; i < 500; i++) {
            const i3 = i * 3;
            starPositions[i3] = (Math.random() - 0.5) * 300;
            starPositions[i3 + 1] = Math.random() * 150;
            starPositions[i3 + 2] = (Math.random() - 0.5) * 300;

            starSizes[i] = 0.5 + Math.random() * 2;

            const brightness = 0.5 + Math.random() * 0.5;
            starColors[i3] = brightness;
            starColors[i3 + 1] = brightness;
            starColors[i3 + 2] = brightness + 0.2;
        }

        starGeometry.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
        starGeometry.setAttribute('size', new THREE.BufferAttribute(starSizes, 1));
        starGeometry.setAttribute('color', new THREE.BufferAttribute(starColors, 3));

        const starMaterial = new THREE.PointsMaterial({
            size: 1,
            vertexColors: true,
            transparent: true,
            opacity: 0.8,
            sizeAttenuation: true
        });

        const stars = new THREE.Points(starGeometry, starMaterial);
        scene.add(stars);

        // Rocks
        const rockGeometry = new THREE.DodecahedronGeometry(1, 0);
        const rockMaterial = new THREE.MeshStandardMaterial({ color: 0x555555 });

        for (let i = 0; i < 8; i++) {
            const rock = new THREE.Mesh(rockGeometry, rockMaterial);
            const angle = Math.random() * Math.PI * 2;
            const distance = 10 + Math.random() * 30;
            rock.position.set(
                Math.cos(angle) * distance,
                0.5,
                Math.sin(angle) * distance
            );
            rock.rotation.set(
                Math.random() * Math.PI,
                Math.random() * Math.PI,
                Math.random() * Math.PI
            );
            rock.scale.set(0.5 + Math.random(), 0.5 + Math.random(), 0.5 + Math.random());
            rock.castShadow = true;
            rock.receiveShadow = true;
            scene.add(rock);
        }

        // Logs around fire
        const logGroup = new THREE.Group();
        for (let i = 0; i < 6; i++) {
            const log = new THREE.Mesh(
                new THREE.CylinderGeometry(0.3, 0.3, 3, 6),
                new THREE.MeshStandardMaterial({ color: 0x663311 })
            );
            const angle = Math.random() * Math.PI * 2;
            const distance = 5 + Math.random() * 8;
            log.position.set(
                Math.cos(angle) * distance,
                1.5,
                Math.sin(angle) * distance
            );
            log.rotation.x = Math.PI / 2;
            log.rotation.z = Math.random() * Math.PI;
            log.castShadow = true;
            log.receiveShadow = true;
            logGroup.add(log);
        }
        campfireGroup.add(logGroup);

        // Animation variables
        let time = 0;
        let fireIntensity = 2;
        let flickerDirection = 1;

        // Animation loop
        function animate() {
            requestAnimationFrame(animate);

            time += 0.01;

            // Flicker fire light
            flickerDirection += (Math.random() - 0.5) * 0.02;
            flickerDirection = Math.max(0.8, Math.min(1.2, flickerDirection));
            fireIntensity = 2 + Math.sin(time * 3) * 0.3 * flickerDirection;
            fireLight.intensity = fireIntensity;
            fireLight.color.setHSL(0.08, 0.9, 0.6 + Math.sin(time * 2) * 0.1);

            // Animate flames
            flameParticles.forEach((flame, i) => {
                flame.position.y = 0.5 + Math.sin(time * 2 + i) * 0.3;
                flame.rotation.y += 0.02;
                flame.material.opacity = flame.userData.opacity * (0.7 + Math.sin(time * 3 + i) * 0.3);
            });

            // Update sparks
            const positions = sparks.geometry.attributes.position.array;
            const lifetimes = sparks.geometry.attributes.lifetime.array;

            for (let i = 0; i < sparkCount; i++) {
                const i3 = i * 3;
                lifetimes[i] -= 0.01;

                if (lifetimes[i] <= 0) {
                    // Reset spark
                    lifetimes[i] = sparkMaxLifetime;
                    positions[i3] = (Math.random() - 0.5) * 2;
                    positions[i3 + 1] = 0.1;
                    positions[i3 + 2] = (Math.random() - 0.5) * 2;
                } else {
                    // Move spark up
                    positions[i3 + 1] += sparkSpeeds[i];
                }
            }

            sparks.geometry.attributes.position.needsUpdate = true;
            sparks.geometry.attributes.lifetime.needsUpdate = true;

            // Rotate moon for subtle effect
            moon.rotation.y += 0.001;

            controls.update();
            renderer.render(scene, camera);
        }

        // Handle window resize
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        // Start animation after click/key
        function startDemo() {
            document.getElementById('start').style.display = 'none';
            animate();
        }

        document.addEventListener('click', startDemo, { once: true });
        document.addEventListener('keydown', startDemo, { once: true });
    </script>
</body>
</html>
Reasoning trace (556 tokens)
I need to create a low-poly 3D campfire scene in a forest clearing at night using Three.js. Let me break down the requirements:

1. Ground with rocks and logs around a central campfire
2. At least 30 low-poly trees randomly placed around the clearing
3. Campfire with animated flames, warm flickering point light, and shadows
4. Sparks as a particle system
5. Dark night sky with stars and moon, plus fog
6. OrbitControls with limits
7. Responsive design that fills the window

I'll need to:
- Set up a Three.js scene with a camera, renderer, and controls
- Create a ground plane with a simple texture or color
- Generate low-poly trees (using cone/geometry combinations)
- Place rocks and logs around the campfire
- Create the campfire with animated flames (using planes with textures or particle systems)
- Add a flickering point light for the fire
- Create a particle system for sparks
- Generate a night sky with stars and moon
- Add fog to the scene
- Set up OrbitControls with limits
- Handle window resizing

Let me start by structuring the HTML file with the import map and basic Three.js setup. I'll use the specified import map URLs.

For the trees, I'll create low-poly versions using simple geometries - cones for trunks and pyramids or custom geometries for foliage. I'll need to generate at least 30 trees randomly placed around the clearing.

For the campfire:
- Base: cylinder or stack of cylinders
- Flames: I can use a particle system or animated planes with textures that change over time
- Light: a point light with intensity that flickers
- Shadows: enable shadow casting for the fire and trees

For sparks:
- A particle system with particles that rise and fade

For the night sky:
- A large sphere or dome with a starry texture
- A moon (sphere with texture or simple color)
- Fog to fade distant objects

For the ground:
- A plane with a simple grass/dirt texture or color
- Add some low-poly rocks and logs around the fire

Let me start coding this step by step. I'll need to:
1. Import Three.js and OrbitControls
2. Set up the scene, camera, renderer
3. Create the ground
4. Generate trees
5. Create the campfire structure
6. Add the particle system for sparks
7. Create the night sky
8. Set up OrbitControls with limits
9. Add animation loop
10. Handle window resizing

I'll keep everything in a single HTML file as required.