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
18.3 s
Cost
$0.0022
Output tokens
3,649
Spent thinking
0 tokens
Speed
203.9 tok/s
Console errors
1
First token after
440 ms
First visible text after
440 ms
Prompt tokens
585
Code size
11.7 KB
Finish reason
stop
Served by
Mistral
Model id
mistralai/mistral-small-2603
Reasoning sent
{"effort":"none"}
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 · 378 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;
      font-family: Arial, sans-serif;
    }
    #info {
      position: absolute;
      top: 10px;
      left: 10px;
      color: white;
      background: rgba(0,0,0,0.5);
      padding: 8px 12px;
      border-radius: 4px;
      font-size: 14px;
      z-index: 100;
    }
    #start {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: white;
      background: rgba(0,0,0,0.7);
      padding: 20px 30px;
      border-radius: 8px;
      font-size: 18px;
      cursor: pointer;
      z-index: 100;
      text-align: center;
    }
    #start:hover {
      background: rgba(0,0,0,0.9);
    }
  </style>
</head>
<body>
  <div id="info">Click or press a key to start</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.FogExp2(0x000000, 0.0015);

    const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(20, 10, 20);

    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    document.body.appendChild(renderer.domElement);

    // Controls
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.maxPolarAngle = Math.PI * 0.8;
    controls.minDistance = 5;
    controls.maxDistance = 50;
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;

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

    const campfireLight = new THREE.PointLight(0xff8c42, 2, 30);
    campfireLight.position.set(0, 3, 0);
    campfireLight.castShadow = true;
    campfireLight.shadow.mapSize.width = 256;
    campfireLight.shadow.mapSize.height = 256;
    campfireLight.shadow.camera.near = 0.5;
    campfireLight.shadow.camera.far = 20;
    scene.add(campfireLight);

    // Ground
    const groundGeometry = new THREE.PlaneGeometry(100, 100, 64, 64);
    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);

    // Noise for terrain variation
    const noise = new ImprovedNoise();
    const groundVertices = groundGeometry.attributes.position.array;
    for (let i = 0; i < groundVertices.length; i += 3) {
      const x = groundVertices[i];
      const z = groundVertices[i + 2];
      const y = noise.get(x * 0.1, z * 0.1, 0) * 0.5;
      groundVertices[i + 1] = y;
    }
    groundGeometry.computeVertexNormals();

    // Campfire
    const fireGroup = new THREE.Group();
    scene.add(fireGroup);

    // Fire base
    const fireBaseGeometry = new THREE.ConeGeometry(1.5, 0.5, 16);
    const fireBaseMaterial = new THREE.MeshStandardMaterial({
      color: 0x3a2a1a,
      roughness: 0.7
    });
    const fireBase = new THREE.Mesh(fireBaseGeometry, fireBaseMaterial);
    fireBase.position.y = 0.25;
    fireBase.castShadow = true;
    fireGroup.add(fireBase);

    // Fire flames (animated)
    const fireGeometry = new THREE.ConeGeometry(2, 4, 16);
    const fireMaterial = new THREE.MeshStandardMaterial({
      color: 0xff4500,
      emissive: 0xff4500,
      emissiveIntensity: 0.8,
      transparent: true,
      opacity: 0.9
    });
    const fire = new THREE.Mesh(fireGeometry, fireMaterial);
    fire.position.y = 2.5;
    fire.castShadow = true;
    fireGroup.add(fire);

    // Sparks particle system
    const sparkCount = 100;
    const sparksGeometry = new THREE.BufferGeometry();
    const sparksPositions = new Float32Array(sparkCount * 3);
    const sparksSpeeds = new Float32Array(sparkCount * 3);
    const sparksColors = new Float32Array(sparkCount * 3);
    const sparksSizes = new Float32Array(sparkCount);

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

      sparksSpeeds[i * 3] = (Math.random() - 0.5) * 0.2;
      sparksSpeeds[i * 3 + 1] = Math.random() * 0.3 + 0.2;
      sparksSpeeds[i * 3 + 2] = (Math.random() - 0.5) * 0.2;

      const hue = 0.1 + Math.random() * 0.1;
      const color = new THREE.Color().setHSL(hue, 0.9, 0.5);
      sparksColors.set([color.r, color.g, color.b], i * 3);

      sparksSizes[i] = Math.random() * 0.2 + 0.1;
    }

    sparksGeometry.setAttribute('position', new THREE.BufferAttribute(sparksPositions, 3));
    sparksGeometry.setAttribute('speed', new THREE.BufferAttribute(sparksSpeeds, 3));
    sparksGeometry.setAttribute('color', new THREE.BufferAttribute(sparksColors, 3));
    sparksGeometry.setAttribute('size', new THREE.BufferAttribute(sparksSizes, 1));

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

    const sparks = new THREE.Points(sparksGeometry, sparkMaterial);
    fireGroup.add(sparks);

    // Trees (30+ low-poly trees)
    const treeGroup = new THREE.Group();
    scene.add(treeGroup);

    const trunkGeometry = new THREE.CylinderGeometry(0.2, 0.3, 3, 8);
    const leavesGeometry = new THREE.ConeGeometry(1.5, 4, 8);

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

      // Don't place trees too close to the campfire
      const distToFire = Math.sqrt(x * x + z * z);
      if (distToFire < 8) continue;

      const tree = new THREE.Group();
      tree.position.set(x, 0, z);
      treeGroup.add(tree);

      // Trunk
      const trunk = new THREE.Mesh(trunkGeometry, new THREE.MeshStandardMaterial({
        color: 0x5a3a22,
        roughness: 0.7
      }));
      trunk.position.y = 1.5;
      trunk.castShadow = true;
      tree.add(trunk);

      // Leaves
      const leaves = new THREE.Mesh(leavesGeometry, new THREE.MeshStandardMaterial({
        color: 0x2a5f2a,
        roughness: 0.8
      }));
      leaves.position.y = 3;
      leaves.castShadow = true;
      tree.add(leaves);
    }

    // Rocks
    const rockGroup = new THREE.Group();
    scene.add(rockGroup);

    const rockGeometry = new THREE.DodecahedronGeometry(0.8, 0);
    for (let i = 0; i < 10; i++) {
      const angle = Math.random() * Math.PI * 2;
      const distance = 5 + Math.random() * 10;
      const x = Math.cos(angle) * distance;
      const z = Math.sin(angle) * distance;

      const rock = new THREE.Mesh(rockGeometry, new THREE.MeshStandardMaterial({
        color: 0x7a7a7a,
        roughness: 0.9
      }));
      rock.position.set(x, 0.4, z);
      rock.rotation.x = Math.random() * Math.PI;
      rock.rotation.y = Math.random() * Math.PI;
      rock.castShadow = true;
      rockGroup.add(rock);
    }

    // Logs
    const logGroup = new THREE.Group();
    scene.add(logGroup);

    const logGeometry = new THREE.CylinderGeometry(0.2, 0.2, 2, 8);
    for (let i = 0; i < 5; i++) {
      const angle = Math.random() * Math.PI * 2;
      const distance = 5 + Math.random() * 10;
      const x = Math.cos(angle) * distance;
      const z = Math.sin(angle) * distance;

      const log = new THREE.Mesh(logGeometry, new THREE.MeshStandardMaterial({
        color: 0x6a4a2a,
        roughness: 0.8
      }));
      log.position.set(x, 0.5, z);
      log.rotation.x = Math.random() * Math.PI;
      log.rotation.z = Math.random() * Math.PI;
      log.castShadow = true;
      logGroup.add(log);
    }

    // Moon and stars
    const moonGeometry = new THREE.SphereGeometry(2, 16, 16);
    const moonMaterial = new THREE.MeshStandardMaterial({
      color: 0xffffcc,
      emissive: 0xffffaa,
      emissiveIntensity: 0.8
    });
    const moon = new THREE.Mesh(moonGeometry, moonMaterial);
    moon.position.set(30, 25, -20);
    scene.add(moon);

    // Stars
    const starGroup = new THREE.Group();
    scene.add(starGroup);

    for (let i = 0; i < 300; i++) {
      const star = new THREE.Mesh(
        new THREE.SphereGeometry(0.05, 4, 4),
        new THREE.MeshBasicMaterial({ color: 0xffffff })
      );
      star.position.set(
        (Math.random() - 0.5) * 100,
        Math.random() * 50 + 20,
        (Math.random() - 0.5) * 100
      );
      starGroup.add(star);
    }

    // Animation variables
    let time = 0;
    let isAnimating = false;
    let fireIntensity = 1.0;
    let lightIntensity = 2.0;

    // Start animation
    function startAnimation() {
      isAnimating = true;
      document.getElementById('start').style.display = 'none';
      document.getElementById('info').style.display = 'none';
    }

    // Event listeners
    document.addEventListener('click', startAnimation);
    document.addEventListener('keydown', (e) => {
      if (e.code === 'Space' || e.key === 'Enter') {
        startAnimation();
      }
    });

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

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

      if (isAnimating) {
        time += 0.01;

        // Animate fire
        fire.scale.y = 1 + Math.sin(time * 2) * 0.2;
        fire.position.y = 2.5 + Math.sin(time * 1.5) * 0.3;

        // Animate fire light flicker
        const flicker = 0.5 + Math.sin(time * 3) * 0.3 + Math.random() * 0.2;
        campfireLight.intensity = lightIntensity * flicker;
        campfireLight.color.setHSL(0.05, 0.8, 0.6 + flicker * 0.1);

        // Update sparks
        const positions = sparksGeometry.attributes.position.array;
        const speeds = sparksGeometry.attributes.speed.array;

        for (let i = 0; i < sparkCount; i++) {
          positions[i * 3] += speeds[i * 3];
          positions[i * 3 + 1] += speeds[i * 3 + 1];
          positions[i * 3 + 2] += speeds[i * 3 + 2];

          // Reset if spark falls below ground or goes too far
          if (positions[i * 3 + 1] < 0 || Math.abs(positions[i * 3]) > 20 || Math.abs(positions[i * 3 + 2]) > 20) {
            positions[i * 3] = 0;
            positions[i * 3 + 1] = 0;
            positions[i * 3 + 2] = 0;
            speeds[i * 3] = (Math.random() - 0.5) * 0.2;
            speeds[i * 3 + 1] = Math.random() * 0.3 + 0.2;
            speeds[i * 3 + 2] = (Math.random() - 0.5) * 0.2;
          }
        }

        sparksGeometry.attributes.position.needsUpdate = true;

        // Animate moon
        moon.position.x = 30 + Math.sin(time * 0.05) * 5;
        moon.position.y = 25 + Math.sin(time * 0.03) * 2;

        // Rotate scene slightly
        treeGroup.rotation.y += 0.0005;
        rockGroup.rotation.y += 0.0003;
        logGroup.rotation.y += 0.0002;
      }

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

    animate();
  </script>
</body>
</html>