iamar

Build a world
with your agent

Point your agent at this page. It says what an iamar world is made of, which commands check it, what a finished world must measure, and where the complete documents are. You describe the world; the agent builds, tests, signs and packs it; you host it from your own computer.

Works with Claude, Codex or any agent that can read a web page and run commands. iamar never runs the agent for you. Current release: v0.5.1, a test build.

Paste this to your agent

then replace the description
What a world is

A folder of data and models, signed and packed

A world is a package: a folder, later packed into one signed .iamar file. Two JSON files describe it, glTF models give it shape, and an optional WebAssembly script gives it behaviour the data cannot express.

Most worlds are data only. scene.json can say everything the browser already knows how to do: environment (sky, sun, fog), terrain, water, placed models, simple shapes, lights, sounds, spawn points, portals, triggers, creatures, NPCs with dialogue, and quests with a tracker and rewards. You describe; the browser runs it.

The package never contains engine code. It is glTF, PNG or JPEG, Ogg audio, JSON and, when needed, .wasm. Positions are in metres, +Y is up, a standing person is about 1.8 m.

my_world/
  manifest.json     who made it, version, budgets, features used
  scene.json        the world, as data: environment, terrain,
                    water, models, primitives, lights, sounds,
                    spawn points, portals, triggers, creatures,
                    NPCs, quests
  assets/*.glb      3D models, glTF 2.0 binary, textures embedded
  textures/         sky faces, terrain layers, heightmaps (PNG, JPEG)
  audio/            Ogg Vorbis
  scripts/*.wasm    optional behaviour, sandboxed (see Scripts)
  thumbnail.png     optional, 512 x 288
  tools/build.py    keep the Blender build script with the world

packed:  my_world-0.1.0.iamar   a plain zip of the same folder, signed

manifest.json, the short version

{
  "format": "iamar-world",  "format_version": 0,
  "id": "my_world",            the <world> of iamar://<owner>/<world>
  "name": "My World",  "description": "...",
  "author": {"name": "..."},
  "version": "0.1.0",         semver; bump it on every publish
  "api_version": "0.1",
  "budgets": {"triangles": 150000, "objects": 64, "texture_size": 1024,
              "texture_bytes": 33554432, "lights": 4,
              "package_bytes": 16777216, "audio_bytes": 4194304,
              "script_bytes": 0},
  "features": ["sky", "terrain", "objects", "npcs", "portals"],
  "license": "CC-BY-4.0",  "credits": [ ... ]
}

Every field, every scene.json section and the hard limits are in WORLD_FORMAT.md; where it and the JSON Schemas disagree, the schemas win. Unknown keys are errors, except keys starting with x-, which are yours for notes.

The tools

The kit is built into the browser you download

There is no separate SDK. The iamar browser executable contains the kit command line: scaffolding, the asset library, validation, screenshots, performance measurement, signing and packing. It needs no Godot, no source checkout, no Bash and no Python.

Engine options go before --, then --kit, the command and its arguments. preview, perf and impostors render, so run them in a desktop session without --headless; everything else runs headless.

The download also ships kit/iamar-world, a thin wrapper that finds the browser beside it and forwards to the same built-in commands (kit\iamar-world.cmd on Windows). Blender is the one optional external tool, for modelling and light baking; ask the user before installing it.

Linux

./Oakhaven.x86_64 --headless -- --kit help

Windows

Oakhaven.exe --headless -- --kit help

macOS

Oakhaven.app/Contents/MacOS/Oakhaven \
  --headless -- --kit help

The app is signed ad hoc, not notarized: once after unzipping, run xattr -dr com.apple.quarantine Oakhaven.app kit.

The commands, in the order you use them

# iamar-world below means the wrapper, or the browser form above
iamar-world new worlds/my_world --title "My World" --author "<name>"
iamar-world assets search tree oak        # premade objects: reuse before modelling
iamar-world assets show <name>            # size at scale 1, lowest point
iamar-world assets use worlds/my_world <hash|name> --as assets/oak.glb
iamar-world blender                       # is Blender installed?
iamar-world blender-run tools/build.py -- worlds/my_world
iamar-world validate worlds/my_world      # fix every ERROR, read every WARN
iamar-world preview  worlds/my_world /tmp/my_world   # screenshots: look at them
iamar-world perf     worlds/my_world /tmp/my_world   # triangles, draws, fps per view
iamar-world techniques worlds/my_world    # what the browser does for you; ADVICE lines
iamar-world impostors worlds/my_world     # far-away cards for big models
iamar-world tiers worlds/my_world         # lighter variants for lower GPUs
iamar-world keygen <name>                 # once: your signing key
iamar-world package worlds/my_world out/my_world-0.1.0.iamar <key> "<Name>"
iamar-world verify out/my_world-0.1.0.iamar
iamar-world add-to-browser out/my_world-0.1.0.iamar

Always look at the screenshots. preview shoots the spawn view, four views around the world, one from above and the NPCs, or the cameras you ask for with --view "x,y,z>lx,ly,lz". A world that only validates is not done.

The playbook

Nine steps, in this order, and no step skipped

This is the sequence the kit asks every agent to follow. Do not move on while a check fails; fix it with the recipe named in TECHNIQUES.md, the catalogue of techniques iamar worlds use to look good and stay smooth: LOD chains, impostors, merged and instanced meshes, baked light, texture sizes and more.

Design for the low tier first, then add the detail that only better GPUs show. One world can carry up to four hardware tiers; the package's own files are the low tier, and it must stay pleasant, because many visitors will see only that.

Hard targets, busiest view, low tier

Frame rate30 fps or more
Visible trianglesunder 150,000
Draw callsunder 150
Video memoryunder 600 MB
Any single frame, once loadedunder 50 ms
World scripts, per frameunder 2 ms
Package downloadas small as the world allows

The low tier is an old GPU like a Radeon HD 5750 with 1 GB. perf measures all of this; claim the frame-rate targets only when the run used comparable hardware, and say so when it did not.

  1. Plan

    Write down what the user asked for, a rough map with sizes in metres, where the spawn point faces, the paths people walk, and a budget for each area.

  2. Block out with primitives

    Ground, walls, paths, the spawn, the portals, each with a short stable id. Validate and preview. Check scale: a person is 1.8 m, doors 2.2 m, walkable slopes under 40 degrees.

  3. Reuse first, then model

    Search the library with assets search and assets use what fits; a reused object is referenced by hash, so visitors download nothing for it. Model the rest in Blender through the kit, bevel edges, use simple materials and atlases, and keep the build script with the world.

  4. Light the world

    Bake Cycles light for static architecture you modelled in Blender and rebake after geometry changes. Primitive-only and reused-asset worlds use the browser's live sun and environment; say so in the report.

  5. Bring it to life

    NPCs, quests, sounds, then scripts only for what the data cannot say. Scripts react to events; never loop every frame over many objects.

  6. Art pass

    Apply the manual recipes that make a world look finished: ground clutter, worn paths, lit windows, lived-in interiors, baked ambient occlusion. Suggest them to the user as you go.

  7. Make it fast

    Foliage thinning, impostors, no shadows on tiny things, collision proxies, right-sized textures, until every budget holds. techniques prints an ADVICE line for each recipe still to apply; fix every one.

  8. Review like a visitor

    Look at every preview from every side against the request. Walk every path and portal in the browser; if you cannot, add --view cameras along each route and say that walking stayed unverified.

  9. Report, then sign, pack and host

    Give the user the numbers: busiest view fps, triangles, draw calls, video memory, worst frame, script time, package size, what was reused, what was checked, and what hardware measured it.

The rules

  • Self-contained.Everything the world uses is inside the package, with relative paths. Built-in features are named in the data; engine files are never copied.
  • Stay within budgets.Visitors run everything from school laptops to gaming PCs. Merge small meshes, reuse one model for many placements, collision: "box" except where people walk.
  • Credit what you use.Every third-party asset needs its licence and author in credits. Prefer your own models or CC0 sources.
  • Ask before installing software.Blender, compilers. If the user says no, build from primitives and CC0 kits and keep going.
  • Never put secrets in a world.No keys, passwords or personal data. Everything in a package is public to its visitors.
  • Portals go to addresses.iamar://owner/world, iamar://owner/world#spawn, or oakhaven for the built-in home world. Every portal gets a label, and there is always a way home.
Scripts

When the data is not enough

A flock that runs from visitors, a door that opens for a password, a game with rules: that is a world script. Scripts are WebAssembly modules in scripts/ that the browser runs in a sandbox. A script can do exactly what the world API lists and nothing else: no files, no network, no clock beyond time(), no threads, no engine types. That is what lets a visitor walk into a world written by a stranger's agent.

Write them in TypeScript: ordinary strict TypeScript, checked by the official compiler and built into one sandboxed module that carries a small JavaScript engine. Every function is iamar.<name>(...) with JavaScript types; callbacks are plain global functions. Start with Build your own iamar world; every call is in the API reference.

Scripts react to events the browser calls them with: on_init(), on_enter(player), on_leave(player), on_interact, timers, triggers, clicks, keys, buttons and messages from the other visitors' copies. They are the successor of the 2009 Semblis world scripts, which registered the same callbacks by name.

// world.ts: a chicken next to every visitor, and a greeting
function on_init(): void {
  iamar.log("welcome world started");
}

function on_enter(player: number): void {
  const p = iamar.player_pos(player);
  if (p === null) return;
  const x = p[0] + 2, z = p[2];
  const hen = iamar.entity_spawn("chicken", x, iamar.ground_y(x, z), z, 0);
  if (hen > 0) iamar.entity_set_grounded(hen, true);
  iamar.ui_note(`Welcome, ${iamar.player_name(player) ?? "traveller"}!`);
}
# build it into the package's scripts/
kit/iamar-world compile-typescript world.ts <package-template> <fresh-out>

Built scripts go in scripts/*.wasm, are listed in the manifest, and run under the per-callback budgets in the reference. Each visitor runs their own copy; the copy where iamar.is_authority() is 1 decides shared state.

World creators

Script it in TypeScript, then make it beautiful

The three pages for people writing worlds: the complete API 0.3 reference (generated from world_api.json, so it cannot drift from the browser), a TypeScript getting-started with a first working script, and the art guide for the iamar look.

World API 0.3 — scripting in TypeScript is new; report problems with F4 in the browser.

World API 0.3 reference

Every function and callback, grouped, with its TypeScript form, error codes and the limits. Machine-readable copies for agents: iamar-world.d.ts and world_api.json.

Build your own iamar world

Getting started: what a world package is, the TypeScript workflow (world.ts → compile-typescript → package → Esc > Host My World), a first complete example — chickens that follow the player — and one short recipe per API group.

Make it look like iamar city

The art guide: palette, light and clutter in the right measure. Full guide coming as docs/WORLD_ART_GUIDE.md.

Hosting

Host it from your own computer and share the address

Every world is hosted by its owner, from their own computer, the way the 2009 iservers were. The iamar browser does the hosting itself: no second program, no router or port-forwarding setup. Visitors reach a home computer through the hub, and visitors who already have the world share its pieces with newcomers.

Creation is unlocked by playing iamar city's quests. After the milestone, the Creator setup panel in the browser issues a scoped key for the user's own agent: bound to that world, a limited set of operations and a lifetime, and revocable. The agent then uses the MCP tools to register the finished world; iamar never runs the agent and never sees an account password.

What the agent does

iamar-world keygen <your-name>                 # once; the .key stays private, out of the world
iamar-world package worlds/my_world out/my_world-0.1.0.iamar \
    ~/.config/iamar/signing/<name>.key "<Name>"  # signs, splits into pieces, writes the .iamar
iamar-world verify out/my_world-0.1.0.iamar
iamar-world add-to-browser out/my_world-0.1.0.iamar   # copies only that package into the browser

What the user does

  1. In iamar, press Esc and choose Host My World. You must be logged in: your account owns the world's address.
  2. Pick the world with the World button. It lists your packed, signed worlds.
  3. Choose who may visit: Everyone (public, listed in the directory), My buddies, or Only me for testing. Set an upload limit if you like.
  4. Press Start Hosting. The panel shows iamar://<account>/<world> and a free public link, iamar://<13 characters>, with a Copy button. That link is what you share.

The world is online exactly while the browser hosts it: it keeps hosting while you play elsewhere and stops when you quit or press Stop Hosting. Visitors check every piece against the signature and are asked before entering a world signed by a key they have not seen. For a new version, bump version in the manifest, pack again, add it to the browser again and host the new one. An always-on server can host instead with iamar-world serve.

For developers

The hub, the protocol and the source

The central hub is the successor of the 2009 PCS server. It does only what must be central: accounts, world lookup and access checks, the first introduction between two computers, buddies and invitations. Gameplay and content flow player to player or through the world's own host.

The hub protocol is one UTF-8 JSON object per WebSocket frame, plus a small read-only HTTP API. Version 1; additions keep it at 1.

The documents

The complete references, as plain text

These are the files an agent should read. They are copied from the source repositories, unchanged, and served here so any agent can fetch them. llms.txt lists them all in one place.