Forge optimize
Atelier - a premium, anti-slop frontend design skill suite for Claude Code: 11 skills + a deepdive knowledge base.
npx -y skills add luminary19/atelier --skill forge-optimizeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Forge suite — web/runtime optimization pipeline for 3D assets: compress, budget, and hand off GLB files to the browser. Takes a raw GLB exported by Blender (or another DCC) and delivers a browser-ready GLB with Draco or Meshopt geometry compression, KTX2/Basis Universal or WebP texture compression, mesh quantization, LOD generation, and spec-validation — then produces the handoff package that atelier-webgl expects (optimized GLB + poster WebP + decoder paths). Use whenever: compressing a GLB for web delivery, reducing file size, applying Draco or Meshopt, encoding KTX2 textures with UASTC or ETC1S, generating LOD levels from a GLB, setting up DRACOLoader / KTX2Loader / MeshoptDecoder in Three.js or R3F, validating a GLB against the Khronos spec, building a before/after size report, running gltf-transform or gltfpack, meeting web 3D budget targets (< 3 MB, < 100 draw calls, < 500k triangles), or preparing assets for the atelier-webgl handoff. Trigger phrases: "optimize GLB", "compress 3D model", "Draco compress", "Meshopt", "KTX2 textures", "web 3D budget", "gltf-transform", "gltfpack", "LOD for web", "GLB too large", "atelier handoff". HEADLESS-ONLY: driven from code, output verified by reading a PNG. Part of the Forge suite.
SKILL.md
11.1 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it
Forge — Web Optimization & Atelier Handoff
The delivery boundary of the Forge pipeline: every raw GLB produced upstream is too large to
serve unoptimized. This skill compresses, budgets, validates, and packages the asset so
atelier-webgl can load it without a second thought.
Project memory: if
FORGE.mdexists at the project root, read it first — it carries the target engine, poly budget, texture constraints, output paths, and the Atelier aesthetic link. IfATELIER.mdalso exists, note the world (production vs award-grade) and primary OKLCH hue — they constrain which quality tier to use.Inputs: an uncompressed GLB from
forge-export(or Blender direct), a budget tier fromforge-standards, and any LOD mesh variants fromforge-topology. Gate downstream: optimized GLB + poster WebP → hand toatelier-webglviaSkill("atelier-webgl"). Web runtime perf gate lives inatelier-perf-a11y; Forge's own spec/mesh gate isforge-validate. Run = call the Skill tool — writing the name in prose runs nothing.
Suite map — where
forge-optimizesits:
forge-brief→forge-standards(budgets) → model/UV/material/texture/light pipeline →forge-render(QA PNG) →forge-export(GLB/USD) →forge-optimize← YOU ARE HERE →atelier-webgl(R3F scene) →atelier-perf-a11y(CWV gate)Cross-skill calls:
forge-topologygenerates LOD meshes this skill then compresses.forge-validateshould gate every output GLB (spec + mesh quality). The web runtime gate (LCP, INP, CLS, a11y) isatelier-perf-a11y's job — do NOT skip it.
Decide first: tool + mode
Before touching any file, confirm availability and pick the right codec:
# 1. Check tools
where.exe gltf-transform # primary: npx gltf-transform
where.exe node # required for gltf-transform
where.exe gltfpack # secondary: native binary
where.exe toktx # required for KTX2 via gltf-transform uastc/etc1s
Then decide:
| Situation | Tool | Mode |
|---|---|---|
| Static mesh, smallest file | gltf-transform | --compress draco |
| Animated mesh / morph targets | gltf-transform | --compress meshopt |
| Batch pipeline, no Node | gltfpack native binary | -cc |
| KTX2 textures (VRAM critical) | gltf-transform uastc + etc1s | requires toktx |
| Quick scenes, 1–3 textures | gltf-transform | --texture-compress webp |
Never apply both Draco and Meshopt to the same file. They are alternative encodings.
Full CLI reference: references/cli-invocations.md
Installation & Windows gotchas: references/install-windows.md
Budget tiers and runtime loader wiring: references/budgets-and-runtime.md
The flow
0. Read FORGE.md (if present) for output paths, budget tier, and engine target.
1. Inspect — always run before optimizing:
gltf-transform inspect input.glb
Read triangle count, draw calls, texture sizes, extension list. Textures dominate (~70–80% of file size); don't apply Draco if you have 5 triangles and 4 MB of textures.
2. Gate: pick codec + texture strategy — from the decide-first table above.
Animated? → Meshopt. Static + max compression? → Draco. VRAM critical? → KTX2 (UASTC+ETC1S).
Quick? → WebP. Document the choice in FORGE.md under ## Optimization.
3. Optimize — run scripts/optimize.ps1 (wrapper over gltf-transform):
# Safe defaults — meshopt + WebP, reports before/after KB
powershell -File "$env:CLAUDE_CONFIG_DIR\skills\forge-optimize\scripts\optimize.ps1" `
-InputPath ".\raw\hero.glb" -Output ".\public\forge\hero-hero.glb"
# With KTX2 (requires toktx in PATH):
powershell -File "...\optimize.ps1" -InputPath .\raw\hero.glb -Output .\public\forge\hero-hero.glb -KTX2
# With Draco (auto-falls-back to Meshopt if the GLB is animated / has morph targets):
powershell -File "...\optimize.ps1" -InputPath .\raw\hero.glb -Output .\public\forge\hero-hero.glb -Draco
# With the poster gate (enforces poster >= 10 KB so there is an image to Read back):
powershell -File "...\optimize.ps1" -InputPath .\raw\hero.glb -Output .\public\forge\hero-hero.glb `
-Poster .\public\forge\hero-hero-poster.webp
The script reports input KB → output KB and exits non-zero if validation fails. It refuses to
run when -Output resolves to the same file as -InputPath (the source GLB is sacred), and warns
before overwriting an existing output (-Force to silence). -Input is accepted as an alias for
-InputPath. PS 5.1-compatible.
4. Fine-grained pipeline (when one-shot is insufficient) — follow the ordered chain in
references/cli-invocations.md §2: prune → dedup → weld → (LOD simplify) → geometry codec
→ texture resize → texture codec → validate. Order is load-bearing: never simplify after
a geometry codec; never geometry-codec before weld.
5. LOD variants (if FORGE.md specifies LOD): produce hero-lod0.glb, hero-lod1.glb,
hero-lod2.glb via cascaded simplification. See references/cli-invocations.md §3.
Use forge-topology (Skill("forge-topology")) for Blender-side remesh before this step.
6. Validate — Khronos spec conformance:
gltf-transform validate .\public\forge\hero-hero.glb
Then run Skill("forge-validate") for the full Forge gate (manifold, normals, UV, polycount).
7. Poster — generate a static WebP poster (the fallback image for no-WebGL / reduced-motion
paths). Must exist BEFORE the Canvas mounts. Use frame3d or screenshot-glb (details in
references/budgets-and-runtime.md §4). The poster IS the reduced-motion fallback — build it
first. Pass it to optimize.ps1 -Poster <path> to enforce the >= 10 KB size gate.
Then Read the poster PNG/WebP with the Read tool — a blank/black/wrong-color poster means
the GLB is broken upstream (e.g. IMAGE_COLORSPACE_MISMATCH, lost geometry). validate passing
does NOT mean the asset renders correctly. Do not hand off on a blank poster.
8. Decoder files — copy static decoder assets into public/:
# Copy from node_modules (do this once per web project):
Copy-Item -Path ".\node_modules\three\examples\jsm\libs\draco" -Destination ".\public\draco" -Recurse
Copy-Item -Path ".\node_modules\three\examples\jsm\libs\basis" -Destination ".\public\basis" -Recurse
9. Handoff — write the handoff note and invoke atelier-webgl:
public/forge/<slug>-hero.glb ← optimized GLB
public/forge/<slug>-hero-poster.webp ← static fallback image
public/draco/ ← DRACOLoader decoder files
public/basis/ ← KTX2Loader transcoder files
Then: Skill("atelier-webgl") — pass the GLB path, poster path, and decoder paths.
Run = call the Skill tool. Writing "hand off to atelier-webgl" in prose runs nothing.
When it goes wrong
The optimize pipeline fails in a small set of recurring ways. Triage here first; full detail +
fixes live in references/install-windows.md §4 (12-row gotcha table).
| Symptom | Likely cause | Fix |
|---|---|---|
ERR_DLOPEN_FAILED / "Could not load the sharp module" | Sharp native binary mismatch (wrong Node/OS/CPU) | Reinstall: npm install --os=win32 --cpu=x64 sharp then -g @gltf-transform/cli --force (Gotcha 1) |
toktx not found with -KTX2 | KTX-Software not on PATH (NullSoft setx truncates PATH at 1024 chars) | Re-add C:\Program Files\KTX-Software\bin to user PATH, restart shell (Gotcha 2) |
| KTX2 GLB larger than the WebP version | UASTC without Zstandard supercompression | Add --zstd 18; ETC1S for color slots, UASTC only for normal/ORM (Gotcha 6/7) |
| Animated GLB plays in T-pose / loses animation | Draco was applied to an animated/morph mesh | Use Meshopt (the script auto-falls-back; never -Draco on animated assets) (Gotcha 4/5) |
simplify gives no reduction or holes | Mesh not welded before simplify | weld --tolerance 0.0001 before simplify (Gotcha 8) |
Poster renders blank/black but validate passes | Spec-valid but visually broken (colorspace, lost geometry) | Read the poster; fix upstream in forge-export/forge-material — do NOT hand off |
Determinism: gltf-transform is deterministic for a given input + flags. Re-running optimize.ps1
on the same input is idempotent — it rebuilds the same artifact and never touches the source.
Operating principles
- Inspect before every compress. File size breakdown decides the strategy; never guess. Textures almost always dominate — resize them before encoding.
- Source files are sacred. Draco and Meshopt are lossy. The uncompressed GLB from
forge-exportis the source of truth; the optimized output is a build artifact. Never overwrite the source —optimize.ps1refuses when-Outputequals-InputPath. Re-running optimize on the same input is safe and idempotent; never point-Outputat the source GLB. - Codec choice is a contract. The runtime loader must match the compression (DRACOLoader
for Draco, MeshoptDecoder for Meshopt, KTX2Loader for KTX2). Document the codec in
FORGE.md; pass it toatelier-webglin the handoff note. - Poster first, canvas second. The static fallback must exist before the Canvas mounts.
Build the poster during this step, not as an afterthought in
atelier-webgl. - Validate before handing off. Run
gltf-transform validate+Skill("forge-validate")on every optimized GLB. A corrupt asset discovered inatelier-webglis expensive to debug.
What ships with it: 4 files
45.5 KB alongside SKILL.md, 1 of them executable
references/
- budgets-and-runtime.md12.1 KB
- cli-invocations.md10.2 KB
- install-windows.md8.1 KB
scripts/
- optimize.ps1runs15.1 KB