API: Core #
Bootstrap, initialization, game loop timing, camera, and core types.
Bootstrap #
The bootstrap() function is the recommended entry point. It handles DOM ready, canvas lookup, backend selection
(WebGPU or software fallback), and error display automatically.
import { bootstrap, type BootstrapOptions } from 'blit-tech';
// One-liner - canvas id defaults to 'blit-tech-canvas', container to 'canvas-container'
bootstrap(MyDemo);
// With options
bootstrap(MyDemo, {
canvasId: 'my-canvas',
containerId: 'error-wrapper',
onSuccess: () => console.log('started'),
onError: (err) => trackError(err),
waitForDOMReady: true, // default true; set false in Electron after DOMContentLoaded
});
BootstrapOptions fields:
| Field | Type | Default | Description |
|---|---|---|---|
canvasId |
string |
'blit-tech-canvas' |
Canvas element id |
containerId |
string |
'canvas-container' |
Container id for error display |
onSuccess |
() => void |
- | Called after successful init |
onError |
(error: Error) => void |
- | Called on any init failure |
waitForDOMReady |
boolean |
true |
Wait for DOMContentLoaded |
Manual utilities (for custom initialization flows):
import { displayError, getCanvas } from 'blit-tech';
const canvas = getCanvas('my-canvas'); // returns null on missing element
displayError('Init Failed', 'WebGPU unavailable.', 'my-container');
Initialization #
const ok = await BT.init(demo, canvas); // low-level init; prefer bootstrap()
BT.displaySize; // Vector2i - configured logical resolution (clone per read)
BT.canvasDisplaySize; // Vector2i | null - output buffer when set in configure()
BT.outputSize; // Vector2i - effective drawing-buffer size (clone per read)
BT.targetFPS; // number - target updates per second
BT.activeBackend; // 'webgpu' | 'software' | null
BT.init() selects WebGPU or falls back to the Canvas 2D software renderer automatically. When not using bootstrap(),
set canvas.tabIndex = 0 and call canvas.focus() so keyboard events reach the canvas.
HardwareSettings (resolved after configure(); the hook may return a partial object):
configure() may return only the fields you want to override. The engine merges them with defaultConfig() via
mergeHardwareSettings() (also exported). Omit displaySize to inherit the full default resolution and 640×480
output buffer. Include displaySize when you want a custom logical size; optional fields you omit then stay unset (for
example no canvasDisplaySize means a 1:1 drawing buffer).
| Field | Type | Default | Description |
|---|---|---|---|
displaySize |
Vector2i |
320×240 |
Logical render resolution |
canvasDisplaySize |
Vector2i |
640×480 |
CSS/output size; enables display-tier effects |
maxCanvasDisplaySize |
Vector2i |
960×720 |
Maximum on-screen canvas CSS size |
targetFPS |
number |
60 |
Fixed-update rate |
renderer |
'webgpu' | 'software' |
'webgpu' |
Force backend |
outputUpscaleFilter |
'nearest' | 'linear' |
'nearest' |
Upscale filter |
detectDroppedFrames |
boolean |
false |
Log a console warning on missed vsync |
displaySize, canvasDisplaySize, and maxCanvasDisplaySize must be positive whole-number pixel dimensions. Each size
is capped at 8192×8192 per axis and 16,777,216 total pixels (4096×4096). Invalid sizes make initialization fail
before the engine applies canvas layout, sets canvas backing dimensions, or allocates renderer buffers. BT.init()
returns false and logs a specific [BT] message to the browser console (press F12); the on-canvas bootstrap error
stays a generic init failure message. In WebGPU mode, the requested logical and output sizes must also fit the active
adapter/device maxTextureDimension2D limit. GPU limit failures do not fall back to the software renderer.
BT getters vs configure() fields: displaySize, canvasDisplaySize, and targetFPS on BT mirror the same
names on HardwareSettings. outputSize is the effective drawing-buffer size (canvasDisplaySize ?? displaySize).
activeBackend is the backend that actually started (after fallback), not the renderer value from configure().
Game Loop Timing #
BT.deltaSeconds; // seconds per fixed tick (1 / BT.targetFPS)
BT.timeSeconds; // elapsed seconds since init (ticks × deltaSeconds)
BT.ticks; // current tick counter (increments each update)
BT.ticksReset(); // reset tick counter to 0
Timer #
Timer fires once per fixed interval. Use it for periodic events: particle spawns, score ticks, palette swaps.
const spawn = new Timer(180); // fires every 180 ticks (3 s at 60 FPS)
// Inside update():
if (spawn.tick()) {
spawnEnemy();
}
// Additional API:
spawn.reset(); // restart interval from now
spawn.elapsedTicks(); // ticks since last fire/reset
spawn.remainingTicks(); // ticks until next fire
spawn.intervalTicks; // readonly interval size
Timer.tick() advances the internal baseline on each true return. Pass BT.ticks explicitly only when you need a
specific snapshot; the default is the engine tick counter.
Camera #
The camera applies a global pixel offset to all subsequent draw calls. Integer only - pass Vector2i, never floats.
BT.cameraSet(new Vector2i(scrollX, scrollY)); // apply offset
BT.camera; // Vector2i - current offset
BT.cameraReset(); // set back to (0, 0)
// Clamp a camera origin so the viewport stays within a world:
const clamped = BT.cameraClamp(desired, worldSize);
// Optional third argument overrides the viewport size (default: BT.displaySize):
const clamped = BT.cameraClamp(desired, worldSize, new Vector2i(160, 120));
Core Types #
Vector2i #
Integer 2D vector. Constructor auto-truncates floats toward zero. Used for all positions, sizes, and camera offsets.
const v = new Vector2i(10, 20);
v.x;
v.y; // direct access
v.width;
v.height; // aliases for x / y (useful when treating the vector as a size)
// Static factories
Vector2i.zero(); // (0, 0) - cached frozen singleton
Vector2i.one(); // (1, 1) - cached frozen singleton
Vector2i.up(); // (0, -1)
Vector2i.down(); // (0, 1)
Vector2i.left(); // (-1, 0)
Vector2i.right(); // (1, 0)
Vector2i.fromFloat(x, y); // truncate floats → integer vector
// Math utilities
Vector2i.distance(a, b); // Euclidean distance (float)
Vector2i.sqrDistance(a, b); // squared distance (avoids sqrt)
Vector2i.dotProduct(a, b); // scalar dot product
Vector2i.lerp(a, b, t); // interpolate, t clamped [0,1], result truncated
Vector2i.lerpTo(a, b, t, out); // zero-allocation lerp into existing vector
Instance methods: .add(), .sub(), .scale(), .dot(), .clone(), .equals(), .negate(), .abs(), .min(),
.max(), etc. See src/utils/Vector2i.ts for the full list.
Rect2i #
Integer rectangle with x, y, width, height fields.
const r = new Rect2i(x, y, width, height);
// Static factories
Rect2i.zero(); // (0,0,0,0) - cached frozen singleton
Rect2i.fromMinMax(min, max); // from corner vectors
Rect2i.fromMinMaxXY(minX, minY, maxX, maxY); // zero-allocation variant
Rect2i.fromCenterSize(center, size); // centered rectangle
Rect2i.fromCenterSizeXY(cx, cy, w, h); // zero-allocation variant
// Instance methods
r.contains(point); // boolean - point inside rect
r.intersects(other); // boolean - rects overlap
r.intersection(other); // Rect2i | null - overlap area
r.center; // Vector2i getter
r.min; // Vector2i getter (top-left)
r.max; // Vector2i getter (bottom-right)
Color32 #
32-bit RGBA color (channels 0-255).
const c = new Color32(r, g, b, a);
// Cached color constants (static getters; frozen singletons)
Color32.white Color32.black Color32.transparent
Color32.red Color32.green Color32.blue
Color32.yellow Color32.cyan Color32.magenta
Color32.gray(value) // grayscale, value 0-255
// Hex parsing
Color32.fromHex('#ff8800') // returns Color32
// Named color registry (global, case-insensitive)
Color32.registerColor('brand', new Color32(255, 128, 0, 255));
Color32.resolveNamedColor('brand'); // → Color32 | undefined
Color32.updateColor('brand', newColor);
Color32.unregisterColor('brand');
// Interpolation
Color32.lerp(a, b, t); // blend a→b; t clamped [0,1]; RGBA independent; truncates like instance lerp
c.lerp(other, t); // same semantics as static helper
// Conversion
c.toFloat32Array() // [r/255, g/255, b/255, a/255]
c.luminance // perceived brightness: 0.299r + 0.587g + 0.114b
c.toHex() // '#rrggbb' string
See Also #
| Guide | What it covers |
|---|---|
| API: Rendering | primitives, sprites, text, post-process, frame capture |
| API: Palette | palette setup, presets, effects |
| Palette Guide | palette-first workflow and practical patterns |
| API: Assets | sprite sheets, bitmap fonts, asset loading |
| Input Guide | pointer, keyboard, gamepad |
| Testing | test tiers, WebGPU mocks |