MCPcopy Index your code
hub / github.com/Bloom-Engine/engine

github.com/Bloom-Engine/engine @v0.4.16

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.4.16 ↗ · + Follow
5,954 symbols 13,987 edges 164 files 723 documented · 12%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Bloom Engine

Native games from TypeScript.

Write TypeScript. Ship native games — and now the web too. Bloom compiles your game to Metal, DirectX 12, Vulkan, OpenGL, and WebGPU — one codebase for every platform.

Inspired by raylib. Bloom models its public API on raylib's — in our view one of the best API designs in gamedev. Bloom is an independent implementation, not a port — how Bloom relates to raylib »

Install

npm install @bloomengine/engine

Or with your preferred package manager:

bun add @bloomengine/engine
pnpm add @bloomengine/engine
yarn add @bloomengine/engine

The npm package ships the TypeScript API alongside the engine's Rust sources and the bundled JoltPhysics C++ shim, so a single install is enough — there's no separate native download step.

You'll also need:

  • Perry — the TypeScript AOT compiler that turns your game into a native binary or WASM module. It also drives the engine's native build.
  • Rust toolchain (rustup.rs) — Perry invokes Cargo to compile the engine's platform crate the first time you build for each target.
  • For web builds only: wasm-pack (cargo install wasm-pack).

Quick Start

import { initWindow, windowShouldClose, beginDrawing,
         endDrawing, clearBackground, drawText, Colors } from "@bloomengine/engine";

initWindow(800, 450, "My Game");

while (!windowShouldClose()) {
  beginDrawing();
  clearBackground(Colors.SNOW);
  drawText("Hello, Bloom!", 190, 200, 20, Colors.DARKGRAY);
  endDrawing();
}

Web-Compatible Pattern

Use runGame() for code that works on both native and web:

import { initWindow, runGame, clearBackground, drawText, Colors } from "@bloomengine/engine";

initWindow(800, 450, "My Game");

runGame((dt) => {
  clearBackground(Colors.SNOW);
  drawText("Hello, Bloom!", 190, 200, 20, Colors.DARKGRAY);
});

Build for web:

./native/web/build.sh main.ts
cd dist/web && python3 -m http.server 8080

Features

  • Simple API — Functions, not classes. The entire API fits on a cheatsheet. (design rationale)
  • True native — Compiles to Metal, DirectX 12, Vulkan, OpenGL, and WebGPU via wgpu.
  • Ship everywhere — macOS, Windows, Linux, iOS, tvOS, Android, and Web from one codebase.
  • Unified 2D/3D — Shapes, textures, text, 3D models, and audio in one engine.
  • Zero magic — Explicit game loops, no hidden framework overhead.

How Bloom relates to raylib

Bloom's public API is heavily inspired by raylib. raylib's API is, in our opinion, one of the best in the gamedev space — a flat library of plain functions, no classes, small enough to learn from a cheatsheet — so we model ours on it. You'll recognize the shape immediately: initWindow, beginDrawing, clearBackground, drawText, and modules named core / shapes / textures / text / audio / models.

That's where the relationship ends. Bloom's implementation is entirely independent — it does not link against, embed, or call raylib. Bloom compiles TypeScript directly to native code via Perry, our LLVM-based AOT compiler, and renders through wgpu (Metal, DirectX 12, Vulkan, OpenGL, WebGPU). It is not a port or a binding — just an engine that admires raylib's API design. Thanks to Ramon Santamaria (@raysan5) and the raylib community for setting the bar. (full design rationale)

Modules

Module Import Description
Core @bloomengine/engine/core Window, game loop, input, timing
Shapes @bloomengine/engine/shapes 2D drawing + collision detection
Textures @bloomengine/engine/textures Image loading, sprite batching
Text @bloomengine/engine/text TTF/OTF font loading and rendering
Audio @bloomengine/engine/audio Sound effects + music streaming
Models @bloomengine/engine/models 3D model loading (glTF, OBJ), skeletal animation
Math @bloomengine/engine/math Vectors, matrices, quaternions, easing
Physics @bloomengine/engine/physics Jolt-backed rigid + soft bodies, character, vehicles (docs)

Platforms

Platform Graphics API Input
macOS Metal Keyboard + mouse
Windows DirectX 12 Keyboard + mouse
Linux Vulkan / OpenGL Keyboard + mouse
iOS Metal Touch + gamepad
tvOS Metal Siri Remote + gamepad
Android Vulkan / OpenGL ES Touch + gamepad
Web WebGPU / WebGL Keyboard + mouse + touch + gamepad

Architecture

src/                  TypeScript API
  core/               Window, input, game loop
  shapes/             2D shapes + collision
  textures/           Image loading, sprites
  text/               Font rendering
  audio/              Sound + music
  models/             3D models
  math/               Vectors, matrices, easing

native/               Rust implementations
  shared/             Cross-platform core (wgpu, fontdue, gltf)
  macos/              Metal + AppKit + Core Audio
  ios/                Metal + UIKit + Core Audio
  tvos/               Metal + UIKit + GCController
  windows/            DirectX 12 + Win32 + XAudio2
  linux/              Vulkan/OpenGL + X11/Wayland + PulseAudio
  android/            Vulkan/OpenGL ES + NativeActivity + AAudio
  web/                WebGPU/WebGL + Canvas + Web Audio (WASM)

examples/
  pong/               Complete working example (~170 lines)

Types

Plain interfaces, no classes:

interface Vec2 { x: number; y: number }
interface Vec3 { x: number; y: number; z: number }
interface Color { r: number; g: number; b: number; a: number }
interface Rect { x: number; y: number; width: number; height: number }
interface Camera2D { offset: Vec2; target: Vec2; rotation: number; zoom: number }
interface Camera3D { position: Vec3; target: Vec3; up: Vec3; fovy: number; projection: number }
interface Texture { handle: number; width: number; height: number }
interface Sound { handle: number }
interface Model { handle: number }

Fullscreen

Launch your game in fullscreen by passing true as the fourth argument to initWindow:

initWindow(800, 450, "My Game", true);   // launches fullscreen
initWindow(800, 450, "My Game");         // windowed (default)

Toggle fullscreen at runtime:

if (isKeyPressed(Key.F11)) {
  toggleFullscreen();
}

Fullscreen is supported on macOS (native AppKit fullscreen), Windows (borderless fullscreen), and Linux (EWMH/X11). The width and height you pass are used as the windowed dimensions when exiting fullscreen.

Skeletal Animation

Bloom supports GPU-accelerated skeletal animation via glTF/GLB models. The pipeline uses 4-bone linear blend skinning with a 128-joint uniform buffer, running entirely on the GPU.

import { loadModel, loadModelAnimation, updateModelAnimation, drawModel,
         getTime, Colors } from "@bloomengine/engine";

const character = loadModel("assets/models/character.glb");
const anim = loadModelAnimation("assets/models/character.glb");

// In your game loop:
updateModelAnimation(anim, 0, getTime(), 1.0, 0, 0, 0);
drawModel(character, { x: 0, y: 0, z: 0 }, 1.0, Colors.WHITE);

Key functions: - loadModel(path) -- loads GLB with skin data (JOINTS_0, WEIGHTS_0) - loadModelAnimation(path) -- loads skeleton + animation channels from GLB - updateModelAnimation(handle, animIndex, time, scale, px, py, pz) -- samples animation, computes joint matrices - drawModel(model, position, scale, tint) -- renders with GPU skinning

For the full pipeline (Blender export, pitfalls, architecture), see docs/skeletal-animation.md.

Links

Extension points exported contracts — how you extend this code

ShaderSource (Interface)
Something that can resolve an include path to its WGSL source. Release builds use a baked slice; debug builds read from [1 …
native/shared/src/renderer/shader_include.rs
Geometry (Interface)
(no doc) [2 implementers]
native/tvos/metal-patched/examples/raytracing/geometry.rs
MaterialJson (Interface)
(no doc)
tools/build-materials-from-json.ts
PbrMaterial (Interface)
(no doc)
src/scene/index.ts
Vec2 (Interface)
(no doc)
src/core/types.ts
Vec3 (Interface)
(no doc)
src/physics/index.ts
TerrainRaycastHit (Interface)
(no doc)
src/world/terrain.ts
DrawCubeOpts (Interface)
(no doc)
src/models/index.ts

Core symbols most depended-on inside this repo

push
called by 573
native/shared/src/renderer/graph.rs
engine
called by 255
native/linux/src/lib.rs
engine
called by 247
native/macos/src/lib.rs
engine
called by 234
native/ios/src/lib.rs
get
called by 232
native/shared/src/models.rs
engine
called by 212
native/android/src/lib.rs
get
called by 206
native/watchos/src/models.rs
str_from_header
called by 206
native/shared/src/string_header.rs

Shape

Function 3,677
Method 1,735
Class 269
Enum 204
Interface 69

Languages

Rust86%
TypeScript14%
Python1%

Modules by API surface

native/web/src/lib.rs385 symbols
native/linux/src/lib.rs303 symbols
native/macos/src/lib.rs286 symbols
native/ios/src/lib.rs286 symbols
native/android/src/lib.rs284 symbols
native/windows/src/lib.rs267 symbols
native/watchos/src/ffi_stubs.rs267 symbols
native/tvos/src/lib.rs264 symbols
native/tvos/metal-patched/src/device.rs240 symbols
native/shared/src/renderer/mod.rs221 symbols
native/tvos/metal-patched/src/encoder.rs147 symbols
native/watchos/src/lib.rs142 symbols

For agents

$ claude mcp add engine \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact