Files
isokit/README.md
T

137 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <project>` 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 <dir>` | 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 <shot-dir> 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`.