Models 44

Gemini 3.1 Flash Lite

by GoogleReasoningClean
Open in new window

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

How it went

Total time
6.1 s
Cost
$0.0037
Output tokens
2,371
Spent thinking
135 tokens
Speed
458.4 tok/s
Console errors
0
First token after
923 ms
First visible text after
923 ms
Prompt tokens
592
Code size
6.9 KB
Finish reason
stop
Served by
Google
Model id
google/gemini-3.1-flash-lite
Reasoning sent
{"effort":"low"}
Max output
65,536 tokens
Generated
Nov 12, 2026

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 · 169 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 Night</title>
    <style>
        body, html { margin: 0; padding: 0; overflow: hidden; background: #050505; }
        #overlay {
            position: absolute; top: 0; left: 0; width: 100%; height: 100%;
            display: flex; justify-content: center; align-items: center;
            background: rgba(0,0,0,0.4); color: white; font-family: sans-serif;
            pointer-events: none; opacity: 1; transition: opacity 0.5s;
        }
    </style>
    <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>
</head>
<body>
    <div id="overlay">Click or press any key to start</div>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

        // State
        let started = false;
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        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);

        scene.background = new THREE.Color(0x020205);
        scene.fog = new THREE.FogExp2(0x020205, 0.08);

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

        const moonLight = new THREE.DirectionalLight(0xaaaaff, 0.2);
        moonLight.position.set(10, 20, 10);
        scene.add(moonLight);

        const fireLight = new THREE.PointLight(0xffaa33, 2, 15);
        fireLight.position.set(0, 0.5, 0);
        fireLight.castShadow = true;
        scene.add(fireLight);

        // Camera & Controls
        camera.position.set(5, 5, 8);
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.minPolarAngle = 0.5;
        controls.maxPolarAngle = 1.4;
        controls.enableDamping = true;

        // Ground
        const groundGeo = new THREE.CircleGeometry(20, 32);
        const groundMat = new THREE.MeshStandardMaterial({ color: 0x1a241a });
        const ground = new THREE.Mesh(groundGeo, groundMat);
        ground.rotation.x = -Math.PI / 2;
        ground.receiveShadow = true;
        scene.add(ground);

        // Trees (Low Poly)
        function createTree() {
            const group = new THREE.Group();
            const trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.3, 1), new THREE.MeshStandardMaterial({ color: 0x4d3319 }));
            trunk.position.y = 0.5;
            trunk.castShadow = true;
            group.add(trunk);
            const leaves = new THREE.Mesh(new THREE.ConeGeometry(0.8, 1.5, 5), new THREE.MeshStandardMaterial({ color: 0x1a331a }));
            leaves.position.y = 1.5;
            leaves.castShadow = true;
            group.add(leaves);
            return group;
        }

        for (let i = 0; i < 40; i++) {
            const tree = createTree();
            const angle = Math.random() * Math.PI * 2;
            const dist = 6 + Math.random() * 12;
            tree.position.x = Math.cos(angle) * dist;
            tree.position.z = Math.sin(angle) * dist;
            tree.scale.setScalar(0.8 + Math.random() * 0.8);
            scene.add(tree);
        }

        // Logs around fire
        for(let i=0; i<6; i++) {
            const log = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.15, 1.2), new THREE.MeshStandardMaterial({ color: 0x3d2b1f }));
            const angle = (i / 6) * Math.PI * 2;
            log.position.set(Math.cos(angle) * 0.8, 0.3, Math.sin(angle) * 0.8);
            log.rotation.z = Math.PI / 2;
            log.rotation.y = angle;
            log.castShadow = true;
            scene.add(log);
        }

        // Fire
        const flame = new THREE.Mesh(new THREE.ConeGeometry(0.4, 0.8, 4), new THREE.MeshBasicMaterial({ color: 0xff6600, transparent: true, opacity: 0.8 }));
        flame.position.y = 0.4;
        scene.add(flame);

        // Sparks
        const sparkCount = 50;
        const sparkGeo = new THREE.BufferGeometry();
        const sparkPos = new Float32Array(sparkCount * 3);
        for(let i=0; i<sparkCount*3; i++) sparkPos[i] = (Math.random() - 0.5) * 0.2;
        sparkGeo.setAttribute('position', new THREE.BufferAttribute(sparkPos, 3));
        const sparkMat = new THREE.PointsMaterial({ color: 0xffaa00, size: 0.05, transparent: true });
        const sparks = new THREE.Points(sparkGeo, sparkMat);
        scene.add(sparks);

        // Stars
        const starGeo = new THREE.BufferGeometry();
        const starPos = [];
        for(let i=0; i<500; i++) {
            starPos.push((Math.random() - 0.5) * 100, Math.random() * 50, (Math.random() - 0.5) * 100);
        }
        starGeo.setAttribute('position', new THREE.Float32BufferAttribute(starPos, 3));
        const stars = new THREE.Points(starGeo, new THREE.PointsMaterial({ color: 0xffffff, size: 0.1 }));
        scene.add(stars);

        // Input
        const start = () => { if(!started) { started = true; document.getElementById('overlay').style.opacity = 0; } };
        window.addEventListener('keydown', start);
        window.addEventListener('mousedown', start);

        // Animation Loop
        const clock = new THREE.Clock();
        function animate() {
            requestAnimationFrame(animate);
            const t = clock.getElapsedTime();

            if(started) {
                // Flickering fire
                fireLight.intensity = 2 + Math.sin(t * 10) * 0.5;
                flame.scale.set(1 + Math.sin(t * 8) * 0.1, 1 + Math.cos(t * 12) * 0.2, 1 + Math.sin(t * 8) * 0.1);
                
                // Spark animation
                const pos = sparks.geometry.attributes.position;
                for(let i=0; i<sparkCount; i++) {
                    pos.array[i*3 + 1] += 0.02;
                    pos.array[i*3 + 0] += Math.sin(t + i) * 0.005;
                    if(pos.array[i*3 + 1] > 2) pos.array[i*3 + 1] = 0;
                }
                pos.needsUpdate = true;
            } else {
                // Auto-demo rotation if not started
                camera.position.x = Math.cos(t * 0.1) * 8;
                camera.position.z = Math.sin(t * 0.1) * 8;
                camera.lookAt(0, 0, 0);
            }

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

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