Models 44

Claude Opus 5.5

by Anthropicreasoning defaultClean
Open in new window

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

How it went

Total time
46.0 s
Cost
$0.122
Output tokens
5,943
Spent thinking
0 tokens
Speed
132.6 tok/s
Console errors
0
First token after
1.1 s
First visible text after
1.1 s
Prompt tokens
855
Code size
10.3 KB
Finish reason
stop
Served by
Claude Platform on AWS
Model id
anthropic/claude-opus-5.5
Reasoning sent
model default
Max output
128,000 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 · 241 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Low-Poly Campfire at Night</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#05070f;font-family:system-ui,sans-serif}
canvas{display:block}
#info{position:fixed;left:12px;bottom:12px;color:#d9c7a8;font-size:13px;background:rgba(0,0,0,.35);padding:6px 10px;border-radius:6px;pointer-events:none}
</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="info">Drag to orbit · Scroll to zoom</div>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
renderer.setSize(innerWidth,innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x070a18);
scene.fog = new THREE.FogExp2(0x070a18, 0.035);

const camera = new THREE.PerspectiveCamera(55, innerWidth/innerHeight, 0.1, 500);
camera.position.set(9,5,11);

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0,1,0);
controls.enableDamping = true;
controls.minDistance = 4;
controls.maxDistance = 30;
controls.maxPolarAngle = Math.PI*0.47;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.4;
controls.addEventListener('start',()=>controls.autoRotate=false);

// seeded random
let seed = 12345;
const rnd = ()=>{seed=(seed*16807)%2147483647;return (seed-1)/2147483646;};

// lights
scene.add(new THREE.HemisphereLight(0x3a4a7a, 0x0a0a10, 0.35));
const moonLight = new THREE.DirectionalLight(0x8fa8ff, 0.35);
moonLight.position.set(-30,40,-20);
scene.add(moonLight);

const fireLight = new THREE.PointLight(0xff8a3a, 30, 40, 1.6);
fireLight.position.set(0,1.2,0);
fireLight.castShadow = true;
fireLight.shadow.mapSize.set(1024,1024);
fireLight.shadow.camera.near = 0.3;
fireLight.shadow.bias = -0.003;
scene.add(fireLight);

// ground
const gGeo = new THREE.PlaneGeometry(120,120,60,60);
gGeo.rotateX(-Math.PI/2);
const gp = gGeo.attributes.position;
for(let i=0;i<gp.count;i++){
  const x=gp.getX(i), z=gp.getZ(i), d=Math.hypot(x,z);
  const h = d<6?0:(Math.sin(x*0.3)*Math.cos(z*0.25)*0.5 + rnd()*0.3)*Math.min(1,(d-6)/6);
  gp.setY(i,h);
}
gGeo.computeVertexNormals();
const ground = new THREE.Mesh(gGeo.toNonIndexed(), new THREE.MeshStandardMaterial({color:0x2b3a22, flatShading:true, roughness:1}));
ground.geometry.computeVertexNormals();
ground.receiveShadow = true;
scene.add(ground);

// clearing dirt patch
const dirt = new THREE.Mesh(new THREE.CircleGeometry(3.2,10), new THREE.MeshStandardMaterial({color:0x3b2c1e, flatShading:true, roughness:1}));
dirt.rotation.x=-Math.PI/2; dirt.position.y=0.01; dirt.receiveShadow=true;
scene.add(dirt);

// rocks
const rockMat = new THREE.MeshStandardMaterial({color:0x6b6b70, flatShading:true, roughness:0.9});
function makeRock(s){
  const g = new THREE.DodecahedronGeometry(s,0);
  const p=g.attributes.position;
  for(let i=0;i<p.count;i++) p.setXYZ(i,p.getX(i)*(0.8+rnd()*0.4),p.getY(i)*(0.6+rnd()*0.3),p.getZ(i)*(0.8+rnd()*0.4));
  g.computeVertexNormals();
  const m=new THREE.Mesh(g,rockMat); m.castShadow=m.receiveShadow=true; return m;
}
// fire ring
for(let i=0;i<10;i++){
  const a=i/10*Math.PI*2, r=makeRock(0.28+rnd()*0.1);
  r.position.set(Math.cos(a)*1.05,0.12,Math.sin(a)*1.05);
  r.rotation.set(rnd()*3,rnd()*3,rnd()*3);
  scene.add(r);
}
for(let i=0;i<8;i++){
  const a=rnd()*Math.PI*2, d=3.5+rnd()*4, r=makeRock(0.3+rnd()*0.6);
  r.position.set(Math.cos(a)*d,0.15,Math.sin(a)*d);
  r.rotation.y=rnd()*6; scene.add(r);
}

// logs
const barkMat = new THREE.MeshStandardMaterial({color:0x5a3a22, flatShading:true, roughness:1});
const endMat = new THREE.MeshStandardMaterial({color:0xa8804f, flatShading:true});
function makeLog(len,rad){
  const m=new THREE.Mesh(new THREE.CylinderGeometry(rad,rad*1.05,len,7),[barkMat,endMat,endMat]);
  m.castShadow=m.receiveShadow=true; return m;
}
// seating logs
[[0,3.2,0],[2.3*1,2.3,Math.PI/4*-1],[-3,0.6,Math.PI/2*0.85]].forEach(([x,z,ry],i)=>{
  const l=makeLog(2.4,0.28); l.rotation.z=Math.PI/2; 
  const g=new THREE.Group(); g.add(l); g.position.set(x,0.28,z);
  g.rotation.y = Math.atan2(x,z)+Math.PI/2; scene.add(g);
});
// fire logs teepee
const charMat = new THREE.MeshStandardMaterial({color:0x2a1a10, flatShading:true, emissive:0x220800});
for(let i=0;i<6;i++){
  const a=i/6*Math.PI*2;
  const l=new THREE.Mesh(new THREE.CylinderGeometry(0.07,0.1,1.3,6),charMat);
  l.castShadow=true;
  l.position.set(Math.cos(a)*0.3,0.5,Math.sin(a)*0.3);
  l.lookAt(0,2,0); l.rotateX(Math.PI/2);
  scene.add(l);
}
// embers bed
const ember = new THREE.Mesh(new THREE.CircleGeometry(0.65,8), new THREE.MeshBasicMaterial({color:0xff4a10}));
ember.rotation.x=-Math.PI/2; ember.position.y=0.03; scene.add(ember);

// trees
const trunkMat = new THREE.MeshStandardMaterial({color:0x4a3020, flatShading:true});
const leafMats = [0x1f4a2a,0x23552e,0x1a3f28,0x2d5a30].map(c=>new THREE.MeshStandardMaterial({color:c, flatShading:true, roughness:1}));
const trees=[];
let placed=0, tries=0;
while(placed<70 && tries<2000){
  tries++;
  const a=rnd()*Math.PI*2, d=8+Math.pow(rnd(),0.8)*40;
  const x=Math.cos(a)*d, z=Math.sin(a)*d;
  if(trees.some(t=>Math.hypot(t.x-x,t.z-z)<2.2)) continue;
  trees.push({x,z}); placed++;
  const s=0.8+rnd()*0.9, g=new THREE.Group();
  const trunk=new THREE.Mesh(new THREE.CylinderGeometry(0.15*s,0.25*s,1.4*s,6),trunkMat);
  trunk.position.y=0.7*s; trunk.castShadow=true; g.add(trunk);
  const mat=leafMats[Math.floor(rnd()*leafMats.length)];
  const layers=3+Math.floor(rnd()*2);
  for(let k=0;k<layers;k++){
    const r=(1.6-k*0.35)*s, h=(1.8-k*0.2)*s;
    const c=new THREE.Mesh(new THREE.ConeGeometry(r,h,7),mat);
    c.position.y=(1.4+k*0.9)*s+h/2-0.3*s; c.rotation.y=rnd()*3;
    c.castShadow=true; c.receiveShadow=true; g.add(c);
  }
  g.position.set(x,0,z); g.rotation.y=rnd()*6; g.rotation.z=(rnd()-0.5)*0.08;
  scene.add(g);
}

// sky: stars
const starCount=1500, sp=new Float32Array(starCount*3);
for(let i=0;i<starCount;i++){
  const th=rnd()*Math.PI*2, ph=Math.acos(rnd()*0.95);
  const R=200;
  sp[i*3]=R*Math.sin(ph)*Math.cos(th); sp[i*3+1]=R*Math.cos(ph); sp[i*3+2]=R*Math.sin(ph)*Math.sin(th);
}
const starGeo=new THREE.BufferGeometry(); starGeo.setAttribute('position',new THREE.BufferAttribute(sp,3));
const stars=new THREE.Points(starGeo,new THREE.PointsMaterial({color:0xffffff,size:1.3,sizeAttenuation:false,fog:false,transparent:true,opacity:0.9}));
scene.add(stars);

// moon
const moon=new THREE.Mesh(new THREE.IcosahedronGeometry(8,1),new THREE.MeshBasicMaterial({color:0xf2efd8,fog:false}));
moon.position.set(-90,110,-120); scene.add(moon);
const glowTex=(()=>{const c=document.createElement('canvas');c.width=c.height=128;const x=c.getContext('2d');
  const g=x.createRadialGradient(64,64,0,64,64,64);g.addColorStop(0,'rgba(255,255,255,1)');g.addColorStop(0.3,'rgba(255,255,255,.5)');g.addColorStop(1,'rgba(255,255,255,0)');
  x.fillStyle=g;x.fillRect(0,0,128,128);return new THREE.CanvasTexture(c);})();
const moonGlow=new THREE.Sprite(new THREE.SpriteMaterial({map:glowTex,color:0x9fb0ff,transparent:true,opacity:0.5,fog:false,depthWrite:false}));
moonGlow.scale.set(60,60,1); moonGlow.position.copy(moon.position); scene.add(moonGlow);

// flames
const flames=[];
const flameCols=[0xffe066,0xffa62b,0xff5a1f];
for(let i=0;i<9;i++){
  const layer=i%3;
  const m=new THREE.Mesh(new THREE.ConeGeometry(0.28-layer*0.06,1.1-layer*0.25,5),
    new THREE.MeshBasicMaterial({color:flameCols[2-layer],transparent:true,opacity:0.85,blending:THREE.AdditiveBlending,depthWrite:false}));
  const a=i*2.4, r=layer===2?0:0.15+rnd()*0.12;
  m.userData={bx:Math.cos(a)*r,bz:Math.sin(a)*r,ph:rnd()*10,sp:6+rnd()*4,h:1.1-layer*0.25};
  scene.add(m); flames.push(m);
}
const fireGlow=new THREE.Sprite(new THREE.SpriteMaterial({map:glowTex,color:0xff7a2a,transparent:true,opacity:0.6,blending:THREE.AdditiveBlending,depthWrite:false}));
fireGlow.scale.set(4,4,1); fireGlow.position.set(0,0.9,0); scene.add(fireGlow);

// sparks
const SP=250, spPos=new Float32Array(SP*3), spVel=[], spLife=new Float32Array(SP);
function resetSpark(i,init){
  spPos[i*3]=(rnd()-0.5)*0.5; spPos[i*3+1]=0.3+(init?rnd()*4:0); spPos[i*3+2]=(rnd()-0.5)*0.5;
  spVel[i]={x:(rnd()-0.5)*0.4,y:1+rnd()*1.8,z:(rnd()-0.5)*0.4};
  spLife[i]=init?rnd()*3:2+rnd()*2.5;
}
for(let i=0;i<SP;i++) resetSpark(i,true);
const spGeo=new THREE.BufferGeometry(); spGeo.setAttribute('position',new THREE.BufferAttribute(spPos,3));
const sparks=new THREE.Points(spGeo,new THREE.PointsMaterial({color:0xffaa44,size:0.09,map:glowTex,transparent:true,blending:THREE.AdditiveBlending,depthWrite:false}));
scene.add(sparks);

const clock=new THREE.Clock();
function animate(){
  const dt=Math.min(clock.getDelta(),0.05), t=clock.elapsedTime;
  // flames
  flames.forEach(f=>{
    const u=f.userData, s=0.8+0.25*Math.sin(t*u.sp+u.ph)+0.1*Math.sin(t*u.sp*2.3);
    f.scale.set(1+0.1*Math.sin(t*7+u.ph),s,1+0.1*Math.cos(t*5+u.ph));
    f.position.set(u.bx+Math.sin(t*3+u.ph)*0.04,0.25+u.h*s/2,u.bz+Math.cos(t*2.6+u.ph)*0.04);
    f.rotation.y=t*0.8+u.ph;
  });
  const flick=0.75+0.15*Math.sin(t*9)+0.1*Math.sin(t*23.7)+0.08*Math.sin(t*4.1);
  fireLight.intensity=30*flick;
  fireLight.position.x=Math.sin(t*5)*0.06; fireLight.position.z=Math.cos(t*6.3)*0.06;
  fireGlow.material.opacity=0.45+0.2*flick;
  ember.material.color.setRGB(1,0.25+0.1*flick,0.05);
  // sparks
  for(let i=0;i<SP;i++){
    spLife[i]-=dt;
    if(spLife[i]<=0||spPos[i*3+1]>7){resetSpark(i,false);continue;}
    const v=spVel[i];
    v.x+=Math.sin(t*2+i)*dt*0.5; v.z+=Math.cos(t*1.7+i)*dt*0.5;
    spPos[i*3]+=v.x*dt; spPos[i*3+1]+=v.y*dt; spPos[i*3+2]+=v.z*dt;
  }
  spGeo.attributes.position.needsUpdate=true;
  stars.material.opacity=0.8+0.1*Math.sin(t*1.3);
  controls.update();
  renderer.render(scene,camera);
  requestAnimationFrame(animate);
}
animate();

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