# isokit Isometric scene engine for B4L projects: site plans, plants and buildings drawn as SimCity-style views that you can pan, zoom, rotate, cut open by storey and click for details. One Rust binary does everything: - **Studio**: a GUI editor in the browser for people who don't code. You add objects from a palette, drag them into place, and edit their properties in forms. - **MCP server**: AI agents (Hermes and others) edit the same scene with the same operations; their changes show up live in an open Studio. - **Build**: a self-contained HTML page with every view prerendered, or standalone SVGs for documents. - **Engine and scripting**: everything you can place is a *prefab* written in [Rhai](https://rhai.rs). Projects add their own prefabs, scripts and colours without touching the engine. The engine is a Rust port of the hand-written JS views in `cnx_vinyl` (fleet calculator), `cnx_scuba` (centre view) and `mooban` (estate view), and it keeps their look: same projection, depth sort, face shading, palette and viewer behaviour. ## Quick start ```bash cargo build --release # target/release/isokit.exe (one file, ~7 MB) isokit new C:/dev/myproject/site-view # starter project isokit studio C:/dev/myproject/site-view # opens the editor in the browser isokit build C:/dev/myproject/site-view # dist/index.html, no server needed ``` Try the demo: `isokit studio examples/demo`. ### Studio (for everyone) | Do | How | |---|---| | Add | pick an object on the left, click on the map (Shift-click places several) | | Select | click it on the map or in the object list | | Move | drag it, or arrow keys by the snap step (0.1 / 0.5 / 1 / 5 m) | | Turn | R / Shift+R or ⟲ ⟳ | | Edit | the right panel: size, storeys, colours, solar, tooltip text, label, levels | | Copy / delete | Ctrl+D / Delete; Ctrl+Z / Ctrl+Y undo and redo | | Look | drag the ground to pan, Ctrl+wheel or pinch to zoom, ↺ ↻ rotate, Site / GF / 1F levels | Every change is saved to `scene.json` at once. When the file changes on disk (an agent, git pull, another editor), the Studio reloads it, and that change can be undone like any other. ### Agents (MCP) While the Studio runs, it also serves MCP over HTTP at `http://127.0.0.1:7878/mcp`. Without the Studio, run `isokit mcp ` over stdio. In Hermes (`config.yaml`): ```yaml mcp_servers: isokit: command: C:\dev\isokit\target\release\isokit.exe args: [mcp, C:\dev\myproject\site-view] ``` Tools: `project_info`, `list_prefabs`, `list_objects`, `get_object`, `add_object`, `update_object`, `remove_object`, `duplicate_object`, `apply_ops` (batch, one undo step), `set_params`, `render_view`, `check_project`, `build_html`, `undo`, `redo`. Bad input comes back with a message that says what is allowed, e.g. the list of types or a prop's range. ## A project ```text isokit.toml title, levels, parameters, theme files, prefab libraries scene.json the objects (edited by the Studio and agents) scene.rhai optional script, drawn before the objects lib/*.rhai optional project prefabs (listed under prelude) theme.toml optional colours and materials ``` An object in `scene.json`: ```json { "id": "hall", "type": "building", "name": "Workshop", "x": -12, "y": 6, "rot": 90, "props": { "w": 24, "d": 12, "floors": 2, "pv": true }, "tag": "Workshop", "info": "Two storeys, solar on the roof", "levels": [] } ``` Coordinates are metres: x points east, y north, z up. `x, y` is the centre of the footprint, and `rot` turns the object in 90° steps. Levels: `site` (or any other id) shows buildings closed, while `gf`, `1f`, `2f` … cut them open at that storey. ## Commands | Command | | |---|---| | `isokit new ` | starter project | | `isokit studio [dir] [--port N] [--no-open]` | GUI editor + `/mcp` + `/view` live preview | | `isokit mcp [dir]` | MCP over stdio | | `isokit build [dir] [-o file]` | self-contained HTML (all levels × 4 rotations) | | `isokit render [dir] -o x.svg [--level gf] [--rot 2] [--light]` | one view as SVG | | `isokit check [dir]` | lint: unknown types, props out of range, script warnings, NaN, node budget, unstyled classes | | `isokit prefabs [dir]` | object types and their properties | ## Architecture ```text crates/isokit-core projection (4 rotations), primitives, sprites, depth sort, SVG (no deps but serde) crates/isokit-theme TOML palettes / materials / rules -> CSS; built-in default theme crates/isokit-script Rhai runtime: drawing API, prefab library (stdlib/*.rhai), scene document driver crates/isokit-project project folder, document ops, export, check, Workspace (undo, reload), MCP tools crates/isokit-cli the `isokit` binary: Studio HTTP server, MCP stdio, build/render/check viewer/ isokit-view.js/.css: pan, zoom, levels, rotation, tooltips (any page can embed it) studio/ the Studio GUI (served by `isokit studio`) examples/demo demo project ``` The layers are independent. A Rust program can draw with `isokit-core` alone. `isokit-script` reads sources from memory, with no disk access, so the same runtime can later run in the browser as WASM. The Studio and MCP both apply the same `ops::Op` JSON operations through a `Workspace`. Writing prefabs and scripts: [docs/SCRIPTING.md](docs/SCRIPTING.md). Plans: [docs/ROADMAP.md](docs/ROADMAP.md). ## Development ```bash cargo test # engine, runtime, ops, demo, MCP cargo clippy --all-targets -- -D warnings isokit studio examples/demo --port 7890 --no-open & uv run --with playwright python tools/check_studio.py http://127.0.0.1:7890 # GUI + MCP end to end (Edge) ``` Set `ISOKIT_ASSETS=C:/dev/isokit` to serve `viewer/` and `studio/` from disk, so you can edit the GUI without rebuilding. `tools/css2theme.py` converted the original views' CSS into `crates/isokit-theme/themes/default.toml`.