Interactive 3D aquariumOne-line
North Mini Code (free)
by CohereReasoning1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 12.1 s
- Cost
- $0
- Output tokens
- 1,914
- Spent thinking
- 0 tokens
- Speed
- 165 tok/s
- Console errors
- 1
- First token after
- 477 ms
- First visible text after
- 477 ms
- Prompt tokens
- 412
- Code size
- 7.4 KB
- Finish reason
- stop
- Served by
- Cohere
- Model id
cohere/north-mini-code:free- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 9, 2026
Console errors
Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.
Identifier 'Scene' has already been declared
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 · 198 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Interactive 3D Aquarium</title>
<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>
<style>
body, html { margin:0; padding:0; width:100%; height:100%; overflow:hidden; background:#000; font-family:sans-serif; }
canvas { display:block; }
#overlay { position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.3); color:#fff; display:flex; flex-direction:column; align-items:center; justify-content:center; pointer-events:none; z-index:5; transition:opacity 0.5s; }
#overlay p { font-size:1.5em; margin:0.5em; text-align:center; max-width:80%; }
#overlay button { padding:0.8em 1.5em; font-size:1.2em; background:#fff; color:#000; border:none; border-radius:8px; cursor:pointer; }
#overlay button:hover { background:#ddd; }
/* Small screens */
@media (max-width: 600px) {
#overlay p { font-size:1.2em; }
#overlay button { font-size:1em; padding:0.6em 1.2em; }
}
</style>
</head>
<body>
<div id="overlay">
<p>Move the mouse near the fish to see them swim away!</p>
<button id="startBtn">Click or press any key to start</button>
</div>
<script type="module">
import { Scene } from 'three';
import { Box, CanvasTexture, Color, DirectionalLight, Fog, HemisphereLight, MathUtils, PerspectiveCamera, Raycaster, Scene, Vector2, Vector3, WebGLRenderer } from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const raycaster = new Raycaster();
const mouse = new Vector2();
let camera, scene, renderer, controls;
const fishList = [];
let animationId;
let started = false;
function init() {
// Hide overlay after start
const overlay = document.getElementById('overlay');
overlay.style.opacity = '0';
document.getElementById('startBtn').remove();
camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
scene = new Scene();
scene.fog = new Fog('#0a0a0a', 50, 200);
const heLight = new HemisphereLight(0xffffff, 0x444444, 2);
heLight.position.set(0, 20, 0);
scene.add(heLight);
const dirLight = new DirectionalLight(0xffffff, 3);
dirLight.position.set(10, 10, 5);
scene.add(dirLight);
renderer = new WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
controls = new OrbitControls(camera, renderer.domElement);
controls.enableZoom = false;
controls.enablePan = false;
// Auto rotate when not interacting
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;
// Lighting for aquarium
const ambient = new Color(0x4d4d4d);
scene.background = new Color(0x001122);
const water = new Color(0x000811);
// Floor
const floorGeo = new Box(100, 0.5, 100);
const floorMat = new MeshStandardMaterial({ color: 0x112233, roughness: 0.9 });
const floor = new Mesh(floorGeo, floorMat);
floor.position.y = -5;
scene.add(floor);
// Load fish models
const loader = new GLTFLoader();
const fishPositions = [
new Vector3(10, 2, 10),
new Vector3(-5, 3, 8),
new Vector3(0, 1, -5),
new Vector3(15, 4, -2),
new Vector3(-8, 2, -12)
];
fishPositions.forEach((pos, i) => {
loader.load('https://cdn.jsdelivr.net/npm/three@0.170.0/examples/models/gltf/Fish.glb', (gltf) => {
const fish = gltf.scene;
fish.scale.setScalar(0.5);
fish.position.copy(pos);
// Random swimming direction
fish.userData.swimDir = new Vector3(Math.random() - 0.5, 0, Math.random() - 0.5).normalize();
fish.userData.swimSpeed = 0.02 + Math.random() * 0.03;
scene.add(fish);
fishList.push(fish);
});
});
camera.position.set(0, 10, 30);
camera.lookAt(0, 0, 0);
animate();
// Event listeners
window.addEventListener('resize', onWindowResize);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('click', startDemo);
document.addEventListener('keydown', startDemo);
}
function startDemo() {
if (!started) {
started = true;
const overlay = document.getElementById('overlay');
overlay.style.pointerEvents = 'none';
overlay.style.opacity = '0';
// Wait a frame for fade
setTimeout(() => overlay.style.display = 'none', 500);
}
}
function onMouseMove(event) {
if (!started) return;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
animationId = requestAnimationFrame(animate);
// Update raycaster
raycaster.setFromCamera(mouse, camera);
// Move fish
fishList.forEach(fish => {
// Swim forward
const move = fish.userData.swimDir.clone().multiplyScalar(fish.userData.swimSpeed);
fish.position.add(move);
fish.rotation.y = Math.atan2(fish.userData.swimDir.x, fish.userData.swimDir.z);
// Check for wall collisions and bounce
const radius = 1;
if (fish.position.x > 25 - radius || fish.position.x < -25 + radius) {
fish.userData.swimDir.x *= -0.8;
fish.userData.swimDir.normalize();
}
if (fish.position.z > 25 - radius || fish.position.z < -25 + radius) {
fish.userData.swimDir.z *= -0.8;
fish.userData.swimDir.normalize();
}
// Ray check for mouse proximity
const v = new Vector3().copy(fish.position).project(camera);
v.x = (v.x * 0.5 + 0.5) * window.innerWidth;
v.y = (1 - (v.y * 0.5 + 0.5)) * window.innerHeight;
const intersect = raycaster.intersectObject(fish);
if (intersect.length > 0 && intersect[0].distance < 5) {
// Swim away from mouse
const awayDir = new Vector3().subVectors(fish.position, new Vector3(mouse.x, mouse.y, 0.5)).normalize();
fish.userData.swimDir.copy(awayDir);
fish.userData.swimSpeed *= 1.5; // speed up
// Reset speed after 2 seconds
setTimeout(() => fish.userData.swimSpeed = 0.02 + Math.random() * 0.03, 2000);
}
});
controls.update();
renderer.render(scene, camera);
}
// Start on any key/click
function startDemoOnInteract() {
startDemo();
}
init();
</script>
</body>
</html>