🧪 TypeScript Binding — Examples
Below are practical examples that mirror how we use the engine in our demos.
1) Minimal WASM Scene (Browser)
ts
import {
initEngine,
createWorld,
createWindow,
createEntity,
createCamera,
createLight,
createGeometry,
createMaterial,
createTexture,
createModel,
updateTransform,
tick,
} from '@vulfram/engine';
import { initWasmTransport, transportWasm } from '@vulfram/transport-wasm';
const WORLD_ID = 1;
await initWasmTransport();
initEngine({ transport: transportWasm });
createWorld(WORLD_ID);
createWindow(WORLD_ID, {
title: 'Vulfram WASM',
size: [1024, 640],
position: [0, 0],
resizable: true,
canvasId: 'vulfram-canvas',
});
// Camera
const camera = createEntity(WORLD_ID);
updateTransform(WORLD_ID, camera, {
position: [0, 0, 8],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1],
});
createCamera(WORLD_ID, camera, { kind: 'perspective', near: 0.1, far: 100 });
// Light
const light = createEntity(WORLD_ID);
updateTransform(WORLD_ID, light, {
position: [3, 4, 6],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1],
});
createLight(WORLD_ID, light, { kind: 'point', intensity: 20, range: 50 });
// Resources
const texId = createTexture(WORLD_ID, {
source: { type: 'color', color: [1, 1, 1, 1] },
srgb: true,
label: 'WhiteTex',
});
const matId = createMaterial(WORLD_ID, {
kind: 'standard',
label: 'WhiteMat',
options: {
type: 'standard',
content: {
baseColor: [1, 1, 1, 1],
baseTexId: texId,
baseSampler: 'linear-clamp',
flags: 0,
surfaceType: 'opaque',
},
},
});
const geomId = createGeometry(WORLD_ID, {
type: 'primitive',
shape: 'cube',
label: 'Cube',
});
const cube = createEntity(WORLD_ID);
updateTransform(WORLD_ID, cube, {
position: [0, 0, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1],
});
createModel(WORLD_ID, cube, { geometryId: geomId, materialId: matId });
let last = performance.now();
function frame(now: number) {
const dt = now - last;
last = now;
tick(now, dt);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
2) Node.js (N-API) — Basic Loop
ts
import {
initEngine,
createWorld,
createWindow,
tick,
} from '@vulfram/engine';
import { transportNapi } from '@vulfram/transport-napi';
initEngine({ transport: transportNapi });
const WORLD_ID = 1;
createWorld(WORLD_ID);
createWindow(WORLD_ID, {
title: 'Vulfram Node',
size: [800, 600],
position: [100, 100],
resizable: true,
});
let last = Date.now();
setInterval(() => {
const now = Date.now();
const dt = now - last;
last = now;
tick(now, dt);
}, 16);
3) Input Handling
ts
import { isKeyPressed, isWindowCloseRequested } from '@vulfram/engine';
const KEY_W = 41; // example keycode (from core)
function update(worldId: number) {
if (isKeyPressed(worldId, KEY_W)) {
// move forward
}
if (isWindowCloseRequested(worldId)) {
// handle close request
}
}
4) Upload Buffer + Texture
ts
import { uploadBuffer, createTexture } from '@vulfram/engine';
const bufferId = 200;
const imageData = new Uint8Array([/* raw image bytes */]);
uploadBuffer(bufferId, 'image-data', imageData);
const textureId = createTexture(1, {
source: { type: 'buffer', bufferId },
srgb: true,
label: 'UploadedTexture',
});
If you want more complex examples, check the demos in the monorepo.
Documentation Vulfram Core