Physics — a box you can push
Give a primitive a collider and dynamic physics; a shove is an impulse. Clicking the box (needs a collider) fires on_click.
const crate = iamar.entity_spawn("box", 4, 1, 4, 0);
iamar.entity_set_scale(crate, 0.6, 0.6, 0.6);
iamar.entity_set_collider(crate, 1, 0.6, 0.6, 0.6); // shape 1 = box
iamar.entity_set_physics(crate, 1, 8); // mode 1 = dynamic, 8 kg
function on_click(player: number, entity: number): void {
if (entity !== crate) return;
const p = iamar.player_pos(player), b = iamar.entity_pos(crate);
if (!p || !b) return;
iamar.entity_apply_impulse(crate, (b[0] - p[0]) * 40, 60, (b[2] - p[2]) * 40);
}
Physics — a trigger zone
Any entity can become a zone; entering and leaving fire callbacks.
const gate = iamar.entity_spawn("marker", 0, 1, -6, 0);
iamar.entity_set_trigger(gate, 3); // 3 m radius; 0 turns it off
function on_trigger_enter(player: number, entity: number): void {
if (entity === gate) iamar.ui_note("You crossed the gate.");
}
Network — multiplayer with an authority
Every visitor runs their own copy of your script. Exactly one copy is the authority: let it run the shared state and broadcast; the others mirror. In TypeScript the adapter handles the message buffers (iamar_alloc is emitted for you); on_message hands you a Uint8Array.
let score = 0;
function on_tick(dt: number): void {
if (iamar.is_authority() !== 1) return; // only the authority simulates
// ... update shared state, then tell every other copy:
iamar.world_message("score:" + score);
}
function on_message(data: Uint8Array): void {
iamar.log("shared update arrived, " + data.length + " bytes");
}
Render — a custom mesh
mesh_create takes interleaved vertices (position, normal, uv — 8 floats each) and triangle indices, and returns a mesh id you spawn as mesh:<id>.
const verts = new Float32Array([
-1, 0, -1, 0, 1, 0, 0, 0,
1, 0, -1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 1,
-1, 0, 1, 0, 1, 0, 0, 1,
]);
const idx = new Uint32Array([0, 1, 2, 0, 2, 3]);
const mesh = iamar.mesh_create(verts, idx);
const platform = iamar.entity_spawn(`mesh:${mesh}`, 0, 1.5, -4, 0);
iamar.entity_set_color(platform, 0.2, 0.5, 0.45, 1);
Camera — a four-second cutscene
Take the camera, look at the spawn, then give it back on a timer. Esc and the browser menus always hand it back to the player at once.
iamar.camera_set(1, 12, 8, 12, 0, 1, 0); // from (12,8,12), looking at the spawn
iamar.timer_after(4000, 7); // time group: on_timer(7) in 4 s
function on_timer(tag: number): void {
if (tag === 7) iamar.camera_set(0, 0, 0, 0, 0, 0, 0); // mode 0 = player's camera
}
Input — your own keys
Bind a key (Godot key codes: A–Z are 65–90) and on_input fires on press and release. Esc, Enter, Tab and the F keys stay the browser's.
iamar.input_bind(82, true); // the R key
function on_input(key: number, pressed: boolean): void {
if (key === 82 && pressed) iamar.ui_note("R pressed — your move.");
}
More groups to explore in the reference: storage (kv_get / kv_set per-world save data), audio (sound_play), world (ground_y), time (timers), and players (player_name, teleports).