This repo is a small pnpm-workspace monorepo for Party: a TypeScript particle simulation engine with dual runtimes (WebGPU + CPU) and a React playground app.
packages/core(@cazala/party)- Engine + module system + CPU/WebGPU runtimes.
packages/playground(@cazala/playground)- The interactive app (React + Redux Toolkit) that drives
@cazala/party.
- The interactive app (React + Redux Toolkit) that drives
packages/worker(worker)- Cloudflare Worker reverse-proxy for hosting under
caza.la/party.
- Cloudflare Worker reverse-proxy for hosting under
docs/- User/maintainer guides (they’re the canonical narrative docs).
From repo root:
npm run setup— installs root deps, then workspace deps viapnpm.npm run dev— starts the playground dev server onhttp://localhost:3000.npm run build— builds core + playground.npm run type-check— builds core and type-checks playground.
packages/core/src/index.tsre-exports the public API (Engine,Module, built-in modules, types).- The “real” type shape for particles is in
packages/core/src/interfaces.ts.
IParticle is:
position: { x, y }velocity: { x, y }size: numbermass: numbercolor: { r, g, b, a }(0..1 floats)
Semantics used throughout:
- Pinned:
mass < 0 - Removed:
mass === 0
new Engine({ runtime: "auto" | "webgpu" | "cpu", ... })is a facade inpackages/core/src/engine.ts."auto"attempts WebGPU first and falls back to CPU oninitialize().- On WebGPU,
getParticles()is a full GPU→CPU readback: avoid in hot paths.- Prefer
getParticlesInRadius(...),setParticle(...), andsetParticleMass(...). - Playground tools are written around this constraint.
- Prefer
Core type is Module in packages/core/src/module.ts:
- Modules declare:
name(string literal, unique)role:ModuleRole.ForceorModuleRole.Renderinputs: map of input keys toDataType.NUMBERorDataType.ARRAY
- Modules implement both descriptors:
webgpu(): WebGPUDescriptorcpu(): CPUDescriptor
- Enabled is tracked separately via
module.setEnabled(bool)and gets propagated as anenableduniform.
Force lifecycle phases (both runtimes support these hooks):
global(WebGPU-only helper WGSL)state(pre-pass, e.g. fluids density)apply(forces/velocity changes)constrain(position corrections, iterated)correct(post-integration corrections)
Render modules contribute passes:
- WebGPU:
RenderPassKind.FullscreenorRenderPassKind.Compute(optionallyinstanced) - CPU: Canvas2D composition via
CPURenderDescriptor
- Engine orchestrator:
packages/core/src/runtimes/webgpu/engine.ts - Resource plumbing:
packages/core/src/runtimes/webgpu/gpu-resources.ts - WGSL program build:
packages/core/src/runtimes/webgpu/module-registry.ts - Simulation concat/dispatch:
packages/core/src/runtimes/webgpu/simulation-pipeline.ts - Local neighborhood query (avoids full readback):
packages/core/src/runtimes/webgpu/local-query.ts - Spatial grid:
packages/core/src/runtimes/webgpu/spacial-grid.ts(typo is in filename/class)
CPU counterparts live under packages/core/src/runtimes/cpu/.
The pattern is “Redux slice → hook wrapper → UI”:
- Slices:
packages/playground/src/slices/** - Hook layer:
packages/playground/src/hooks/**- Hooks encapsulate Redux and provide “actions” to components.
- Many hooks follow a dual-write pattern: dispatch to Redux + immediately call engine for responsiveness.
- Components:
packages/playground/src/components/**
- Tool orchestrator:
packages/playground/src/hooks/tools/index.ts - Individual tools:
packages/playground/src/hooks/tools/individual-tools/* - Global hotkeys are implemented in
packages/playground/src/components/GlobalHotkeys.tsx.- Tool switching requires Cmd/Ctrl + letter (A/S/D/F/G/H/J/K/L).
- Session “quick load 1–9” is Cmd/Ctrl + 1–9.
If you’re changing a tool, sanity-check you’re not introducing WebGPU readbacks (getParticles()) during mouse move/drag.
Cloudflare Worker reverse-proxies requests:
- Incoming:
/party/*oncaza.la - Upstream:
vars.UPSTREAM_ORIGIN(defaulthttps://party.caza.la) - Adds response header:
x-edge-proxy: cazala-party-worker
Config: packages/worker/wrangler.toml
Implementation: packages/worker/src/index.ts
If you need deeper narrative docs, start here:
docs/user-guide.md(engine API + built-in modules)docs/module-author-guide.md(writing modules)docs/maintainer-guide.md(core internals)docs/playground-user-guide.md(UI/tools/hotkeys)docs/playground-maintainer-guide.md(playground patterns)