🧪 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