Models 44

GLM 5.3

by Z.aiReasoningClean
Open in new window

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

How it went

Total time
3 min 50 s
Cost
$0.0058
Output tokens
4,076
Spent thinking
106 tokens
Speed
17.8 tok/s
Console errors
0
First token after
1.5 s
First visible text after
17.5 s
Prompt tokens
424
Code size
11.3 KB
Finish reason
stop
Served by
Wafer
Model id
z-ai/glm-5.3
Reasoning sent
model default
Max output
943,718 tokens
Generated
Nov 12, 2026

What it was asked

The prompt
“a 3D aquarium with Three.js where the fish swim away when I move the mouse near them (Load Three.js only through this import map: <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>)”
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 · 316 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Aquarium — move your mouse near the fish</title>
<style>
  html,body{margin:0;height:100%;overflow:hidden;background:#03182a;font-family:Georgia,serif}
  #ui{position:fixed;left:0;right:0;top:0;padding:18px 22px;color:#cfeef7;
      display:flex;justify-content:space-between;align-items:flex-start;pointer-events:none;
      text-shadow:0 1px 6px rgba(0,20,40,.8)}
  h1{font-size:22px;font-weight:400;letter-spacing:.06em;margin:0}
  #hint{font-size:13px;opacity:.75;margin-top:6px;max-width:340px;line-height:1.5}
  #stats{font-size:12px;opacity:.6;text-align:right}
  canvas{display:block}
</style>
</head>
<body>
<div id="ui">
  <div>
    <h1>🐠 The Reef Tank</h1>
    <div id="hint">Move your mouse near the fish and they scatter. Click to lure them with a sprinkle of food.</div>
  </div>
  <div id="stats"></div>
</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';

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

const camera = new THREE.PerspectiveCamera(52, innerWidth/innerHeight, 0.1, 100);
camera.position.set(0, 3.5, 16);
camera.lookAt(0, 0, 0);

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

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.minDistance = 6; controls.maxDistance = 28;
controls.maxPolarAngle = Math.PI * 0.62;

// Lights
scene.add(new THREE.HemisphereLight(0x9fd8ff, 0x0a2a3a, 0.9));
const sun = new THREE.DirectionalLight(0xcaf2ff, 1.4);
sun.position.set(4, 12, 6);
scene.add(sun);

// ---------- Tank ----------
const TANK = {w: 16, h: 9, d: 9}; // half-ish extents used below
const floorY = -4.2, topY = 3.8;

const sand = new THREE.Mesh(
  new THREE.PlaneGeometry(34, 20, 60, 40),
  new THREE.MeshStandardMaterial({color:0xcbb489, roughness:1})
);
const pos = sand.geometry.attributes.position;
for(let i=0;i<pos.count;i++){
  pos.setZ(i, Math.sin(pos.getX(i)*0.5)*0.15 + Math.cos(pos.getY(i)*0.7)*0.1);
}
sand.rotation.x = -Math.PI/2;
sand.position.y = floorY;
scene.add(sand);

// Back glass tint
const backWall = new THREE.Mesh(new THREE.PlaneGeometry(36,22),
  new THREE.MeshStandardMaterial({color:0x0a4a63, roughness:0.9, side:THREE.DoubleSide}));
backWall.position.set(0, 4, -9);
scene.add(backWall);

// Rocks
const rockMat = new THREE.MeshStandardMaterial({color:0x6a7580, roughness:0.95, flatShading:true});
const rockGeo = new THREE.DodecahedronGeometry(1, 0);
[[-6.5,-3.6,0.7,-3],[ -5,-3.8,-2.5,2.2],[6.3,-3.7,-1,2.6],[7.2,-3.8,2,1.6],[0,-3.9,-5,3]].forEach(([x,y,z,s])=>{
  const r = new THREE.Mesh(rockGeo, rockMat);
  r.position.set(x,y,z); r.scale.set(s, s*0.7, s);
  r.rotation.set(Math.random()*3, Math.random()*3, Math.random()*3);
  scene.add(r);
});

// Seaweed
const weeds = [];
const weedMat = new THREE.MeshStandardMaterial({color:0x2e8b57, roughness:0.8, side:THREE.DoubleSide});
for(let i=0;i<26;i++){
  const h = 2.5+Math.random()*3.5;
  const g = new THREE.PlaneGeometry(0.35, h, 1, 8);
  const m = new THREE.Mesh(g, weedMat);
  const x = -9 + Math.random()*18, z = -6 + Math.random()*5;
  m.position.set(x, floorY + h/2, z);
  m.userData = {phase: Math.random()*6.28, baseX:x};
  scene.add(m); weeds.push(m);
}

// Bubbles
const bubbleGeo = new THREE.SphereGeometry(0.07, 8, 8);
const bubbleMat = new THREE.MeshStandardMaterial({color:0xbfe8ff, transparent:true, opacity:0.5, roughness:0.2});
const bubbles = [];
for(let i=0;i<70;i++){
  const b = new THREE.Mesh(bubbleGeo, bubbleMat.clone());
  b.material.opacity = 0.25+Math.random()*0.4;
  b.position.set((Math.random()-0.5)*20, floorY+Math.random()*8, -7+Math.random()*7);
  b.userData = {s: 0.4+Math.random()*1.2, w: Math.random()*6.28};
  scene.add(b); bubbles.push(b);
}

// ---------- Fish ----------
const FISH_COLORS = [0xff8c42, 0xffd166, 0x06d6a0, 0x4cc9f0, 0xf15bb5, 0xfdf0d5, 0xef476f, 0xffb703];
const fishes = [];
const fishCount = 26;

function makeFish(){
  const g = new THREE.Group();
  const color = FISH_COLORS[Math.floor(Math.random()*FISH_COLORS_COLORS_LEN())];
  function FISH_COLORS_COLORS_LEN(){ return FISH_COLORS.length; }
  const s = 0.55 + Math.random()*0.6;
  const mat = new THREE.MeshStandardMaterial({color, roughness:0.5, metalness:0.15, flatShading:true});
  const body = new THREE.Mesh(new THREE.ConeGeometry(0.32*s, 1.1*s, 7), mat);
  body.rotation.z = -Math.PI/2; // point forward +x
  g.add(body);
  const tailMat = new THREE.MeshStandardMaterial({color, roughness:0.6, side:THREE.DoubleSide, flatShading:true});
  const tail = new THREE.Mesh(new THREE.CircleGeometry(0.34*s, 3), tailMat);
  tail.position.x = -0.68*s;
  tail.rotation.y = Math.PI/2;
  g.add(tail);
  const fin = new THREE.Mesh(new THREE.CircleGeometry(0.2*s, 3), tailMat);
  fin.position.set(0.05*s, 0, 0.28*s);
  fin.rotation.x = Math.PI/2;
  g.add(fin);
  // eye
  const eye = new THREE.Mesh(new THREE.SphereGeometry(0.05*s, 6, 6),
    new THREE.MeshStandardMaterial({color:0x111111}));
  eye.position.set(0.36*s, 0.08*s, 0.2*s);
  g.add(eye);
  const eye2 = eye.clone(); eye2.position.z = -0.2*s; g.add(eye2);

  const SPEED = 1.6 + Math.random()*1.6;
  const f = {
    obj: g, vel: new THREE.Vector3((Math.random()-.5), (Math.random()-.5)*.3, (Math.random()-.5)).normalize().multiplyScalar(SPEED),
    speed: SPEED, maxSpeed: SPEED*2.6,
    wiggle: Math.random()*6.28, wander: Math.random()*100,
    scale: s, tail, panicked: 0
  };
  g.position.set((Math.random()-.5)*13, floorY+1+Math.random()*5.5, -5+Math.random()*7);
  g.scale.setScalar(s);
  scene.add(g);
  fishes.push(f);
}

for(let i=0;i<fishCount;i++) makeFish();

// ---------- Interaction ----------
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2(0, 0);
const pointerWorld = new THREE.Vector3(0, 0, 0);
const pointerActive = new THREE.Vector3(1, 0, 0); // strength
let haveMouse = false;

const foodDots = [];
const foodMat = new THREE.MeshBasicMaterial({color:0xffe8b0});
const foodGeo = new THREE.SphereGeometry(0.06, 6, 6);

addEventListener('pointermove', e=>{
  mouse.x = (e.clientX/innerWidth)*2-1;
  mouse.y = -(e.clientY/innerHeight)*2+1;
  haveMouse = true;
});
addEventListener('pointerdown', e=>{
  // sprinkle food at pointer
  raycaster.setFromCamera(new THREE.Vector2((e.clientX/innerWidth)*2-1, -(e.clientY/innerHeight)*2+1), camera);
  const t = new THREE.Vector3().copy(raycaster.ray.direction).normalize();
  const p = raycaster.ray.origin.clone().add(t.multiplyScalar(11));
  p.z = THREE.MathUtils.clamp(p.z, -7.5, 3);
  for(let i=0;i<8;i++){
    const d = new THREE.Mesh(foodGeo, foodMat);
    d.position.copy(p).add(new THREE.Vector3((Math.random()-.5)*0.8, Math.random()*0.5, (Math.random()-.5)*0.5));
    d.userData = {vy: -0.15-Math.random()*0.15, life: 6+Math.random()*4};
    scene.add(d); foodDots.push(d);
  }
});

const clock = new THREE.Clock();
const tmp = new THREE.Vector3();
const desired = new THREE.Vector3();

function steer(f, dt){
  const p = f.obj.position;
  // mouse threat position: project ray into the tank mid-depth
  raycaster.setFromCamera(mouse, camera);
  const dir = raycaster.ray.direction.clone().normalize();
  const cam = raycaster.ray.origin;
  // intersect ray with plane z = p.z (fish's depth) — keeps threat near the fish
  const dz = (p.z - cam.z) / dir.z;
  const mx = cam.x + dir.x*dz, my = cam.y + dir.y*dz;
  pointerWorld.set(THREE.MathUtils.clamp(mx,-11,11), THREE.MathUtils.clamp(my,floorY+.4,topY), p.z);

  const dist = p.distanceTo(pointerWorld);
  let panicked = 0;
  if(haveMouse && dist < 3.2){
    panicked = 1 - dist/3.2;
    desired.copy(p).sub(pointerWorld).normalize().multiplyScalar(f.maxSpeed);
    f.vel.lerp(desired, Math.min(1, panicked*7*dt));
    f.panicked = Math.max(f.panicked, panicked);
  } else {
    f.panicked *= 0.95;
    // wander
    f.wander += dt;
    desired.set(Math.sin(f.wander*0.5)*3, Math.sin(f.wander*0.31)*0.6, Math.cos(f.wander*0.23)*2.4);
    const toCenter = tmp.set(-p.x*0.12, (floorY+3 - p.y)*0.15, (-p.z-2)*0.1);
    desired.add(toCenter);
    // light schooling: drift toward neighbors' average heading
    desired.normalize().multiplyScalar(f.speed);
    f.vel.lerp(desired, dt*1.4);
  }

  // food attraction
  for(const d of foodDots){
    if(p.distanceTo(d.position) < 4.5){
      desired.copy(d.position).sub(p).normalize().multiplyScalar(f.speed*1.8);
      f.vel.lerp(desired, dt*3);
      if(p.distanceTo(d.position) < 0.25){ d.userData.life = 0; }
      break;
    }
  }

  // bounds
  const bx = 13, bz0 = -7.5, bz1 = 3.5;
  if(p.x >  bx) f.vel.x -= 6*dt;
  if(p.x < -bx) f.vel.x += 6*dt;
  if(p.y > topY) f.vel.y -= 5*dt;
  if(p.y < floorY+0.5) f.vel.y += 5*dt;
  if(p.z > bz1) f.vel.z -= 6*dt;
  if(p.z < bz0) f.vel.z += 6*dt;

  f.vel.clampLength(0.3, f.maxSpeed);
  p.addScaledVector(f.vel, dt);

  // orient along velocity
  if(f.vel.lengthSq() > 0.001){
    const targetYaw = Math.atan2(f.vel.y, Math.abs(f.vel.x)) * (f.vel.x >= 0 ? 1 : 0);
    const yaw = Math.atan2(f.vel.z, f.vel.x);
    f.obj.rotation.y = -yaw + (f.vel.x >= 0 ? 0 : 0);
    // If moving backwards, flip so tail follows (keep head forward)
    const pitch = Math.atan2(f.vel.y, Math.hypot(f.vel.x, f.vel.z));
    f.obj.rotation.z = -pitch * Math.sign(f.vel.x || 1);
  }
}

const statsEl = document.getElementById('stats');
let statTimer = 0;

function animate(){
  requestAnimationFrame(animate);
  const dt = Math.min(clock.getDelta(), 0.05);
  const t = clock.elapsedTime;

  // fake "auto demo": wiggle mouse gently until user moves it
  if(!haveMouse){
    mouse.x = Math.sin(t*0.5)*0.55;
    mouse.y = Math.sin(t*0.33)*0.3;
  }

  for(const f of fishes){
    steer(f, dt);
    f.wiggle += dt * (6 + f.vel.length()*4 + f.panicked*14);
    f.tail.rotation.y = Math.PI/2 + Math.sin(f.wiggle)*0.5;
    f.obj.position.y += Math.sin(f.wiggle*0.5)*0.002;
  }

  for(const w of weeds){
    w.rotation.z = Math.sin(t*0.9 + w.userData.phase)*0.18;
  }

  for(let i=bubbles.length-1;i>=0;i--){
    const b = bubbles[i];
    b.position.y += b.userData.s*dt*1.2;
    b.position.x = b.userData.w + Math.sin(t*2 + b.userData.w)*0.25;
    if(b.position.y > topY){ b.position.y = floorY+0.1; b.userData.w = (Math.random()-.5)*20; }
  }

  for(let i=foodDots.length-1;i>=0;i--){
    const d = foodDots[i];
    d.position.y += d.userData.vy*dt;
    d.position.x += Math.sin(t*3+i)*0.05*dt*10;
    if(d.position.y < floorY+0.05) d.position.y = floorY+0.05;
    d.userData.life -= dt;
    if(d.userData.life <= 0){ scene.remove(d); foodDots.splice(i,1); }
  }

  statTimer += dt;
  if(statTimer > 0.5){
    statTimer = 0;
    const panicking = fishes.filter(f=>f.panicked>0.05).length;
    statsEl.textContent = `${fishes.length} fish · ${panicking} startled`;
  }

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

addEventListener('resize', ()=>{
  camera.aspect = innerWidth/innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});
</script>
</body>
</html>
Reasoning trace (106 tokens)
Build a Three.js aquarium: tank, water tint, fish as simple meshes with tail wiggle, boids fleeing from mouse raycast point. Orbit controls optional. Make it pretty: gradient, caustics-ish light, bubbles, seaweed. Responsive. No console errors.

Implement fish with group: body (cone/lathe), tail plane wiggle. Flee behavior with 3D mouse point projected onto plane near fish depth. Also idle wander.

Write compact code.