oneshotlm
Compare all models on this prompt →

3D solar system · qwen3.8-max

Using the pre-provided three.min.js (global THREE), build a 3D solar system with the sun and orbiting planets at varied speeds and sizes, orbit-drag camera controls, and a starfield.

⛨ sandboxed Open in new tab ↗
transcript · 22 messages
user

Using the pre-provided three.min.js (global THREE), build a 3D solar system with the sun and orbiting planets at varied speeds and sizes, orbit-drag camera controls, and a starfield.

assistant
thinking
Build a single index.html containing three.min.js, a solar system, orbital camera controls (custom implementation, no OrbitControls import), and a point-based starfield.

Write the file.
bash {"command":"ls -la /tmp/ws"}
toolResult

total 592 drwxr-sr-x. 2 node node 26 Aug 3 23:53 . drwxrwsrwx. 3 root node 16 Aug 3 23:53 .. -rw-r--r--. 1 node node 603445 Aug 3 23:53 three.min.js

assistant
thinking
Write index.html that includes a complete solar system. Features:
- Sun: emissive sphere + PointLight
- 8 planets with varying sizes and speeds, with orbit rings
- Maybe a moon around the Earth too
- Custom orbit camera: rotate on drag, zoom on wheel
- Starfield: Points with random positions
- Saturn's rings would be nice too
- Labels are optional — keep it simple, maybe show planet names via raycast hover. Keep it moderate: add planet name display on hover, and a speed slider if needed. Keep it robust.
write /tmp/ws/index.html (12750 bytes)
toolResult

Successfully wrote 12750 bytes to /tmp/ws/index.html

assistant
thinking
Quick sanity check — verify that the three.min.js version is compatible with the features being used. Check whether BufferGeometry's setAttribute exists (r110+) and the PointLight decay parameter. Let me grep the three.min.js version.
bash {"command":"head -c 500 /tmp/ws/three.min.js | grep -o 'r[0-9]\\{2,\\}' | head -1; grep -o 'REVISION[^,]*' /tmp/ws/three.min.js | head -1"}
toolResult

REVISION=e

assistant
thinking
That didn't work. Let me try searching for "REVISION:" or "revision".
bash {"command":"grep -oE 'REVISION\\s*[:=]\\s*\"?[0-9a-z]+' /tmp/ws/three.min.js | head -3"}
toolResult

REVISION=e

assistant
thinking
It's minified as a variable. Let's try searching another way: the 'BufferGeometry.prototype.setAttribute' or 'setAttribute' method, and 'CanvasTexture'.
bash {"command":"for t in setAttribute CanvasTexture RingGeometry SphereGeometry LineLoop SpriteMaterial; do printf '%s: %s\\n' \"$t\" \"$(grep -
toolResult

setAttribute: 1 CanvasTexture: 1 RingGeometry: 1 SphereGeometry: 1 LineLoop: 1 SpriteMaterial: 1

assistant
thinking
The name only appears once each — that's probably because minified code registers them like `THREE.SphereGeometry=...`, and the occurrence count is low. But they exist. Let's check if they're attached to THREE (exports). Also, should I check whether it's a newer version that uses the newer light intensity units (r155+ has physically correct lighting by default, PointLight intensity 2.2 with decay 1.6 might be very dark)? In newer three (r155+), useLegacyLights defaults to false, point light intensity is in candela units, and decay 2 is physical. A PointLight with intensity 2.2 at a distance of 66 units would be essentially 2.2/66² ≈ negligible. This would make the planets very dark.

To be safe, boost the point light's intensity substantially and lower the decay, and also rely on the ambient light. Let's detect the version. I'll check for strings like 'useLegacyLights' or 'WebGPURenderer' that indicate a newer version.
bash {"command":"grep -c 'useLegacyLights' /tmp/ws/three.min.js; grep -oE '\"[0-9]{3}\"' /tmp/ws/three.min.js | head -5; grep -oE 'REVISION:\\s*[
toolResult

0 "128" "100"

assistant
thinking
No useLegacyLights — meaning either old (<r150) or it's been minified away. Let's find the REVISION value another way: search for the pattern around the THREE.REVISION assignment, e.g. look for `"1` near the top of the file.
bash {"command":"grep -oE 'REVISION=[a-z]+' /tmp/ws/three.min.js; grep -oE '\\b[a-z]+=\"[0-9]{2,3}\".{0,40}REVISION' /tmp/ws/three.min.js | head
toolResult

REVISION=e

assistant
thinking
REVISION=e, where e is a variable. Find where e is defined near the beginning:
bash {"command":"grep -oE '.{80}REVISION' /tmp/ws/three.min.js | head -2"}
toolResult

t.Quaternion=At,t.QuaternionKeyframeTrack=$o,t.QuaternionLinearInterpolant=Ko,t.REVISION

assistant
thinking
Can't easily tell. Let's just try running it headless — check whether node + a headless browser exist? Probably not available. Safer approach: make the lighting robust regardless of the version:

1. Use a moderate-intensity PointLight, plus a decent ambient light (already 0.55). If this is the physically-based lighting era (r155+), a PointLight intensity of 2.2 with decay 1.6 will produce almost no light contribution. Bump the intensity up high (e.g., 1500, decay 2) — but if it's the old legacy lighting, that would blow out white. Hmm.

Alternative: use DirectionalLight? No, the sun is at the center. Use MeshLambert/Standard... Actually, the simplest and most robust option: check THREE.WebGLRenderer.useLegacyLights at runtime? In older versions this property doesn't exist. Could branch:

```
var intensity = (THREE.PointLight && renderer.useLegacyLights === false) ? 2000 : 2.2;
```

If renderer.useLegacyLights is undefined (old version), use the legacy value. In newer versions (r155–r16x?) useLegacyLights existed until r165? It was removed in r165 (always physically based). In that case renderer.useLegacyLights === undefined again. Hmm.

Better approach: set a decay-independent approach. Actually there's another trick: keep PointLight, but additionally give each planet a small emissive component so it's always visible. Emissive color = planet color * 0.25 guarantees visibility under any lighting regime. And scale the point light intensity dynamically: set intensity in candela-ish units depending on the renderer's capabilities...

The simplest and most robust: try to detect at runtime:
```
var legacy = renderer.useLegacyLights; // r150-r165
```
For older versions (<r150), legacy lighting is the default. For r155+, the default is false. For r165+, the property was removed, and the default is physical.

Detection: if `renderer.useLegacyLights === false`, it's physical. If undefined: either old (legacy) or very new (physical). Hmm, ambiguous.

Alternative robust solution: compute intensity so it looks OK either way — impossible with a single value.

Yet another approach: make the sun's contribution independent of the renderer's lighting mode, by using MeshBasicMaterial or MeshLambert for the planets? Lambert still needs light.

The cleanest is: add a modest emissive per planet, plus two point lights? No.

Actually, let me try harder to detect the revision. Search for strings that differ across versions, like "WebXR", "LinearSRGBColorSpace" (r152+), "sRGBEncoding" (older).
bash {"command":"for s in LinearSRGBColorSpace sRGBEncoding physicallyCorrectLights WebGPURenderer InstancedMesh ColorManagement SpotLightShadow;
toolResult

LinearSRGBColorSpace: 0 sRGBEncoding: 1 physicallyCorrectLights: 1 WebGPURenderer: 0 InstancedMesh: 1 ColorManagement: 0 SpotLightShadow: 1

assistant
thinking
sRGBEncoding exists, but LinearSRGBColorSpace / ColorManagement don't → this is an older three.js (pre-r152), legacy lighting by default, physicallyCorrectLights is opt-in (off). In other words, PointLight intensity 2.2 works fine. The current code is compatible. Also, the existence of setAttribute confirms r110+. Good.

One concern: in older three, PointLight's decay parameter defaults to 1 with distance 0 — if distance is 0, does decay have no effect? In legacy mode with distance=0, there's no distance attenuation at all, so no problem — planets are lit uniformly. Good.

Everything else is compatible. Done — confirm the file exists.

The bundled three.min.js is an older build (r110+, legacy lighting — confirmed by `sRGBEncoding` present, `ColorManagement` absent), so the lighting values I used are correct. Everything's in place:

bash {"command":"ls -la /tmp/ws && node -e \"\nconst fs=require('fs');const h=fs.readFileSync('/tmp/ws/index.html','utf8');\nconst s=h.match(/<sc
toolResult

total 608 drwxr-sr-x. 2 node node 44 Aug 3 23:54 . drwxrwsrwx. 3 root node 16 Aug 3 23:53 .. -rw-r--r--. 1 node node 12750 Aug 3 23:54 index.html -rw-r--r--. 1 node node 603445 Aug 3 23:53 three.min.js JS parses OK

assistant
thinking
The replace trick doesn't really validate that much, but at least Function's syntax parsing succeeded (in reality, `new Function` should throw an exception if the syntax is invalid, but `undefined_check` as an identifier is fine). That's enough.

Done. **`/tmp/ws/index.html`** is a fully self-contained solar system app (no network, loads only the local `three.min.js` via a plain `<script src>`). **Features:** - ☀️ **Sun** — emissive sphere with an additive-blended canvas-texture glow sprite, plus a `PointLight` at the center - 🪐 **8 planets** — varied sizes, colors, orbit radii, and speeds (Mercury fastest, Neptune slowest), each with random starting phase and its own axial spin; Earth has an orbiting Moon, Saturn has rings, faint orbit-path rings for every planet - 🎥 **Orbit-drag camera** — custom spherical-coordinate controls: drag to orbit (azimuth + polar clamped), scroll wheel to zoom, one-finger drag and two-finger pinch zoom on touch devices - ✨ **Starfield** — 3,000 color-varied stars (blue-white, warm, and blue tints) distributed on a large spherical shell, rendered as points with size attenuation off - 🎛️ **HUD extras** — speed slider (0–5×), pause/play button, and raycaster-based hover labels showing the body name under the cursor - Fully responsive (handles window resize), delta-time clamped animation loop so tab-switching doesn't cause jumps

TAKE IT TO CODE

A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.

RUN

modelqwen3.8-max
vendorQwen
harnesspi-agent
generated2026-08-03

EVALUATION

3/5 working

A simple animated solar system simulator with orbiting planets, speed slider, and pause button; scroll/wheel zooms dramatically.

Vision grade · anthropic/claude-sonnet-5

MEASUREMENTS

Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.

idle motion2.4%
on click1.8%
on drag4.3%
on wheel11.0%
on enter + space9.3%
on arrow keys17.1%
on w/a/s/d9.0%
frame spread36.5 / 255
console errors0
js errors none

METRICS

runtime139.0s
tokens in71k
tokens out7.0k
cached55k
cost / run$0.0865