Claude Haiku 4.5
by AnthropicReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 13.6 s
- Cost
- $0.021
- Output tokens
- 4,119
- Spent thinking
- 0 tokens
- Speed
- 321 tok/s
- Console errors
- 0
- First token after
- 724 ms
- First visible text after
- 724 ms
- Prompt tokens
- 614
- Code size
- 12.1 KB
- Finish reason
- stop
- Served by
- Amazon Bedrock
- Model id
anthropic/claude-haiku-4.5- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 10, 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 · 322 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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100vh;
overflow: hidden;
background: #000;
font-family: Arial, sans-serif;
}
canvas {
display: block;
width: 100%;
height: 100%;
}
#info {
position: absolute;
top: 20px;
left: 20px;
color: #fff;
font-size: 14px;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 8px;
max-width: 300px;
z-index: 10;
}
</style>
</head>
<body>
<div id="info">
<strong>Low-Poly Campfire Scene</strong><br>
Use mouse to rotate view<br>
Scroll to zoom in/out
</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';
// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0a1a);
scene.fog = new THREE.Fog(0x0a0a1a, 80, 150);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(30, 20, 30);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowShadowMap;
document.body.appendChild(renderer.domElement);
// Lighting
const ambientLight = new THREE.AmbientLight(0x1a1a2e, 0.3);
scene.add(ambientLight);
// Flickering campfire light
const fireLight = new THREE.PointLight(0xff6600, 1.5, 50);
fireLight.position.set(0, 3, 0);
fireLight.castShadow = true;
fireLight.shadow.mapSize.width = 2048;
fireLight.shadow.mapSize.height = 2048;
fireLight.shadow.camera.near = 0.5;
fireLight.shadow.camera.far = 100;
scene.add(fireLight);
// Moon
const moonGeometry = new THREE.SphereGeometry(20, 32, 32);
const moonMaterial = new THREE.MeshBasicMaterial({ color: 0xeeeeee });
const moon = new THREE.Mesh(moonGeometry, moonMaterial);
moon.position.set(-100, 80, -100);
scene.add(moon);
// Stars
const starsGeometry = new THREE.BufferGeometry();
const starsMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.5 });
const starsVertices = [];
for (let i = 0; i < 200; i++) {
const x = (Math.random() - 0.5) * 400;
const y = Math.random() * 150 + 50;
const z = (Math.random() - 0.5) * 400;
starsVertices.push(x, y, z);
}
starsGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(starsVertices), 3));
const stars = new THREE.Points(starsGeometry, starsMaterial);
scene.add(stars);
// Ground
const groundGeometry = new THREE.PlaneGeometry(200, 200);
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0x2a3a2a });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
// Helper function to create low-poly trees
function createLowPolyTree(x, z) {
const trunkGeometry = new THREE.ConeGeometry(1.5, 12, 4);
const trunkMaterial = new THREE.MeshLambertMaterial({ color: 0x4a3728 });
const trunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
trunk.position.set(x, 6, z);
trunk.castShadow = true;
trunk.receiveShadow = true;
const foliageGeometry = new THREE.ConeGeometry(8, 20, 6);
const foliageMaterial = new THREE.MeshLambertMaterial({ color: 0x1a3a1a });
const foliage = new THREE.Mesh(foliageGeometry, foliageMaterial);
foliage.position.set(x, 18, z);
foliage.castShadow = true;
foliage.receiveShadow = true;
const group = new THREE.Group();
group.add(trunk);
group.add(foliage);
return group;
}
// Plant trees around the clearing (avoid center)
for (let i = 0; i < 35; i++) {
let x, z, distance;
do {
x = (Math.random() - 0.5) * 200;
z = (Math.random() - 0.5) * 200;
distance = Math.sqrt(x * x + z * z);
} while (distance < 25); // Keep clear around campfire
const tree = createLowPolyTree(x, z);
scene.add(tree);
}
// Low-poly rocks around campfire
function createRock(x, z, scale = 1) {
const rockGeometry = new THREE.DodecahedronGeometry(2 * scale, 0);
const rockMaterial = new THREE.MeshLambertMaterial({ color: 0x5a5a5a });
const rock = new THREE.Mesh(rockGeometry, rockMaterial);
rock.position.set(x, 2 * scale, z);
rock.rotation.x = Math.random() * Math.PI;
rock.rotation.z = Math.random() * Math.PI;
rock.castShadow = true;
rock.receiveShadow = true;
return rock;
}
scene.add(createRock(-5, -8, 1.2));
scene.add(createRock(8, -5, 0.9));
scene.add(createRock(6, 6, 1.1));
scene.add(createRock(-7, 5, 0.8));
// Logs
function createLog(x, z, rotation = 0) {
const logGeometry = new THREE.CylinderGeometry(1, 1, 12, 6);
const logMaterial = new THREE.MeshLambertMaterial({ color: 0x3a2818 });
const log = new THREE.Mesh(logGeometry, logMaterial);
log.position.set(x, 1, z);
log.rotation.z = rotation;
log.castShadow = true;
log.receiveShadow = true;
return log;
}
scene.add(createLog(-8, 0, 0.3));
scene.add(createLog(8, 0, -0.3));
scene.add(createLog(0, -8, Math.PI / 2));
// Campfire - wooden base and logs
const fireGroupGeometry = new THREE.TetrahedronGeometry(0.5, 1);
const fireGroupMaterial = new THREE.MeshLambertMaterial({ color: 0x8b4513 });
const fireGroup = new THREE.Group();
fireGroup.position.y = 0.2;
// Center fireplace with low-poly logs
for (let i = 0; i < 4; i++) {
const angle = (i / 4) * Math.PI * 2;
const campLogGeometry = new THREE.CylinderGeometry(0.5, 0.5, 6, 4);
const campLogMaterial = new THREE.MeshLambertMaterial({ color: 0x5a3a2a });
const campLog = new THREE.Mesh(campLogGeometry, campLogMaterial);
campLog.position.x = Math.cos(angle) * 2.5;
campLog.position.z = Math.sin(angle) * 2.5;
campLog.rotation.z = 0.5;
campLog.castShadow = true;
campLog.receiveShadow = true;
fireGroup.add(campLog);
}
scene.add(fireGroup);
// Flames (animated)
const flameGroup = new THREE.Group();
flameGroup.position.set(0, 3, 0);
function createFlame(offsetX = 0, offsetZ = 0, scale = 1) {
const flameGeometry = new THREE.ConeGeometry(1.5 * scale, 5 * scale, 4);
const flameMaterial = new THREE.MeshBasicMaterial({ color: 0xff6633 });
const flame = new THREE.Mesh(flameGeometry, flameMaterial);
flame.position.set(offsetX, 0, offsetZ);
flame.scale.y = 0.8;
return flame;
}
const flame1 = createFlame(0, 0, 0.8);
const flame2 = createFlame(1, 0.5, 0.6);
const flame3 = createFlame(-1, -0.5, 0.7);
flameGroup.add(flame1);
flameGroup.add(flame2);
flameGroup.add(flame3);
scene.add(flameGroup);
// Particle system for sparks
const particlesGeometry = new THREE.BufferGeometry();
const particleCount = 150;
const positionArray = new Float32Array(particleCount * 3);
const velocityArray = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount * 3; i += 3) {
positionArray[i] = (Math.random() - 0.5) * 2;
positionArray[i + 1] = Math.random() * 2;
positionArray[i + 2] = (Math.random() - 0.5) * 2;
velocityArray[i] = (Math.random() - 0.5) * 0.1;
velocityArray[i + 1] = Math.random() * 0.15 + 0.05;
velocityArray[i + 2] = (Math.random() - 0.5) * 0.1;
}
particlesGeometry.setAttribute('position', new THREE.BufferAttribute(positionArray, 3));
const particlesMaterial = new THREE.PointsMaterial({
color: 0xffaa33,
size: 0.15,
sizeAttenuation: true
});
const particles = new THREE.Points(particlesGeometry, particlesMaterial);
particles.position.y = 3;
scene.add(particles);
// OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 5, 0);
controls.minDistance = 15;
controls.maxDistance = 100;
controls.maxPolarAngle = Math.PI * 0.9;
controls.minPolarAngle = Math.PI * 0.1;
controls.autoRotate = false;
controls.update();
// Animation loop
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const elapsedTime = clock.getElapsedTime();
// Animate flames
flame1.scale.y = 0.8 + Math.sin(elapsedTime * 3) * 0.2;
flame1.position.y = Math.sin(elapsedTime * 2.5) * 0.3;
flame2.scale.y = 0.6 + Math.sin(elapsedTime * 3.5 + 1) * 0.15;
flame2.position.y = Math.cos(elapsedTime * 2.8 + 0.5) * 0.2;
flame3.scale.y = 0.7 + Math.sin(elapsedTime * 3.2 + 2) * 0.18;
flame3.position.y = Math.cos(elapsedTime * 2.3 + 1) * 0.25;
// Flicker fire light
fireLight.intensity = 1.5 + Math.sin(elapsedTime * 2) * 0.3 + Math.sin(elapsedTime * 5) * 0.2;
fireLight.color.setHSL(0.05, 1, 0.5 + Math.sin(elapsedTime * 2) * 0.1);
// Animate particles
const positions = particles.geometry.attributes.position.array;
for (let i = 0; i < particleCount; i++) {
const i3 = i * 3;
positions[i3] += velocityArray[i3];
positions[i3 + 1] += velocityArray[i3 + 1];
positions[i3 + 2] += velocityArray[i3 + 2];
// Gravity and air resistance
velocityArray[i3] *= 0.98;
velocityArray[i3 + 1] -= 0.002;
velocityArray[i3 + 2] *= 0.98;
// Reset particles that go too high
if (positions[i3 + 1] > 10) {
positions[i3] = (Math.random() - 0.5) * 2;
positions[i3 + 1] = 0;
positions[i3 + 2] = (Math.random() - 0.5) * 2;
velocityArray[i3] = (Math.random() - 0.5) * 0.1;
velocityArray[i3 + 1] = Math.random() * 0.15 + 0.05;
velocityArray[i3 + 2] = (Math.random() - 0.5) * 0.1;
}
}
particles.geometry.attributes.position.needsUpdate = true;
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);
});
animate();
</script>
</body>
</html>