Interactive 3D aquariumOne-line
Gemini 3.1 Flash Lite
by GoogleReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 3.1 s
- Cost
- $0.0019
- Output tokens
- 1,195
- Spent thinking
- 0 tokens
- Speed
- 453.2 tok/s
- Console errors
- 0
- First token after
- 457 ms
- First visible text after
- 457 ms
- Prompt tokens
- 448
- Code size
- 4.0 KB
- Finish reason
- stop
- Served by
- Model id
google/gemini-3.1-flash-lite- Reasoning sent
model default- Max output
- 65,536 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 · 105 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: #001f3f; font-family: sans-serif; }
#overlay {
position: absolute; top: 0; width: 100%; height: 100%;
display: flex; justify-content: center; align-items: center;
color: white; background: rgba(0,0,0,0.4); cursor: pointer;
z-index: 10; transition: opacity 0.5s;
}
canvas { display: block; }
</style>
</head>
<body>
<div id="overlay"><h1>Click to Enter Aquarium</h1></div>
<script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js"}}</script>
<script type="module">
import * as THREE from 'three';
let scene, camera, renderer, fish = [], mouse = new THREE.Vector2(100, 100);
let started = false;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x002b36);
document.body.appendChild(renderer.domElement);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);
scene.add(new THREE.AmbientLight(0x404040, 2));
// Create simple "fish"
for(let i=0; i<15; i++) {
const group = new THREE.Group();
const body = new THREE.Mesh(
new THREE.ConeGeometry(0.2, 0.5, 8),
new THREE.MeshStandardMaterial({color: Math.random() * 0xffffff})
);
body.rotation.x = Math.PI/2;
group.add(body);
group.position.set((Math.random()-0.5)*15, (Math.random()-0.5)*10, (Math.random()-0.5)*5);
group.userData = { velocity: new THREE.Vector3((Math.random()-0.5)*0.05, (Math.random()-0.5)*0.05, 0) };
scene.add(group);
fish.push(group);
}
window.addEventListener('mousemove', (e) => {
mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
});
document.getElementById('overlay').addEventListener('click', () => {
document.getElementById('overlay').style.opacity = '0';
setTimeout(() => document.getElementById('overlay').style.display = 'none', 500);
started = true;
});
animate();
}
function animate() {
requestAnimationFrame(animate);
const vector = new THREE.Vector3(mouse.x, mouse.y, 0).unproject(camera);
fish.forEach(f => {
f.position.add(f.userData.velocity);
// Repel from mouse
const dist = f.position.distanceTo(vector);
if(dist < 3) {
const dir = f.position.clone().sub(vector).normalize();
f.userData.velocity.add(dir.multiplyScalar(0.01));
}
// Keep inside bounds
if(Math.abs(f.position.x) > 8) f.userData.velocity.x *= -1;
if(Math.abs(f.position.y) > 6) f.userData.velocity.y *= -1;
// Face direction
f.lookAt(f.position.clone().add(f.userData.velocity));
});
// Demo movement
if(!started) {
mouse.x = Math.sin(Date.now() * 0.001) * 0.5;
mouse.y = Math.cos(Date.now() * 0.001) * 0.5;
}
renderer.render(scene, camera);
}
init();
</script>
</body>
</html>