This file provides guidance to Claude Code when working with the Bloom Engine codebase.
Bloom is a native TypeScript game engine compiled by Perry (a TypeScript AOT compiler). It provides a simple, function-based API for 2D/3D games that compiles to Metal, DirectX 12, Vulkan, OpenGL, and WebGPU.
# Native (macOS example)
cd native/macos && cargo build --release
# Web/WASM
cd native/web && cargo check --target wasm32-unknown-unknown
./native/web/build.sh [game.ts] # Full web build pipeline
# Check shared code compiles for all targets
cd native/shared && cargo check # native (default features)
cd native/shared && cargo check --target wasm32-unknown-unknown --no-default-features --features web # WASMsrc/ TypeScript API (compiled by Perry)
core/ Window, input, game loop, runGame()
shapes/ 2D shapes + collision
textures/ Image loading, sprites
text/ Font rendering
audio/ Sound + music
models/ 3D models, skeletal animation
math/ Vectors, matrices, easing
scene/ Scene graph, frame callbacks, lighting
physics/ Jolt-backed rigid + soft bodies, character, vehicles
native/ Rust implementations (one crate per platform)
shared/ Cross-platform core (~7000 lines)
- renderer.rs: wgpu + WGSL shaders (2D/3D, shadows, post-FX)
- audio.rs: platform-agnostic mixer
- text_renderer.rs: fontdue-based text
- physics_jolt.rs: JoltPhysics wrapper (native only)
- jolt_sys.rs: C ABI bindings to bloom_jolt shim
- textures.rs, models.rs, scene.rs, etc.
third_party/
JoltPhysics/ Jolt 5.5.0 submodule (built via cmake crate)
bloom_jolt/ C++ shim exposing Jolt behind a C ABI
- include/bloom_jolt.h, src/bloom_jolt.cpp
macos/ Metal + AppKit + Core Audio
ios/ Metal + UIKit + Core Audio
tvos/ Metal + UIKit + GCController
windows/ DirectX 12 + Win32 + WASAPI
linux/ Vulkan/OpenGL + X11 + PulseAudio
android/ Vulkan/OpenGL ES + NativeActivity + AAudio
web/ WebGPU/WebGL + Canvas + Web Audio API (WASM via wasm-pack)
watchos/ Planned — README only, blocked on Perry watchOS target support
Each platform implements ~230 bloom_* FFI functions declared in package.json under perry.nativeLibrary.functions. Native platforms use #[no_mangle] extern "C", web uses #[wasm_bindgen].
String parameters are i64 on native (Perry StringHeader pointers) and NaN-boxed string IDs on web (converted by JS glue layer).
Physics FFI (~110 of the ~230) is generated by the define_physics_ffi! macro in native/shared/src/physics_jolt.rs; each platform crate invokes it once to re-export the full surface. On web the same surface is wasm_bindgen wrappers forwarding to native/web/jolt_bridge.js, which drives JoltPhysics.js.
The web target uses a two-module WASM architecture:
- Perry WASM (game logic) imports bloom_* functions under the
"ffi"namespace - bloom_web.wasm (rendering engine) compiled from
native/web/via wasm-pack - JS glue (
index.html) bridges both modules, handles DOM events, string conversion, asset fetching, and Web Audio
Key features flags in native/shared/Cargo.toml:
default = ["mp3", "jolt"]— includes minimp3 (C dep, not WASM-compatible) + Jolt physicsjolt— compiles the C++ Jolt shim via cmake on native; no-op on wasm32 (web uses JoltPhysics.js)web— uses web-time instead of std::time::Instant
The web crate exposes _str variants (accepting &str) and _bytes variants (accepting &[u8]) for functions that take strings or file data. The JS glue converts Perry NaN-boxed values via __perryToJsValue and fetches assets via sync XHR.
| File | Purpose |
|---|---|
package.json |
FFI function manifest + per-platform build config |
src/core/index.ts |
Core API: window, input, drawing, runGame() |
src/physics/index.ts |
Physics API (see docs/physics.md for architecture) |
native/shared/src/renderer.rs |
wgpu renderer (2D/3D, ~2600 lines) |
native/shared/src/engine.rs |
EngineState with timing, frame callbacks |
native/shared/src/physics_jolt.rs |
Jolt handle registries + define_physics_ffi! macro |
native/third_party/bloom_jolt/ |
C++ shim wrapping JoltPhysics behind a C ABI |
native/web/src/lib.rs |
Web platform: all FFI functions via wasm-bindgen |
native/web/jolt_bridge.js |
Web physics: JoltPhysics.js implementation of FFI |
native/web/index.html |
JS glue: FFI bridge, input, asset loading, Web Audio |
native/web/build.sh |
Build script: wasm-pack + wasm-opt + assembly |