Interactive 3D aquariumOne-line
gpt-oss-120b
by OpenAIReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 25.3 s
- Cost
- $0.0004
- Output tokens
- 2,099
- Spent thinking
- 454 tokens
- Speed
- 85.2 tok/s
- Console errors
- 0
- First token after
- 648 ms
- First visible text after
- 6.2 s
- Prompt tokens
- 487
- Code size
- 5.8 KB
- Finish reason
- stop
- Served by
- AkashML
- Model id
openai/gpt-oss-120b- Reasoning sent
{"effort":"medium"}- Max output
- 64,000 tokens
- Generated
- Nov 11, 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 · 207 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Three.js 3D Aquarium Demo</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#001e3c;font-family:sans-serif;}
#overlay{
position:absolute;top:0;left:0;width:100%;height:100%;
display:flex;align-items:center;justify-content:center;
background:rgba(0,0,0,0.6);color:#fff;font-size:1.5rem;
cursor:pointer;user-select:none;z-index:10;
}
canvas{display:block;}
</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';
let scene, camera, renderer, controls;
let fishGroup = [];
const FISH_COUNT = 30;
const AQUA_SIZE = 40;
let raycaster, mouse = new THREE.Vector2();
let started = false;
// ---------- Init ----------
init();
animate();
function init() {
// Scene & Camera
scene = new THREE.Scene();
scene.background = new THREE.Color(0x001e3c);
camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 200);
camera.position.set(0, 15, 45);
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
// Controls
controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.07;
// Lights
const ambient = new THREE.AmbientLight(0x888888);
scene.add(ambient);
const dir = new THREE.DirectionalLight(0xffffff, 0.8);
dir.position.set(10, 20, 10);
scene.add(dir);
// Aquarium box
const boxGeo = new THREE.BoxGeometry(AQUA_SIZE, AQUA_SIZE, AQUA_SIZE);
const boxMat = new THREE.MeshPhongMaterial({
color: 0x1e90ff,
transparent: true,
opacity: 0.1,
side: THREE.BackSide,
depthWrite: false
});
const aquarium = new THREE.Mesh(boxGeo, boxMat);
scene.add(aquarium);
// Floor (optional)
const floorGeo = new THREE.PlaneGeometry(AQUA_SIZE, AQUA_SIZE);
const floorMat = new THREE.MeshPhongMaterial({color:0x004466, side:THREE.DoubleSide, transparent:true, opacity:0.3});
const floor = new THREE.Mesh(floorGeo, floorMat);
floor.rotation.x = -Math.PI/2;
floor.position.y = -AQUA_SIZE/2;
scene.add(floor);
// Raycaster
raycaster = new THREE.Raycaster();
// Create fish
const fishGeom = new THREE.ConeGeometry(1, 2.5, 8);
fishGeom.translate(0, -0.5, 0); // pivot at center
const fishMat = new THREE.MeshStandardMaterial({color: 0xffaa33, flatShading:true});
for (let i = 0; i < FISH_COUNT; i++) {
const fish = new THREE.Mesh(fishGeom, fishMat.clone());
resetFish(fish);
scene.add(fish);
fishGroup.push({mesh: fish, vel: new THREE.Vector3()});
}
// Event listeners for start
const overlay = document.getElementById('overlay');
const start = () => {
if (!started) {
started = true;
overlay.style.display = 'none';
}
};
overlay.addEventListener('click', start);
window.addEventListener('keydown', start);
}
// ---------- Helpers ----------
function resetFish(fish) {
fish.position.set(
THREE.MathUtils.randFloatSpread(AQUA_SIZE * 0.8),
THREE.MathUtils.randFloatSpread(AQUA_SIZE * 0.8),
THREE.MathUtils.randFloatSpread(AQUA_SIZE * 0.8)
);
const angle = Math.random() * Math.PI * 2;
fish.rotation.y = angle;
}
// ---------- Animation ----------
function animate() {
requestAnimationFrame(animate);
if (started) {
updateFish();
controls.update();
}
renderer.render(scene, camera);
}
function updateFish() {
// Update mouse ray
raycaster.setFromCamera(mouse, camera);
const ray = raycaster.ray;
const fleeRadius = 4; // world units
fishGroup.forEach(body => {
const fish = body.mesh;
const vel = body.vel;
// Flee behavior
const distSq = ray.distanceSqToPoint(fish.position);
if (distSq < fleeRadius * fleeRadius) {
const pointOnRay = new THREE.Vector3();
ray.closestPointToPoint(fish.position, pointOnRay);
const away = new THREE.Vector3().subVectors(fish.position, pointOnRay).normalize().multiplyScalar(0.6);
vel.add(away);
}
// Simple wandering
if (Math.random() < 0.01) {
const randomDir = new THREE.Vector3(
THREE.MathUtils.randFloatSpread(1),
THREE.MathUtils.randFloatSpread(0.5),
THREE.MathUtils.randFloatSpread(1)
).normalize().multiplyScalar(0.02);
vel.add(randomDir);
}
// Apply drag
vel.multiplyScalar(0.96);
// Move
fish.position.add(vel);
// Keep inside aquarium
const half = AQUA_SIZE/2 - 1;
['x','y','z'].forEach(coord => {
if (fish.position[coord] > half) {
fish.position[coord] = half;
vel[coord] *= -0.5;
} else if (fish.position[coord] < -half) {
fish.position[coord] = -half;
vel[coord] *= -0.5;
}
});
// Orient fish towards movement direction
if (vel.lengthSq() > 0.0001) {
const dir = vel.clone().normalize();
const angle = Math.atan2(dir.x, dir.z);
fish.rotation.y = angle;
// Slight up/down tilt based on vertical velocity
fish.rotation.x = -dir.y * 0.3;
}
});
}
// ---------- Mouse handling ----------
function onMouseMove(event) {
mouse.x = (event.clientX / innerWidth) * 2 - 1;
mouse.y = -(event.clientY / innerHeight) * 2 + 1;
}
window.addEventListener('mousemove', onMouseMove);
// ---------- Resize ----------
function onWindowResize() {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
}
window.addEventListener('resize', onWindowResize);
</script>
</body>
</html>Reasoning trace (454 tokens)
We need to output a single HTML file with importmap and using three.js via modules. Must be self-contained. The requirement: 3D aquarium with fish that swim away when mouse near them. We need to include import map script and then module script that imports three. We'll create a scene with box (aquarium) and some fish objects (simple geometries like tetrahedron or sphere with color). Use basic animation. Detect mouse position in screen, raycast to fish, and if distance less than threshold, apply fleeing behavior (move away). Should have visible on first paint. We must not use external assets, so fish are simple meshes. Make it responsive. We'll include a "Click or press a key to start" overlay message, and hide after click/keypress to start interaction. We must ensure no errors. We'll embed the import map as required. Write HTML with style to make canvas full screen. Implement a simple fish class with position, velocity, and flee behavior. Set initial fish random positions. Add simple water plane maybe. We'll use requestAnimationFrame loop. Add ambient light and directional. Implement mouse move listener only after start? Possibly can start earlier but fish only react after start. Better: initially display overlay message covering screen; after click/keypress, remove overlay and start animation. Make fish flee if mouse world distance less than some radius. To compute world mouse position we can use raycaster intersect with a plane at fish depth (maybe using camera). We'll simply compute mouse direction and project to a point on a sphere? Simpler: for each fish compute distance from fish to ray; if less than threshold, set fish velocity away from point of closest approach. We'll use raycaster: set from camera and mouse coordinates, then compute distance from ray to fish position: using ray.distanceSqToPoint. If less than threshold^2, apply flee. Implement fish update: move according to velocity, apply some damping, confine within aquarium box. Aquarium: a transparent box using BoxGeometry with MeshBasicMaterial with wireframe or transparent material. Make sure canvas uses three's WebGLRenderer with antialias. All fits. Now produce final answer: a single HTML file with importmap script and then a module script. Let's craft code.