Models 44

Ministral 3 14B 2512

by Mistralreasoning 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
38.1 s
Cost
$0.0012
Output tokens
4,824
Spent thinking
0 tokens
Speed
127.6 tok/s
Console errors
1
First token after
264 ms
First visible text after
264 ms
Prompt tokens
573
Code size
20.1 KB
Finish reason
stop
Served by
Mistral
Model id
mistralai/ministral-14b-2512
Reasoning sent
model default
Max output
209,715 tokens
Generated
Nov 13, 2026

Console errors

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

startAnimation is not defined

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 · 565 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>Low-Poly Campfire in the Forest</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background-color: #000;
            font-family: Arial, sans-serif;
        }
        #container {
            width: 100vw;
            height: 100vh;
        }
        #start-message {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: white;
            text-align: center;
            background-color: rgba(0, 0, 0, 0.7);
            padding: 20px 40px;
            border-radius: 10px;
            font-size: 18px;
            pointer-events: none;
            z-index: 100;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        #start-message button {
            margin-top: 15px;
            padding: 8px 16px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        #start-message button:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
    <div id="container"></div>
    <div id="start-message">
        <div>Click or press a key to start</div>
        <button id="start-button">Start Experience</button>
    </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 { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
        import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
        import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';

        // Scene setup
        const container = document.getElementById('container');
        const startMessage = document.getElementById('start-message');
        const startButton = document.getElementById('start-button');

        let scene, camera, renderer, controls, composer;
        let fireLight, fireMesh;
        let sparkParticles = [];
        let clock = new THREE.Clock();
        let animationId = null;
        let isPlaying = false;

        // Initialize scene
        function init() {
            // Create scene
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x050520);

            // Create camera
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(5, 3, 8);

            // Create renderer
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.shadowMap.enabled = true;
            renderer.shadowMap.type = THREE.PCFSoftShadowMap;
            container.appendChild(renderer.domElement);

            // Add fog
            scene.fog = new THREE.FogExp2(0x050520, 0.002);

            // Add OrbitControls with limits
            controls = new OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;
            controls.dampingFactor = 0.05;
            controls.maxPolarAngle = Math.PI * 0.8; // Limit vertical rotation
            controls.minDistance = 2;
            controls.maxDistance = 15;
            controls.screenSpacePanning = false;

            // Add lights
            const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
            scene.add(ambientLight);

            const moonLight = new THREE.DirectionalLight(0xffffff, 0.3);
            moonLight.position.set(100, 100, 50);
            moonLight.castShadow = false;
            scene.add(moonLight);

            // Create ground
            createGround();

            // Create campfire
            createCampfire();

            // Create trees
            createTrees();

            // Create rocks and logs
            createRocksAndLogs();

            // Create stars
            createStars();

            // Create moon
            createMoon();

            // Post-processing
            setupPostProcessing();

            // Handle window resize
            window.addEventListener('resize', onWindowResize);

            // Start animation
            startAnimation();

            // Handle start button
            startButton.addEventListener('click', startExperience);
            document.addEventListener('keydown', startExperience);

            // Hide start message after a delay (for demo)
            setTimeout(() => {
                if (!isPlaying) {
                    startExperience();
                }
            }, 3000);
        }

        function startExperience() {
            if (!isPlaying) {
                isPlaying = true;
                startMessage.style.display = 'none';
                animate();
            }
        }

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

        function createGround() {
            const groundGeometry = new THREE.PlaneGeometry(50, 50);
            const groundMaterial = new THREE.MeshStandardMaterial({
                color: 0x3a2e22,
                roughness: 0.8,
                metalness: 0.2
            });
            const ground = new THREE.Mesh(groundGeometry, groundMaterial);
            ground.rotation.x = -Math.PI / 2;
            ground.receiveShadow = true;
            scene.add(ground);
        }

        function createCampfire() {
            // Fire base
            const fireBaseGeometry = new THREE.ConeGeometry(1.5, 0.5, 8);
            const fireBaseMaterial = new THREE.MeshStandardMaterial({
                color: 0x333333,
                roughness: 0.7,
                metalness: 0.1
            });
            const fireBase = new THREE.Mesh(fireBaseGeometry, fireBaseMaterial);
            fireBase.position.y = 0.25;
            fireBase.castShadow = true;
            scene.add(fireBase);

            // Fire flames (animated)
            const flameGeometry = new THREE.ConeGeometry(1.2, 1.5, 8);
            flameGeometry.rotateX(Math.PI / 2);

            const flameMaterial = new THREE.ShaderMaterial({
                uniforms: {
                    time: { value: 0 },
                    color: { value: new THREE.Color(0xffcc00) },
                    glowColor: { value: new THREE.Color(0xffaa00) },
                    texture: { value: null }
                },
                vertexShader: `
                    uniform float time;
                    varying vec3 vPosition;
                    varying float vHeight;

                    void main() {
                        vPosition = position;
                        vHeight = position.y;

                        // Add some animation to the vertices
                        float offset = sin(position.y * 10.0 + time) * 0.1;
                        vec3 newPosition = position + normal * offset;

                        gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
                    }
                `,
                fragmentShader: `
                    uniform vec3 color;
                    uniform vec3 glowColor;
                    uniform float time;
                    varying vec3 vPosition;
                    varying float vHeight;

                    void main() {
                        // Base color with height-based intensity
                        float intensity = smoothstep(0.0, 1.5, vHeight);
                        vec3 col = mix(color, glowColor, intensity * 0.5);

                        // Add some flickering
                        float flicker = sin(time * 5.0 + vPosition.x * 10.0 + vPosition.z * 10.0) * 0.1;
                        col *= 0.8 + flicker;

                        gl_FragColor = vec4(col, 1.0);
                    }
                `,
                transparent: true,
                side: THREE.DoubleSide,
                blending: THREE.AdditiveBlending
            });

            fireMesh = new THREE.Mesh(flameGeometry, flameMaterial);
            fireMesh.position.y = 0.75;
            fireMesh.castShadow = true;
            scene.add(fireMesh);

            // Fire light (flickering)
            fireLight = new THREE.PointLight(0xffaa00, 3, 8);
            fireLight.position.set(0, 1.5, 0);
            fireLight.castShadow = true;
            fireLight.shadow.mapSize.width = 1024;
            fireLight.shadow.mapSize.height = 1024;
            fireLight.shadow.camera.near = 0.5;
            fireLight.shadow.camera.far = 20;
            scene.add(fireLight);

            // Create logs around the fire
            const logGeometry = new THREE.CylinderGeometry(0.2, 0.2, 2, 8);
            const logMaterial = new THREE.MeshStandardMaterial({
                color: 0x5a3921,
                roughness: 0.7,
                metalness: 0.1
            });

            const logs = [
                { position: [1, 0, 0], rotation: [0, 0, 0] },
                { position: [-1, 0, 0], rotation: [0, 0, 0] },
                { position: [0, 0, 1], rotation: [0, Math.PI/2, 0] },
                { position: [0, 0, -1], rotation: [0, Math.PI/2, 0] }
            ];

            logs.forEach(log => {
                const logMesh = new THREE.Mesh(logGeometry, logMaterial);
                logMesh.position.set(...log.position);
                logMesh.rotation.set(...log.rotation);
                logMesh.castShadow = true;
                logMesh.receiveShadow = true;
                scene.add(logMesh);
            });
        }

        function createTrees() {
            const treeCount = 30;
            const treeTrunkGeometry = new THREE.CylinderGeometry(0.1, 0.15, 1.5, 8);
            const treeTrunkMaterial = new THREE.MeshStandardMaterial({
                color: 0x5a3921,
                roughness: 0.7,
                metalness: 0.1
            });

            const treeLeavesGeometry = new THREE.ConeGeometry(0.8, 1.2, 8);
            treeLeavesGeometry.rotateX(Math.PI / 2);
            const treeLeavesMaterial = new THREE.MeshStandardMaterial({
                color: 0x2e7d32,
                roughness: 0.8,
                metalness: 0.1
            });

            for (let i = 0; i < treeCount; i++) {
                // Random position in a circle around the campfire
                const angle = Math.random() * Math.PI * 2;
                const distance = 5 + Math.random() * 15;
                const x = Math.cos(angle) * distance;
                const z = Math.sin(angle) * distance;

                // Create trunk
                const trunk = new THREE.Mesh(treeTrunkGeometry, treeLeavesMaterial);
                trunk.position.set(x, 0.75, z);
                trunk.castShadow = true;
                scene.add(trunk);

                // Create leaves
                const leaves = new THREE.Mesh(treeLeavesGeometry, treeLeavesMaterial);
                leaves.position.set(x, 2.25, z);
                leaves.castShadow = true;
                scene.add(leaves);

                // Random rotation for variety
                leaves.rotation.y = Math.random() * Math.PI * 2;
                trunk.rotation.y = Math.random() * Math.PI * 2;
            }
        }

        function createRocksAndLogs() {
            const rockGeometry = new THREE.IcosahedronGeometry(0.5, 3);
            const rockMaterial = new THREE.MeshStandardMaterial({
                color: 0x5d4037,
                roughness: 0.9,
                metalness: 0.2
            });

            const logGeometry = new THREE.CylinderGeometry(0.15, 0.2, 1.5, 8);
            const logMaterial = new THREE.MeshStandardMaterial({
                color: 0x5a3921,
                roughness: 0.7,
                metalness: 0.1
            });

            const rocksAndLogs = [
                { type: 'rock', position: [-3, 0.25, 2], rotation: [0, 0, 0] },
                { type: 'rock', position: [4, 0.3, -3], rotation: [0, Math.PI/4, 0] },
                { type: 'rock', position: [-2, 0.2, -4], rotation: [0, Math.PI/3, 0] },
                { type: 'log', position: [3, 0.1, 3], rotation: [0, Math.PI/2, 0] },
                { type: 'log', position: [-4, 0.1, 1], rotation: [0, Math.PI/2, 0] },
                { type: 'rock', position: [2, 0.3, -5], rotation: [0, Math.PI/6, 0] }
            ];

            rocksAndLogs.forEach(item => {
                const mesh = item.type === 'rock'
                    ? new THREE.Mesh(rockGeometry, rockMaterial)
                    : new THREE.Mesh(logGeometry, logMaterial);

                mesh.position.set(...item.position);
                mesh.rotation.set(...item.rotation);
                mesh.castShadow = true;
                mesh.receiveShadow = true;
                scene.add(mesh);
            });
        }

        function createStars() {
            const starGeometry = new THREE.BufferGeometry();
            const starMaterial = new THREE.PointsMaterial({
                color: 0xffffff,
                size: 0.05,
                transparent: true,
                opacity: 0.8,
                sizeAttenuation: true
            });

            const starVertices = [];
            const starColors = [];
            const starSizes = [];

            const starCount = 500;

            for (let i = 0; i < starCount; i++) {
                const x = (Math.random() - 0.5) * 2000;
                const y = Math.random() * 1000 - 100;
                const z = (Math.random() - 0.5) * 2000;

                starVertices.push(x, y, z);

                // Random size for stars
                const size = 0.05 + Math.random() * 0.2;
                starSizes.push(size);

                // Brighter stars are more likely to be closer
                const distance = Math.sqrt(x*x + y*y + z*z);
                const brightness = 0.5 + Math.random() * 0.5;
                const colorIntensity = 0.5 + (1 - distance/1000) * 0.5;
                const color = new THREE.Color().setHSL(0, 0, colorIntensity * brightness);

                starColors.push(color.r, color.g, color.b);
            }

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

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

        function createMoon() {
            const moonGeometry = new THREE.SphereGeometry(1.5, 32, 32);
            const moonMaterial = new THREE.MeshStandardMaterial({
                color: 0xf5f5dc,
                roughness: 0.5,
                metalness: 0.1
            });

            const moon = new THREE.Mesh(moonGeometry, moonMaterial);
            moon.position.set(10, 15, -10);
            scene.add(moon);

            // Add some craters for detail
            const craterGeometry = new THREE.SphereGeometry(0.3, 16, 16);
            const craterMaterial = new THREE.MeshStandardMaterial({
                color: 0x333333,
                roughness: 0.8
            });

            const craters = [
                { position: [0.8, 0.3, 0.5] },
                { position: [-0.5, -0.4, 0.7] },
                { position: [0.3, 0.6, -0.4] }
            ];

            craters.forEach(crater => {
                const craterMesh = new THREE.Mesh(craterGeometry, craterMaterial);
                craterMesh.position.set(...crater.position);
                moon.add(craterMesh);
            });
        }

        function setupPostProcessing() {
            // Render pass
            const renderPass = new RenderPass(scene, camera);

            // Bloom pass
            const bloomPass = new UnrealBloomPass(
                new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85
            );
            bloomPass.threshold = 0;
            bloomPass.strength = 0.8;
            bloomPass.radius = 0.5;

            // Composer
            composer = new EffectComposer(renderer);
            composer.addPass(renderPass);
            composer.addPass(bloomPass);
        }

        function createSpark() {
            const sparkGeometry = new THREE.BufferGeometry();
            const sparkMaterial = new THREE.PointsMaterial({
                color: 0xffff00,
                size: 0.1,
                transparent: true,
                opacity: 0.8,
                sizeAttenuation: true,
                blending: THREE.AdditiveBlending
            });

            const spark = {
                mesh: new THREE.Points(sparkGeometry, sparkMaterial),
                velocity: new THREE.Vector3(
                    (Math.random() - 0.5) * 0.1,
                    Math.random() * 0.2 + 0.1,
                    (Math.random() - 0.5) * 0.1
                ),
                position: new THREE.Vector3(0, 0, 0),
                age: 0,
                maxAge: 1.5 + Math.random() * 1.5,
                size: 0.1 + Math.random() * 0.2
            };

            spark.mesh.position.set(0, 0, 0);
            spark.mesh.scale.set(spark.size, spark.size, spark.size);

            scene.add(spark.mesh);
            sparkParticles.push(spark);

            return spark;
        }

        function animate() {
            requestAnimationFrame(animate);

            const delta = clock.getDelta();
            const elapsedTime = clock.getElapsedTime();

            if (isPlaying) {
                // Update controls
                controls.update();

                // Animate fire light (flicker)
                const flickerIntensity = 0.5 + Math.sin(elapsedTime * 5) * 0.3;
                fireLight.intensity = 2 + flickerIntensity;
                fireLight.color.setHSL(0.1, 0.8, 0.8 + Math.sin(elapsedTime * 3) * 0.1);

                // Animate fire mesh
                fireMesh.material.uniforms.time.value = elapsedTime;

                // Update spark particles
                for (let i = sparkParticles.length - 1; i >= 0; i--) {
                    const spark = sparkParticles[i];

                    // Update position
                    spark.position.add(spark.velocity);
                    spark.mesh.position.copy(spark.position);

                    // Add some random movement
                    spark.velocity.y -= 0.01 * delta;
                    spark.velocity.x += (Math.random() - 0.5) * 0.01;
                    spark.velocity.z += (Math.random() - 0.5) * 0.01;

                    // Update age and size
                    spark.age += delta;
                    const lifeRatio = 1 - spark.age / spark.maxAge;
                    spark.mesh.scale.set(
                        spark.size * lifeRatio,
                        spark.size * lifeRatio,
                        spark.size * lifeRatio
                    );
                    spark.mesh.material.opacity = lifeRatio;

                    // Remove old sparks
                    if (spark.age >= spark.maxAge) {
                        scene.remove(spark.mesh);
                        sparkParticles.splice(i, 1);
                    }
                }

                // Create new sparks randomly
                if (Math.random() < 0.05) {
                    createSpark();
                }

                // Render scene
                renderer.render(scene, camera);
                // composer.render();
            }
        }

        // Start the application
        init();
    </script>
</body>
</html>