Interactive 3D aquariumOne-line
Mistral Small 4
by MistralReasoning1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 12.7 s
- Cost
- $0.0015
- Output tokens
- 2,404
- Spent thinking
- 0 tokens
- Speed
- 196.6 tok/s
- Console errors
- 1
- First token after
- 421 ms
- First visible text after
- 421 ms
- Prompt tokens
- 449
- Code size
- 8.6 KB
- Finish reason
- stop
- Served by
- Mistral
- Model id
mistralai/mistral-small-2603- Reasoning sent
{"effort":"none"}- Max output
- 209,715 tokens
- Generated
- Nov 12, 2026
Console errors
Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.
Failed to load resource: the server responded with a status of 404 ()
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 · 283 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Aquarium</title>
<style>
body {
margin: 0;
overflow: hidden;
background: linear-gradient(to bottom, #1a6bb0, #0d2b45);
font-family: Arial, sans-serif;
}
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 5px;
font-size: 14px;
}
#start {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
background: rgba(0, 0, 0, 0.7);
padding: 20px 40px;
border-radius: 10px;
font-size: 24px;
cursor: pointer;
transition: all 0.3s;
}
#start:hover {
background: rgba(0, 0, 0, 0.9);
}
</style>
</head>
<body>
<div id="info">Move your mouse near fish to scare them away!</div>
<div id="start">Click or press a key to start</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';
import { Water } from 'three/addons/objects/Water.js';
import { Sky } from 'three/addons/objects/Sky.js';
// Scene setup
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.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.screenSpacePanning = false;
controls.maxPolarAngle = Math.PI * 0.9;
controls.minDistance = 5;
controls.maxDistance = 50;
// Water
const waterGeometry = new THREE.PlaneGeometry(1000, 1000);
const water = new Water(
waterGeometry,
{
textureWidth: 512,
textureHeight: 512,
waterNormals: new THREE.TextureLoader().load('https://cdn.jsdelivr.net/npm/three@0.170.0/examples/textures/waternormals.jpg', function(texture) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
sunDirection: new THREE.Vector3(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 3.7,
fog: scene.fog !== undefined
}
);
water.rotation.x = -Math.PI / 2;
scene.add(water);
// Sky
const sky = new Sky();
sky.scale.setScalar(1000);
scene.add(sky);
const skyUniforms = sky.material.uniforms;
skyUniforms['turbidity'].value = 10;
skyUniforms['rayleigh'].value = 2;
skyUniforms['mieCoefficient'].value = 0.005;
skyUniforms['mieDirectionalG'].value = 0.8;
// Sun
const sun = new THREE.Vector3();
const parameters = {
elevation: 2,
azimuth: 180
};
const pmremGenerator = new THREE.PMREMGenerator(renderer);
let renderTarget;
function updateSun() {
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
const theta = THREE.MathUtils.degToRad(parameters.azimuth);
sun.setFromSphericalCoords(1, phi, theta);
sky.material.uniforms['sunPosition'].value.copy(sun);
water.material.uniforms['sunDirection'].value.copy(sun).normalize();
if (renderTarget) renderTarget.dispose();
renderTarget = pmremGenerator.fromScene(sky);
scene.environment = renderTarget.texture;
}
updateSun();
// Fish
const fishGroup = new THREE.Group();
scene.add(fishGroup);
const fishCount = 20;
const fishGeometry = new THREE.ConeGeometry(0.5, 2, 8, 1);
const fishMaterial = new THREE.MeshStandardMaterial({
color: 0xff7f50,
metalness: 0.1,
roughness: 0.3
});
const fish = [];
for (let i = 0; i < fishCount; i++) {
const fishMesh = new THREE.Mesh(fishGeometry, fishMaterial);
fishMesh.position.set(
(Math.random() - 0.5) * 50,
Math.random() * 20 - 10,
(Math.random() - 0.5) * 50
);
fishMesh.rotation.y = Math.random() * Math.PI * 2;
fishMesh.userData = {
speed: 0.05 + Math.random() * 0.1,
direction: new THREE.Vector3(
Math.random() - 0.5,
Math.random() - 0.5,
Math.random() - 0.5
).normalize(),
originalPosition: fishMesh.position.clone(),
scared: false,
scareTime: 0
};
fishMesh.castShadow = true;
fishGroup.add(fishMesh);
fish.push(fishMesh);
}
// Lighting
const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(10, 20, 10);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
scene.add(directionalLight);
// Mouse interaction
const mouse = new THREE.Vector2();
const raycaster = new THREE.Raycaster();
let isInteracting = false;
window.addEventListener('mousemove', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
// Camera position
camera.position.set(0, 10, 30);
// Start screen
const startScreen = document.getElementById('start');
let isStarted = false;
function startDemo() {
if (isStarted) return;
isStarted = true;
startScreen.style.display = 'none';
isInteracting = true;
}
document.addEventListener('click', startDemo);
document.addEventListener('keydown', startDemo);
// Animation loop
function animate() {
requestAnimationFrame(animate);
if (isInteracting) {
// Update mouse raycasting
raycaster.setFromCamera(mouse, camera);
// Check for fish interaction
fish.forEach(f => {
const distance = f.position.distanceTo(camera.position);
if (distance < 15) {
const directionToCamera = new THREE.Vector3().subVectors(camera.position, f.position).normalize();
const angle = directionToCamera.dot(f.userData.direction);
// If fish is looking toward camera and within scare distance
if (angle > 0.7 && distance < 10) {
f.userData.scared = true;
f.userData.scareTime = 30;
}
}
// Update fish behavior
if (f.userData.scared) {
f.userData.scareTime--;
if (f.userData.scareTime <= 0) {
f.userData.scared = false;
}
// Swim away quickly
f.userData.direction = new THREE.Vector3(
Math.random() - 0.5,
Math.random() - 0.5,
Math.random() - 0.5
).normalize().multiplyScalar(0.3);
} else {
// Normal swimming
f.userData.direction.y += (Math.random() - 0.5) * 0.02;
f.userData.direction.normalize();
}
// Move fish
f.position.add(f.userData.direction.clone().multiplyScalar(f.userData.speed));
// Bounce off boundaries
if (f.position.x < -25 || f.position.x > 25) {
f.userData.direction.x *= -1;
f.rotation.y = Math.PI - f.rotation.y;
}
if (f.position.y < -15 || f.position.y > 15) {
f.userData.direction.y *= -1;
}
if (f.position.z < -25 || f.position.z > 25) {
f.userData.direction.z *= -1;
f.rotation.y = -f.rotation.y;
}
// Update rotation to face swimming direction
f.lookAt(f.position.clone().add(f.userData.direction));
});
}
// Update water and sky
water.material.uniforms['time'].value += 0.01;
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>