You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Epic. Harvest reusable, asset-free procedural primitives from Matt Shumer's MIT Claude-of-Duty into a ScriptHammer game toolkit — the substrate for a future "prototype your own game demo" capability. Feasibility spike done 2026-08-05 (full CoD source read, 9 parallel subsystem readers).
The one finding that decides everything: harvest, don't embed
CoD is a genuinely modular, MIT, three-only, 100%-procedural (zero art/audio assets) mini-engine (~65k LOC) with a service-locator + event-bus contract and no cross-subsystem imports. But it runs its own imperative render loop + kernel, and ScriptHammer is React-Three-Fiber (React owns the loop). Two loops can't share one canvas.
So we do not embed the engine — we harvest its framework-agnostic procedural primitives (the asset-free, hard-to-build things that make quick 3D prototypes painful) and let R3F + drei + @react-three/postprocessing own the render/post layer. The harvest is a "procedural game toolkit for R3F."
Extract / Adapt / Skip
Tier
Subsystem
Verdict
Why
⭐
materials (4.2k LOC)
EXTRACT
Procedural PBR forge → plain THREE.Material/Texture; triplanar (no UVs), needs renderer only at bake time. "Single most valuable extract."
R3F/drei/postprocessing already are this; salvage env.js IBL + glsl.js only.
weapons + ai + world + ui (30k)
SKIP
FPS app layer → reference for #226. Pull out world/util.js + weapons/geometry.js (plain-three geometry builders).
Net Tier-1 harvest ≈ 13–16k LOC of asset-free, framework-agnostic primitives.
Integration paradigm (the one rule)
R3F owns the <Canvas> renderer + rAF loop. Adapt each primitive to it: materials bake off-screen (save/restore render target); physics runs a fixed-step tick in useFrame writing transforms onto R3F meshes; springs live in useFrame; rng/eventbus are plain modules; audio is a small hook. Do NOT lift render/core.engine (two-loops-fighting-one-canvas trap).
Tasks
Walking skeleton (do first, in a git worktree): vendor physics/{math,surfaces,character,bvh} + player/springs, wire a capsule controller into /game/3d (WASD + pointer-lock) on a BoxGeometry floor skinned with one materials surface. Proves r180→r184, static-export ssr:false, and the ⭐ materials + ⭐ physics pieces at once. Gate: pnpm run type-check + "Validate Component Structure" green, WebGL FallbackPanel intact.
The gauntlet-loop "game-demo generator" (a parameterized skill: game-spec in → scaffolded playable demo out, polished by the gauntlet loop). Design it after this toolkit exists, seeded by these primitives. Only its optional save/share features would touch Supabase; the toolkit + prototype layer is 100% client-side.
Attribution: Claude-of-Duty is MIT (Matt Shumer). All extracted code retains its license/NOTICE.
Epic. Harvest reusable, asset-free procedural primitives from Matt Shumer's MIT Claude-of-Duty into a ScriptHammer game toolkit — the substrate for a future "prototype your own game demo" capability. Feasibility spike done 2026-08-05 (full CoD source read, 9 parallel subsystem readers).
The one finding that decides everything: harvest, don't embed
CoD is a genuinely modular, MIT,
three-only, 100%-procedural (zero art/audio assets) mini-engine (~65k LOC) with a service-locator + event-bus contract and no cross-subsystem imports. But it runs its own imperative render loop + kernel, and ScriptHammer is React-Three-Fiber (React owns the loop). Two loops can't share one canvas.So we do not embed the engine — we harvest its framework-agnostic procedural primitives (the asset-free, hard-to-build things that make quick 3D prototypes painful) and let R3F + drei +
@react-three/postprocessingown the render/post layer. The harvest is a "procedural game toolkit for R3F."Extract / Adapt / Skip
THREE.Material/Texture; triplanar (no UVs), needs renderer only at bake time. "Single most valuable extract."rng(seedable PRNG),EventBus,QUALITY_PRESETS; discard the kernel (fights R3F).springs.js(177 LOC — camera feel/recoil/shake); skip the FPS controller.<ProceduralSky>(drop volumetrics). Beats drei<Sky>/<Environment>.env.jsIBL +glsl.jsonly.world/util.js+weapons/geometry.js(plain-three geometry builders).Net Tier-1 harvest ≈ 13–16k LOC of asset-free, framework-agnostic primitives.
Integration paradigm (the one rule)
R3F owns the
<Canvas>renderer + rAF loop. Adapt each primitive to it: materials bake off-screen (save/restore render target); physics runs a fixed-step tick inuseFramewriting transforms onto R3F meshes; springs live inuseFrame; rng/eventbus are plain modules; audio is a small hook. Do NOT liftrender/core.engine(two-loops-fighting-one-canvas trap).Tasks
physics/{math,surfaces,character,bvh}+player/springs, wire a capsule controller into/game/3d(WASD + pointer-lock) on aBoxGeometryfloor skinned with onematerialssurface. Proves r180→r184, static-export ssr:false, and the ⭐ materials + ⭐ physics pieces at once. Gate:pnpm run type-check+ "Validate Component Structure" green, WebGLFallbackPanelintact.materialsforge (Tier-1 ⭐).audioleaf layer (Tier-1 ⭐).coregems (rng,EventBus,QUALITY_PRESETS) +player/springs+ geometry builders.sky→<ProceduralSky>; adaptfxparticle core.src/lib/cod/) with CoD's MITLICENSE/NOTICE retained.Relationships
/game/3dssr:false island).weapons/aiare a reference, not a lift.good_prompt_bad_promptFPS-placeholder prompt ([Gap-Audit] 029 SEO Editorial Assistant: technical.ts test coverage + import-bundle conflict UX + offline autosave #38, being closed).Deferred — Phase 2 (not this epic)
The gauntlet-loop "game-demo generator" (a parameterized skill: game-spec in → scaffolded playable demo out, polished by the gauntlet loop). Design it after this toolkit exists, seeded by these primitives. Only its optional save/share features would touch Supabase; the toolkit + prototype layer is 100% client-side.
Attribution: Claude-of-Duty is MIT (Matt Shumer). All extracted code retains its license/NOTICE.