sg.js API Reference

Complete reference for the SiliconGhetto engine JavaScript API (sg.js).

import sg from 'https://cdn.siliconghetto.com/engine/v0.1/sg.js';

Lifecycle

sg.init(canvasId, width, height) — async

Initialize the engine. Loads the WASM module, detects GPU (WebGPU or WebGL2 fallback), and sets up the rendering context.

await sg.init('game-canvas', 800, 600);

sg.run({ update, draw })

Start the game loop. update() runs at 60fps for game logic. draw() runs after for rendering.

sg.run({
    update() { /* game logic */ },
    draw() { /* rendering */ },
});

sg.stop()

Stop the game loop.

sg.clear(r, g, b)

Set the background clear color. Call at the start of draw().

sg.clear(0.1, 0.1, 0.2); // dark blue

Time

PropertyTypeDescription
sg.dtnumberDelta time in seconds since last frame
sg.elapsednumberTotal elapsed time in seconds
sg.framenumberTotal frame count

Input

Keyboard

MethodReturnsDescription
sg.keyDown(key)booleanKey is currently held
sg.keyPressed(key)booleanKey was pressed this frame

Key names use KeyboardEvent.code values: 'KeyW', 'ArrowUp', 'Space', 'ShiftLeft', etc.

if (sg.keyDown('KeyW')) { /* moving forward */ }
if (sg.keyPressed('Space')) { /* just jumped */ }

Mouse

Property/MethodTypeDescription
sg.mouseXnumberMouse X position on canvas
sg.mouseYnumberMouse Y position on canvas
sg.mouseDXnumberMouse X movement delta (works under pointer lock)
sg.mouseDYnumberMouse Y movement delta
sg.scrollDeltanumberScroll wheel delta (positive = down)
sg.mouseButton(btn)booleanMouse button held (0=left, 1=middle, 2=right)
sg.lockPointer()voidRequest pointer lock for FPS-style mouse look
sg.pointerLockedbooleanWhether pointer is currently locked

Entities (2D)

sg.spawn(opts)number

Create an entity. Returns a numeric handle used to reference the entity in all other calls.

const player = sg.spawn({
    x: 400, y: 300,
    sprite: { w: 32, h: 32, r: 1, g: 0.3, b: 0.3 },
    collision: { w: 32, h: 32 },
    tag: 'player',
});
OptionTypeDescription
x, ynumberInitial position
sprite{ w, h, r?, g?, b?, a? }Size and color
collision{ w, h }Collision box dimensions
tagstringTag for finding entities later
texturestringTexture ID (loaded with loadTexture)

sg.despawn(entity)

Remove an entity and clean up all subsystem state (health, physics, AI, animation).

Position & Velocity

MethodDescription
sg.setPos(e, x, y)Set 2D position
sg.setPos3D(e, x, y, z)Set 3D position
sg.getX(e)Get X position
sg.getY(e)Get Y position
sg.setVelocity(e, vx, vy)Set velocity
sg.getVelocity(e)Get velocity → { vx, vy }

Appearance

MethodDescription
sg.setSprite(e, w, h, r, g, b, a)Set size and color
sg.setTexture(e, textureId)Set texture

Tags

MethodDescription
sg.tag(e, tag)Set a tag
sg.hasTag(e, tag)Check for tag
sg.findByTag(tag)Find first entity with tag

Camera

MethodDescription
sg.setCamera(x, y, zoom)Set 2D camera position and zoom
sg.setCamera3D(px, py, pz, tx, ty, tz)Set 3D camera (position → target)
sg.cameraFollow(entity, lerpSpeed)Camera smoothly follows an entity

Drawing

Call these inside draw(). All coordinates are screen-space pixels.

MethodDescription
sg.drawAll()Draw all entities
sg.drawRect(x, y, w, h, { r, g, b, a })Draw a filled rectangle
sg.drawCircle(x, y, radius, { r, g, b, a })Draw a filled circle
sg.drawLine(x1, y1, x2, y2, { thickness, r, g, b, a })Draw a line
sg.drawText(text, x, y, size, { r, g, b })Draw text
sg.drawSprite(textureId, x, y, w, h)Draw a textured sprite
sg.drawRect(10, 10, 200, 30, { r: 0, g: 0, b: 0, a: 0.5 });
sg.drawText('Score: 100', 15, 15, 14, { r: 1, g: 1, b: 1 });

Screen

PropertyTypeDescription
sg.screenWidthnumberCanvas width in pixels
sg.screenHeightnumberCanvas height in pixels
MethodDescription
sg.resize(width, height)Resize canvas and GPU surfaces

Physics (2D)

Collision Detection

MethodReturnsDescription
sg.checkCollision(a, b)booleanAABB overlap test between two entities
sg.overlapping(e)number[]All entities overlapping with e
sg.moveAndCollide(e, dx, dy)booleanMove entity, stop at collisions

Platformer Physics

Full platformer controller with gravity, jumping (coyote time + jump buffer), and variable jump height.

const player = sg.spawn({ x: 100, y: 100, collision: { w: 16, h: 24 } });
sg.setPlatformerPhysics(player, {
    gravity: 980, jumpForce: 400, maxFall: 600, speed: 200,
});

// In update():
const input = sg.keyDown('ArrowRight') ? 1 : sg.keyDown('ArrowLeft') ? -1 : 0;
if (sg.keyPressed('Space')) sg.platformerJump(player);
sg.platformerJumpHeld(player, sg.keyDown('Space'));

const { dx, dy } = sg.updatePlatformer(player, input);
const { hitX, hitY } = sg.tilemapCollide(sg.getX(player), sg.getY(player), 8, 12, dx, dy);
sg.platformerResolve(player, hitX, hitY, dy > 0);
MethodDescription
sg.setPlatformerPhysics(e, opts)Enable platformer physics (gravity, jumpForce, maxFall, speed)
sg.updatePlatformer(e, inputX)Compute movement delta → { dx, dy }
sg.platformerJump(e)Request jump (buffered)
sg.platformerJumpHeld(e, held)Set jump button hold state
sg.platformerResolve(e, hitX, hitY, wasMovingDown)Resolve collision
sg.onGround(e)boolean — is entity on ground?
sg.facing(e)-1 or 1 — facing direction
sg.onWallLeft(e)boolean — touching wall on left
sg.onWallRight(e)boolean — touching wall on right

Top-Down Physics

sg.setTopDownPhysics(entity, { speed: 150, friction: 600 });

Tile Maps

Grid-based level system with collision.

sg.createTileMap(20, 15, 32); // 20x15 grid, 32px tiles
sg.setTile(5, 14, 1);         // solid ground
sg.setTileFlags(3, 10, 2, 2); // platform (one-way)

// In draw():
sg.drawTileMap();
MethodDescription
sg.createTileMap(w, h, tileSize)Create grid
sg.setTile(x, y, type)Set tile (0=empty)
sg.setTileFlags(x, y, type, flags)Set tile with collision flags (1=solid, 2=platform, 4=ladder, 8=hazard)
sg.getTile(x, y)Get tile type
sg.getTileFlags(x, y)Get collision flags
sg.drawTileMap()Render the map
sg.tilemapCollide(cx, cy, halfW, halfH, dx, dy)AABB collision → { x, y, hitX, hitY }
sg.tileAtWorld(wx, wy)Get tile at world position
sg.isTileHazard(x, y)Check hazard flag
sg.isTileLadder(x, y)Check ladder flag
sg.clearTileMap()Destroy tile map

Animation

Frame-based sprite animation system.

sg.addAnimation(player, 'run', { frames: [0, 1, 2, 3], fps: 10, loop: true });
sg.addAnimation(player, 'idle', { frames: [0], fps: 1 });
sg.playAnim(player, 'run');

// In draw():
const frame = sg.getAnimFrame(player); // current frame index
MethodDescription
sg.addAnimation(e, name, { frames, fps, loop })Define animation clip
sg.playAnim(e, name)Play animation
sg.getAnimFrame(e)Current frame index (-1 if none)
sg.animationName(e)Currently playing animation name
sg.animationFinished(e)Has non-looping animation finished?

Health & Damage

sg.setHealth(enemy, 50);        // 50 HP
sg.damage(enemy, 20);           // -20 HP, triggers invincibility
sg.heal(enemy, 10);             // +10 HP (capped at max)

if (sg.isDead(enemy)) sg.despawn(enemy);
MethodReturnsDescription
sg.setHealth(e, max)Set max HP (also sets current to max)
sg.damage(e, amount)booleanDeal damage (false if invincible)
sg.heal(e, amount)Restore HP
sg.getHealth(e)numberCurrent HP (-1 if no health component)
sg.getMaxHealth(e)numberMax HP
sg.isDead(e)booleanHP <= 0
sg.healthFraction(e)numberHP / maxHP (0.0 to 1.0)
sg.healthVisible(e)booleanVisible during hit flicker
sg.updateHealth()Update invincibility timers (call in update())
sg.revive(e)Reset HP to max
sg.setInvincibilityDuration(e, secs)Set i-frame duration

Projectiles

const bullet = sg.spawnProjectile(x, y, 1, 0, 300, {
    damage: 25, lifetime: 2, owner: player,
    w: 8, h: 4, r: 1, g: 0.8, b: 0,
});

// In update():
sg.updateProjectiles();
for (const { handle, damage } of sg.checkProjectileHits()) {
    sg.damage(handle, damage);
}

// In draw():
sg.drawProjectiles();
MethodDescription
sg.spawnProjectile(x, y, dirX, dirY, speed, opts)Spawn projectile → ID
sg.updateProjectiles()Move all projectiles (call in update())
sg.drawProjectiles()Render all projectiles (call in draw())
sg.checkProjectileHits()Check hits → [{ handle, damage }]
sg.projectileCountActive projectile count
sg.clearProjectiles()Remove all projectiles

AI Behaviors

sg.setAI(enemy, 'chase', { target: player, speed: 80 });
sg.setAI(guard, 'patrol', { points: [[100,200], [300,200]], speed: 60 });
sg.setAI(rabbit, 'flee', { target: player, speed: 120, maxDistance: 200 });

// In update():
for (const { handle, dx, dy, facing } of sg.updateAI()) {
    const { hitX, hitY } = sg.tilemapCollide(sg.getX(handle), sg.getY(handle), 8, 12, dx, dy);
    sg.setPos(handle, sg.getX(handle) + (hitX ? 0 : dx), sg.getY(handle) + (hitY ? 0 : dy));
}
BehaviorOptionsDescription
'chase'{ target, speed }Move toward target entity
'patrol'{ points, speed }Walk between waypoints
'flee'{ target, speed, maxDistance }Run away from target

Voxel World

Quick Start

const { seed } = await sg.createVoxelGame({
    canvas: 'game-canvas',
    worldSize: [256, 64, 256],
    seed: 42,
});

sg.run({
    update() { sg.fpsUpdate(); },
    draw() { sg.clear(0.5, 0.7, 1.0); },
});

sg.createVoxelGame(opts) — async

One-call setup: initializes engine, creates voxel world, generates terrain with 20 biomes, enables FPS controller, sets up pointer lock.

OptionDefaultDescription
canvas'game-canvas'Canvas element ID
width960Canvas width
height600Canvas height
worldSize[256, 64, 256]World dimensions [x, y, z]
worldHeight64Y height (overridden by worldSize[1])
seedrandomTerrain generation seed
player{}FPS controller settings (see below)
biomes20 defaultsCustom biome array (replaces defaults)
spawncenter[x, y, z] spawn position

Returns { seed, canvas, width, height }.

Block Operations

MethodDescription
sg.createVoxelWorld(sx, sy, sz)Create empty voxel world
sg.setBlock(x, y, z, type)Set a block (auto-remeshes chunk)
sg.getBlock(x, y, z)Get block type at position
sg.fillBlocks(x1, y1, z1, x2, y2, z2, type)Fill region with block type
sg.voxelSizeX/Y/ZWorld dimensions

Block Types

Access via sg.BLOCKS or sg.blockTypes:

sg.setBlock(x, y, z, sg.BLOCKS.STONE);
sg.setBlock(x, y, z, sg.BLOCKS.DIAMOND_ORE);
IDConstantIDConstant
0AIR22CALCITE
1DIRT23FLOWER_YELLOW
2GRASS24FLOWER_RED
3STONE25TALL_GRASS
4SAND26DEAD_BUSH
5WOOD27CACTUS
6LEAVES28MUSHROOM_RED
7WATER29MUSHROOM_BROWN
8BRICK30CHERRY_LEAVES
9COBBLESTONE31BIRCH_WOOD
10PLANKS32SPRUCE_WOOD
11SNOW33JUNGLE_WOOD
12GRAVEL34ACACIA_WOOD
13PACKED_ICE35GLOW_LICHEN
14SANDSTONE36IRON_ORE
15RED_SAND37GOLD_ORE
16TERRACOTTA38DIAMOND_ORE
17PODZOL39COAL_ORE
18MYCELIUM40LAVA
19MUD41DRY_GRASS
20CLAY42SPRUCE_LEAVES
21MOSSY_STONE

Block names are available via sg.BLOCK_NAMES[id].

FPS Controller

Enabled automatically by createVoxelGame(), or manually:

sg.enableFPSController({
    speed: 7,             // walk speed
    jumpForce: 8.5,       // jump velocity
    gravity: 22,          // gravity strength
    sensitivity: 0.003,   // mouse look sensitivity
    flySpeed: 14,         // fly mode speed
    sprintMultiplier: 1.6,// shift sprint
    playerRadius: 0.28,   // collision cylinder radius
    playerHeight: 1.65,   // collision cylinder height
});

Built-in controls: WASD (move), Mouse (look), Space (jump), Shift (sprint), F (fly toggle), Ctrl (fly down).

MethodReturnsDescription
sg.fpsUpdate(){ x, y, z, eyeY, targetX/Y/Z, onGround, flyMode, sprinting }Update controller (call in update())
sg.fpsSetPosition(x, y, z)Teleport player
sg.fpsGetPosition(){ x, y, z }Player feet position
sg.fpsGetLook(){ yaw, pitch }Camera angles (radians)
sg.fpsSetFly(bool)Set fly mode

Raycasting

DDA (Digital Differential Analyzer) — exact, never misses a block.

// From FPS eye position:
const hit = sg.voxelRaycast(7);
if (hit.hit) {
    // hit.x, hit.y, hit.z — the block that was hit
    // hit.prevX, hit.prevY, hit.prevZ — the air block before it (for placing)
    // hit.blockType — block type ID
}

// From arbitrary position + direction:
const hit2 = sg.voxelRaycastFrom(ox, oy, oz, dx, dy, dz, 20);

Collision

MethodReturnsDescription
sg.voxelCollide(px, py, pz, dx, dy, dz, radius, height){ x, y, z, hitY }AABB collision (standalone)
sg.voxelFindSpawnY(x, z)numberHighest solid block + 2 at column
sg.voxelIsWater(x, y, z)booleanIs block water?

Terrain Generation

sg.generateTerrain({ seed: 42 });

Generates terrain using simplex noise with 20 biomes, 3 cave types (cheese, spaghetti, noodle), Y-level ore distribution, biome-specific trees, and surface decoration (flowers, grass).

Biome System

20 default biomes are registered automatically. To customize:

// Replace all biomes with custom set:
sg.resetBiomes();
sg.addBiome({
    name: 'Alien Desert',
    tempRange: [0.5, 1.0],
    moistRange: [-1, 0],
    surface: sg.BLOCKS.RED_SAND,
    subSurface: sg.BLOCKS.TERRACOTTA,
    treeDensity: 0.02,
    treeTrunk: sg.BLOCKS.CACTUS,
    treeLeaves: sg.BLOCKS.AIR,
});
sg.generateTerrain({ seed: 42 });
MethodDescription
sg.addBiome(opts)Add a biome (first match wins)
sg.resetBiomes()Clear all biomes (for custom set)
sg.clearBiomes()Reset to 20 defaults
sg.biomeCountNumber of registered biomes

Assets

await sg.loadTexture('hero', 'hero.png');
await sg.loadSound('jump', 'jump.wav');

sg.drawSprite('hero', 100, 200, 32, 32);
sg.playSound('jump');
MethodDescription
sg.loadTexture(id, url)Load texture (async)
sg.loadSound(id, url)Load audio (async)
sg.playSound(id)Play sound effect
sg.playMusic(id)Play looping music
sg.stopMusic()Stop music
sg.setVolume(v)Set master volume (0.0–1.0)

CDN Library

await sg.loadTexture('hero', sg.lib.texture('hero-spritesheet'));
await sg.loadSound('jump', sg.lib.sound('jump'));

Particles

const emitter = sg.createEmitter(400, 300);
sg.emitBurst(emitter, 50); // spawn 50 particles

3D Meshes

const cube = sg.createCube();
const sphere = sg.createSphere();
const plane = sg.createPlane();