Skip to content

Bloom-Engine/engine

Repository files navigation

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.

Quick Start

import { initWindow, windowShouldClose, beginDrawing,
         endDrawing, clearBackground, drawText, Colors } from "bloom";

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

while (!windowShouldClose()) {
  beginDrawing();
  clearBackground(Colors.RAYWHITE);
  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 "bloom";

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

runGame((dt) => {
  clearBackground(Colors.RAYWHITE);
  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.

Modules

Module Import Description
Core bloom/core Window, game loop, input, timing
Shapes bloom/shapes 2D drawing + collision detection
Textures bloom/textures Image loading, sprite batching
Text bloom/text TTF/OTF font loading and rendering
Audio bloom/audio Sound effects + music streaming
Models bloom/models 3D model loading (glTF, OBJ), skeletal animation
Math bloom/math Vectors, matrices, quaternions, easing
Physics bloom/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 "bloom";

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

About

Native TypeScript game engine — compiles to Metal, DirectX 12, Vulkan, and OpenGL

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors