Qwen3 Coder Next
by Qwenreasoning defaultClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 40.8 s
- Cost
- $0.0033
- Output tokens
- 4,068
- Spent thinking
- 0 tokens
- Speed
- 101 tok/s
- Console errors
- 0
- First token after
- 537 ms
- First visible text after
- 537 ms
- Prompt tokens
- 569
- Code size
- 15.1 KB
- Finish reason
- stop
- Served by
- Parasail
- Model id
qwen/qwen3-coder-next- Reasoning sent
model default- Max output
- 235,929 tokens
- Generated
- Nov 13, 2026
What it was asked
The prompt
Build a low-poly 3D scene of a campfire in a forest clearing at night, with Three.js in a single HTML file. Load Three.js only through this import map (do not use any other URL or version): <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> Requirements: - A ground with a few low-poly rocks and logs around a campfire in the center. - At least 30 low-poly trees placed randomly around the clearing (not on the fire). - The campfire has animated flames and a warm point light that flickers and casts shadows. - Sparks rising from the fire as a simple particle system. - A dark night sky with stars and a moon, plus fog that fades the distant trees. - OrbitControls to look around, with limits so the camera stays above the ground. - The renderer fills the window and handles resizing correctly.
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 · 414 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Low Poly Campfire - Three.js</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #050510;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #ffffff;
}
canvas {
display: block;
}
#loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
font-weight: bold;
text-align: center;
pointer-events: none;
transition: opacity 0.5s;
}
#instruction {
position: absolute;
bottom: 20px;
left: 0;
width: 100%;
text-align: center;
pointer-events: none;
font-size: 14px;
text-shadow: 1px 1px 2px black;
opacity: 0.7;
}
h1 {
margin: 0;
font-size: 1.5rem;
color: #ffccaa;
}
</style>
</head>
<body>
<div id="loading">
<h1>Building the Campfire...</h1>
<p>Generating low-poly environment</p>
</div>
<div id="instruction">Left Click: Rotate | Right Click: Pan | Scroll: Zoom</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';
// --- Configuration ---
const SCENE_CONFIG = {
fogColor: 0x050510,
groundColor: 0x1a1a20,
treeCount: 35,
rockCount: 8,
logCount: 6,
sparkCount: 100
};
// --- Scene Setup ---
const scene = new THREE.Scene();
scene.background = new THREE.Color(SCENE_CONFIG.fogColor);
scene.fog = new THREE.FogExp2(SCENE_CONFIG.fogColor, 0.02);
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(12, 8, 12);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
// --- Controls ---
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 5;
controls.maxDistance = 30;
controls.maxPolarAngle = Math.PI / 2 - 0.1; // Prevent going under ground
controls.target.set(0, 0, 0);
// --- Lighting ---
const ambientLight = new THREE.AmbientLight(0x111111, 1.5); // Dark ambient
scene.add(ambientLight);
const moonLight = new THREE.DirectionalLight(0xaaccff, 1.0);
moonLight.position.set(-10, 20, -10);
moonLight.castShadow = true;
moonLight.shadow.mapSize.width = 1024;
moonLight.shadow.mapSize.height = 1024;
scene.add(moonLight);
// --- The Campfire & Light ---
const fireGroup = new THREE.Group();
scene.add(fireGroup);
// Fire Point Light
const fireLight = new THREE.PointLight(0xffaa00, 10, 25, 1.5);
fireLight.position.set(0, 2.5, 0);
fireLight.castShadow = true;
fireLight.shadow.mapSize.width = 512;
fireLight.shadow.mapSize.height = 512;
fireGroup.add(fireLight);
// Fire Base (Chars)
const charMat = new THREE.MeshStandardMaterial({ color: 0x111111, roughness: 0.9 });
const log1 = new THREE.Mesh(new THREE.CylinderGeometry(0.4, 0.6, 0.3, 6), charMat);
log1.rotation.x = Math.PI / 2;
log1.position.set(0.3, 0.3, 0.2);
fireGroup.add(log1);
const log2 = new THREE.Mesh(new THREE.CylinderGeometry(0.4, 0.6, 0.3, 6), charMat);
log2.rotation.x = Math.PI / 2;
log2.rotation.y = Math.PI / 2;
log2.position.set(-0.3, 0.3, -0.2);
fireGroup.add(log2);
// Wood Base
const woodMat = new THREE.MeshStandardMaterial({ color: 0x5c4033, roughness: 0.8 });
const woodBase = new THREE.Mesh(new THREE.ConeGeometry(1.5, 0.5, 8), woodMat);
woodBase.position.y = 0.25;
fireGroup.add(woodBase);
// The Flames (Animated)
const flameMat = new THREE.MeshStandardMaterial({
color: 0xff5500,
emissive: 0xff3300,
emissiveIntensity: 2,
roughness: 0.5,
transparent: true,
opacity: 0.9,
side: THREE.DoubleSide
});
const innerFlameGeo = new THREE.ConeGeometry(1, 2.5, 6);
const innerFlame = new THREE.Mesh(innerFlameGeo, flameMat);
innerFlame.position.y = 1.5;
fireGroup.add(innerFlame);
const outerFlameGeo = new THREE.ConeGeometry(1.6, 3, 6);
const outerFlame = new THREE.Mesh(outerFlameGeo, flameMat);
outerFlame.position.y = 1.5;
outerFlame.scale.set(0.8, 0.8, 0.8);
fireGroup.add(outerFlame);
// Sparks Particle System
const sparkMat = new THREE.PointsMaterial({
color: 0xffaa00,
size: 0.15,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending
});
const sparkGeometry = new THREE.BufferGeometry();
const sparkCount = SCENE_CONFIG.sparkCount;
const sparkPositions = [];
const sparkVelocities = [];
const sparkLifetimes = [];
for (let i = 0; i < sparkCount; i++) {
sparkPositions.push(0, 2.5, 0);
sparkVelocities.push(
(Math.random() - 0.5) * 0.05,
0.15 + Math.random() * 0.1,
(Math.random() - 0.5) * 0.05
);
sparkLifetimes.push(Math.random() * 2.0 + 1.0);
}
sparkGeometry.setAttribute('position', new THREE.Float32BufferAttribute(sparkPositions, 3));
const sparkSystem = new THREE.Points(sparkGeometry, sparkMat);
fireGroup.add(sparkSystem);
// --- Ground ---
const groundMat = new THREE.MeshStandardMaterial({
color: SCENE_CONFIG.groundColor,
roughness: 1.0,
flatShading: true
});
const ground = new THREE.Mesh(new THREE.PlaneGeometry(60, 60), groundMat);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
// --- Procedural Textures (Canvas) ---
function createTreeTexture() {
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
const ctx = canvas.getContext('2d');
// Dark Green Base
ctx.fillStyle = '#0a1a0a';
ctx.fillRect(0, 0, 256, 256);
// Noise/Pattern
for(let i=0; i<5000; i++){
ctx.fillStyle = Math.random() > 0.5 ? '#0f250f' : '#051005';
ctx.fillRect(Math.random()*256, Math.random()*256, 2, 2);
}
const tex = new THREE.CanvasTexture(canvas);
tex.magFilter = THREE.NearestFilter; // Keep low-poly look
return tex;
}
const treeTexture = createTreeTexture();
const treeMat = new THREE.MeshStandardMaterial({
map: treeTexture,
side: THREE.DoubleSide,
flatShading: true
});
const branchMat = new THREE.MeshStandardMaterial({ color: 0x3d2817, flatShading: true });
// --- Trees ---
const trees = [];
function createTree(x, z) {
const treeGroup = new THREE.Group();
treeGroup.position.set(x, 0, z);
// Trunk
const trunkGeo = new THREE.CylinderGeometry(0.2, 0.3, 1.5, 5);
const trunk = new THREE.Mesh(trunkGeo, branchMat);
trunk.position.y = 0.75;
trunk.castShadow = true;
trunk.receiveShadow = true;
treeGroup.add(trunk);
// Foliage (3 Low Poly Cones)
const foliageColors = [0x0b210b, 0x102b10, 0x061606];
for (let i = 0; i < 3; i++) {
const height = 1.5 - (i * 0.3);
const radius = 1.2 - (i * 0.3);
const yOffset = 1.2 + (i * 0.6);
const foliageGeo = new THREE.ConeGeometry(radius, height, 5);
const foliage = new THREE.Mesh(foliageGeo, treeMat);
foliage.position.y = yOffset;
foliage.castShadow = true;
foliage.receiveShadow = true;
treeGroup.add(foliage);
}
scene.add(treeGroup);
trees.push(treeGroup);
}
// Generate Random Trees
for (let i = 0; i < SCENE_CONFIG.treeCount; i++) {
const angle = Math.random() * Math.PI * 2;
const radius = 5 + Math.random() * 15; // Keep away from center (0,0)
const x = Math.cos(angle) * radius;
const z = Math.sin(angle) * radius;
createTree(x, z);
}
// --- Rocks & Logs ---
const rockMat = new THREE.MeshStandardMaterial({ color: 0x555555, roughness: 1.0, flatShading: true });
const logMat = new THREE.MeshStandardMaterial({ color: 0x3e2723, roughness: 0.9, flatShading: true });
function createRock(x, z) {
const geo = new THREE.DodecahedronGeometry(0.4 + Math.random() * 0.4, 0);
const rock = new THREE.Mesh(geo, rockMat);
rock.position.set(x, 0.3, z);
rock.rotation.set(Math.random()*Math.PI, Math.random()*Math.PI, Math.random()*Math.PI);
rock.scale.setScalar(0.8 + Math.random() * 0.8);
rock.castShadow = true;
rock.receiveShadow = true;
scene.add(rock);
}
function createLog(x, z) {
const geo = new THREE.CylinderGeometry(0.15, 0.2, 1.5, 5);
const log = new THREE.Mesh(geo, logMat);
log.position.set(x, 0.2, z);
log.rotation.x = Math.random() * Math.PI;
log.rotation.y = Math.random() * Math.PI;
log.castShadow = true;
log.receiveShadow = true;
scene.add(log);
}
for (let i = 0; i < SCENE_CONFIG.rockCount; i++) {
const angle = Math.random() * Math.PI * 2;
const radius = 3 + Math.random() * 12;
createRock(Math.cos(angle) * radius, Math.sin(angle) * radius);
}
for (let i = 0; i < SCENE_CONFIG.logCount; i++) {
const angle = Math.random() * Math.PI * 2;
const radius = 2.5 + Math.random() * 8;
createLog(Math.cos(angle) * radius, Math.sin(angle) * radius);
}
// --- Stars ---
const starsGeometry = new THREE.BufferGeometry();
const starCount = 500;
const starPositions = [];
for (let i = 0; i < starCount; i++) {
const x = (Math.random() - 0.5) * 200;
const y = Math.random() * 50 + 10; // Keep above ground
const z = (Math.random() - 0.5) * 200;
starPositions.push(x, y, z);
}
starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starPositions, 3));
const starMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.5, sizeAttenuation: true });
const starField = new THREE.Points(starsGeometry, starMaterial);
scene.add(starField);
// --- Animation Loop ---
let time = 0;
const clock = new THREE.Clock();
// UI State
const loadingDiv = document.getElementById('loading');
setTimeout(() => {
loadingDiv.style.opacity = 0;
setTimeout(() => loadingDiv.remove(), 500);
}, 1000);
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
time += delta;
// 1. Animate Fire Flames
const wave = Math.sin(time * 5) * 0.2;
const flickerScale = 1 + Math.random() * 0.1 - 0.05; // Small random flicker
// Inner Flame
innerFlame.scale.y = 1.0 + Math.sin(time * 8) * 0.2;
innerFlame.scale.x = 1.0 + Math.cos(time * 8) * 0.1;
innerFlame.scale.z = innerFlame.scale.x;
innerFlame.position.y = 1.5 + Math.sin(time * 6) * 0.1;
// Outer Flame
outerFlame.scale.y = 0.9 + Math.sin(time * 6) * 0.15;
outerFlame.position.y = 1.5 + Math.cos(time * 5) * 0.05;
// 2. Animate Fire Light (Flickering)
const flickerIntensity = 10 + Math.sin(time * 15) * 2 + Math.random() * 2;
fireLight.intensity = flickerIntensity;
// Slight color shift for warmth
fireLight.color.setHSL(0.1 + (Math.sin(time * 3) * 0.02), 1.0, 0.5);
// 3. Animate Sparks
const positions = sparkSystem.geometry.attributes.position.array;
for (let i = 0; i < sparkCount; i++) {
// Update Y position
sparkPositions[i * 3 + 1] += sparkVelocities[i * 3 + 1];
// Update X/Z position with slight drift
sparkPositions[i * 3] += sparkVelocities[i * 3];
sparkPositions[i * 3 + 2] += sparkVelocities[i * 3 + 2];
sparkLifetimes[i] -= delta * 0.8;
// Reset spark if it goes too high or too long
if (sparkLifetimes[i] <= 0 || sparkPositions[i * 3 + 1] > 6.0) {
sparkPositions[i * 3] = (Math.random() - 0.5) * 0.5; // Reset to fire center X
sparkPositions[i * 3 + 1] = 2.5; // Reset to fire height
sparkPositions[i * 3 + 2] = (Math.random() - 0.5) * 0.5; // Reset to fire center Z
sparkLifetimes[i] = 2.0;
}
}
sparkSystem.geometry.attributes.position.needsUpdate = true;
// 4. Rotate Trees slightly for wind effect (subtle)
trees.forEach((tree, i) => {
tree.rotation.y = Math.sin(time + i) * 0.02;
});
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);
});
// Start Loop
animate();
</script>
</body>
</html>