{
  "slug": "threejs-glb-scene-assembly",
  "skill": "threejs-glb-scene-assembly",
  "upstream": "GameSkill original (onsite/<slug>/original)",
  "sourceHash": "0d19840737c65ac48ee6b8c662e41fc913ccb2c6462639f2f242eb5ce8b72a34",
  "date": "2026-10-28",
  "engine": "three.js r186 (0.186.1) in Chrome 156 headless",
  "env": [
    "Node v20.19.2",
    "three.js r186 and the Draco decoder vendored in vendor/ (no CDN)",
    "puppeteer-core 24 from package-lock.json",
    "Google Chrome 156 headless, WebGL through SwiftShader"
  ],
  "trigger": "static",
  "passed": 40,
  "total": 40,
  "commands": [
    "(cd ../original && sh -c npm ci --silent --no-audit --no-fund && node --test --test-reporter=tap test/logic.test.mjs)",
    "(cd ../original && node test/browser.test.mjs)",
    "(cd . && cp ../original/shots/scene.png screenshot.png)"
  ],
  "checks": [
    {
      "criterion": "trigger",
      "name": "SKILL.md description says when to use it",
      "pass": true,
      "detail": "Load a glb (including Draco-compressed) into a three.js scene asynchronously and assemble a small playable scene around "
    },
    {
      "criterion": "trigger",
      "name": "triggers on: \"How do I load a Draco compressed glb in three.js with GLTFLoader and DRACOLoader\"",
      "pass": true,
      "detail": "rank 1/118, overlap 7"
    },
    {
      "criterion": "trigger",
      "name": "triggers on: \"Build a first 3D web game scene in three.js with water, floating objects and particles\"",
      "pass": true,
      "detail": "rank 1/118, overlap 8"
    },
    {
      "criterion": "trigger",
      "name": "triggers on: \"DRACOLoader decoder error when I load a gltf in the browser\"",
      "pass": true,
      "detail": "rank 1/118, overlap 6"
    },
    {
      "criterion": "trigger",
      "name": "does not trigger on: \"Make a Godot 2D platformer jump feel better\"",
      "pass": true,
      "detail": "rank 32/118, overlap 0"
    },
    {
      "criterion": "trigger",
      "name": "does not trigger on: \"Write a launch checklist for release day\"",
      "pass": true,
      "detail": "rank 13/118, overlap 0"
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): wave height is bounded by the sum of amplitudes",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): waves move over time and are continuous in space",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): wave normal is unit length and points up",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): floating body settles onto a calm surface at -draft",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): floating body follows waves but lags (no teleporting)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): sphere is pushed out of a box side and corner",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): sphere centre inside the box leaves by the nearest face",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): sphere away from box is untouched",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): walking into a rock never tunnels through at max speed",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): moveStep caps speed, normalises diagonals and stops by friction",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): clampToDisc keeps walker on the island",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): particles: pool reuses slots, falls under gravity, dies on time",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): rng is deterministic per seed",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): phrase stays in the pentatonic scale and in a sane range",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): midiToHz: A4 = 440, octave doubles",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): scheduler windows cover every step exactly once with no gaps",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "logic tests (waves, buoyancy, collisions, particles, music scheduler): exits 0 with no script errors",
      "pass": true,
      "detail": "exit 0"
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: glb loaded asynchronously",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: Draco glb decoded (2908 tris)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: render loop running (41 frames in 1.5 s)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: frame has 143 colour bins, water 84%, sand 14%",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: WebAudio context running after first key press",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: collider pickup works (score >= 2)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: screenshot + 36 GIF frames written",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: rock AABB collider stops the walker (bump sound path hit)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: no console errors, page errors or failed requests",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: missing glb shows an error overlay, no uncaught exception",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "scene in headless Chrome: exits 0 with no script errors",
      "pass": true,
      "detail": "exit 0"
    },
    {
      "criterion": "output",
      "name": "screenshot screenshot.png rendered",
      "pass": true
    },
    {
      "criterion": "output",
      "name": "self-check list has at least 3 items",
      "pass": true,
      "detail": "6 items"
    },
    {
      "criterion": "single",
      "name": "one job per skill (reviewed)",
      "pass": true,
      "detail": "One job: load a glb (Draco included) into three.js and wire the smallest playable scene around it; every system is one numbered section of src/main.js. Making the glb small is left to multiview-to-web-3d-asset."
    },
    {
      "criterion": "bilingual",
      "name": "English SKILL.md",
      "pass": true
    },
    {
      "criterion": "bilingual",
      "name": "Chinese SKILL.zh.md shipped next to SKILL.md",
      "pass": true,
      "detail": "2844 chars"
    },
    {
      "criterion": "bilingual",
      "name": "Chinese guide written",
      "pass": true,
      "detail": "1422 chars"
    }
  ]
}
