Deploy web Studio / deploy (push) Successful in 1m4s
Studio: one selected object with pts (a route, an outlined area) shows a handle on each point and a + in the middle of each side: drag a point to move it, drag a + to add one there, double-click a point to remove it (open routes keep 2, outlines 3). Points snap to the grid and onto wall, fence and road ends, at any angle; one undo step each. Handles keep their screen size (new viewer callback onView on every redraw) and follow re-renders and selection. The viewer captures the pointer, so a double- click targets the drawing: the last point pressed is remembered instead. Prefab meta `outline`: the prefab draws pts as its outline. Area has it: Edit corners turns its rectangle into four points, Rectangle again removes them. Routes: where a path doubles back, the lane offset puts a point on each side, so it rounds into a U-turn instead of a diagonal across the lanes. The streets demo bus now runs east, three quarters round the roundabout (clockwise, left-hand traffic), down south street, turns and comes back by the short way, instead of going round the wrong way on its way out. Tests: Rust 81 (a doubling-back route: each mover once, no sort cycles), Studio 134 (corners, move, add, remove, undo), web 100.
195 lines
14 KiB
Markdown
195 lines
14 KiB
Markdown
# Roadmap
|
|
|
|
Each phase ends with tests, a Studio/viewer check in Edge, commit and push.
|
|
|
|
## Phase 1: engine, Studio, MCP (done)
|
|
|
|
- [x] Core: projection with 4 rotations, primitives (box, prism, cylinder, frustum, face, poly, flat,
|
|
openings, lines, disc, circle, stem, figures, puffs, fan, raw, groups, sequences), sprites with
|
|
90° object frames, depth sort ported from the JS views, SVG writer, tags, tooltips
|
|
- [x] Theme: built-in palette, materials and rules converted from the Mooban/CNX CSS; TOML overrides
|
|
- [x] Rhai runtime: drawing API, module imports from memory, errors with file:line, safety limits
|
|
- [x] Prefab library: site, area, road, parking, wall, fence, lamp, marker, tree, tree row, hedge,
|
|
building (storeys, windows, door, flat/gable roof, solar, AC, cut-open levels), carport, shed,
|
|
car (driving), truck, motorbike, person, crowd, tank, container, generator, solar field, chimney
|
|
- [x] Scene document + prefab catalog with property schemas
|
|
- [x] Project folder, ops (add/update/remove/duplicate/reorder/set_cfg/replace), Workspace (save, undo,
|
|
reload on outside changes), check, static HTML page, SVG export
|
|
- [x] Viewer JS: port of the views' mount() (pan, pinch, wheel, declutter, tooltips, full screen) for
|
|
prerendered, server and future WASM sources
|
|
- [x] Studio GUI: palette, object list, placing, drag-to-move with snap, keyboard, forms from schemas,
|
|
levels, undo/redo, live follow of agent edits, MCP connection panel
|
|
- [x] MCP: 15 tools over stdio and HTTP (`/mcp`), validation messages for agents
|
|
- [x] Demo project, 52 Rust tests, Playwright Studio + MCP test
|
|
|
|
## Web Studio (done)
|
|
|
|
- [x] `isokit-wasm`: the engine in the browser (wasm-bindgen, 2.8 MB / 0.75 MB gzipped); `Store`
|
|
trait (folder or memory) under the `Workspace`; Studio JSON API shared with `isokit studio`
|
|
- [x] `studio.js` runs on a pluggable backend; the web shell answers it from WASM
|
|
- [x] Projects in IndexedDB; new, demo copy, delete; export / import `.zip` (stored or deflated) and
|
|
folders (drop or pick); two tabs on one project stay in step
|
|
- [x] Folder projects (File System Access, Chrome / Edge): edits written to disk, outside changes
|
|
followed live and undoable, Build page writes `dist/index.html`
|
|
- [x] Code editor for scripts, prefabs, theme and manifest, with script errors by file and line
|
|
- [x] MCP tools inside the page (`isokit.mcp`), WebMCP registration when the browser offers it
|
|
- [x] `tools/build_web.py` (static output), `tools/check_web.py` (44 checks, Edge)
|
|
- [x] Hosted copy at https://isokit.buildfor.life/ (deployed by `.gitea/workflows/deploy-web.yml`)
|
|
- [ ] Render in a Web Worker for very large scenes
|
|
|
|
## Agent window (done)
|
|
|
|
- [x] ✦ Agent in the Studio: chat with a model on an OpenAI-compatible endpoint (default: B4L's
|
|
inference server) that edits the scene with the MCP tools + page tools (select, view);
|
|
streamed answers and reasoning, tool calls with results, clickable object ids, Stop, Undo
|
|
- [x] `isokit studio` relays the calls (`/api/agent/*`, key stays on the machine, no CORS);
|
|
settings from `ISOKIT_LLM_*` or `agent.json` in the user's config folder
|
|
- [x] Web Studio calls the endpoint from the page; isokit.buildfor.life relays `/llm/` to the
|
|
inference server (Caddy) so the page needs no CORS from it
|
|
- [x] `tools/mock_llm.py` + `tools/agent_checks.py` in both Studio checks
|
|
- [ ] Keep the conversation per project across reloads; attach a rendered view (PNG, Phase 4)
|
|
for vision models
|
|
|
|
## Build your own house (done)
|
|
|
|
- [x] House parts: `house_wall` (drawn along a line, ends adapt at corners, T-junctions and
|
|
straight runs), `window` and `door` that sit on a wall and cut its opening (door styles:
|
|
panel, glass, double, sliding, opening; open / closed, hinge and swing by rotation),
|
|
`floor` (boards / tiles / carpet / stone), `roof` (hip, gable, flat, solar), `stairs`
|
|
- [x] Furniture: chair, sofa / armchair, table with chairs, desk with monitor and chair, TV,
|
|
bed with nightstands, cupboard, bookshelf, kitchen run (sink, hob, wall cabinets, fridge),
|
|
bathtub, shower, toilet, washbasin, plant, rug, floor lamp
|
|
- [x] Cut-open levels for houses: walls in front of rooms cut low (rooms found by their floors),
|
|
roof as an outline, storeys from z (`storey_h`), upper storeys left out
|
|
- [x] Scripting: `objects_of`, `objects_at`, `objects_on`, `mount_of`, `mounted`, `frame`,
|
|
`to_world`, `to_local`, `local_of`; prefab meta `shape` (line / rect), `mount`, `storey`
|
|
- [x] Studio: drag to draw lines and rectangles (walls, roads, fences, floors, areas, buildings),
|
|
Room tool (floor + walls, shared walls not doubled), windows and doors snap onto walls
|
|
(hover preview) and move, turn, copy and delete with them, new parts land on the storey
|
|
shown, collapsible palette that scrolls on its own
|
|
- [x] `examples/house` (a furnished house built from parts), House demo in the web Studio
|
|
- [x] Diagonal walls (any angle, mitred corners, windows and doors on them)
|
|
- [ ] Openings across two walls; floor openings for stairs
|
|
|
|
## Backlog (2026-10)
|
|
|
|
1. ~~Web performance~~ (done, see below)
|
|
2. ~~Conveyors~~ (done, see below)
|
|
3. ~~Producers with adjustable production speed~~ (done, see below)
|
|
4. ~~Robotic arms~~ (done, see below)
|
|
5. ~~Rounded streets: curved road segments~~ (done, see below)
|
|
6. ~~Sidewalks along streets~~ (done, see below)
|
|
7. ~~Roundabouts~~ (done, see below)
|
|
8. ~~Waypoint animation: a person or car moving along a path of waypoints~~ (done, see below)
|
|
9. ~~Build your own house~~ (done, see above)
|
|
10. ~~Diagonal streets, walls, fences, hedges~~ (done, see below)
|
|
11. ~~Wildlife and nature: deer, bushes, beehives and more~~ (done, see below)
|
|
|
|
Done since: the middle mouse button only moves the camera; fences and site walls join like house
|
|
walls (`line_joint`); fence designs (mesh, wood, bars, half stone, cobble, brick with pillars);
|
|
runs of walls and fences drawn corner by corner, ends snapping onto the pieces they meet;
|
|
multi-select (Ctrl+click on the map and in the list, Shift range, Shift+drag box, Ctrl+A; group drag,
|
|
nudge, turn, copy, delete and property edits; a second click on a wall or fence selects the joined
|
|
run); the Pond with fish swimming round (`swim` primitive, CSS rotation), lily pads, ripples, reeds.
|
|
|
|
Web performance, measured with `tools/bench_web.py` on the web Studio's house demo with the CPU
|
|
slowed 6x (before → after): idle main thread in a browser window 99% → 5% (animations step about ten
|
|
times a second instead of repainting the drawing every frame; ▷ toolbar button: light / smooth / off,
|
|
`[build] animation`); zoom 69 → 11 ms per wheel step, pan 28 → 10 ms per move (gestures move the
|
|
drawing as one compositor layer and draw it again when they end; no forced layouts; `--iso-k` set on
|
|
the tags only); hover 22 → 15 ms per move (tooltip placed once per frame on its own layer, x/y
|
|
readout ten times a second); rotate 226 → 154 ms, edit 409 → 305 ms until painted (WASM built with
|
|
opt-level 3: engine render 11.7 → 9.4 ms at full speed).
|
|
|
|
Sharp zooming: the moved layer is a picture at the scale last drawn, so a long touchpad pinch showed
|
|
an ever more stretched, blurry view (3.6x at the end of a 1.2 s pinch) and every zoom ended with a
|
|
blur-then-snap 180 ms after its last step. Now the view is drawn anew during the gesture once the
|
|
picture is 30% off in scale (at most every 120 ms), and at its true scale 90 ms after the last step:
|
|
sharp about 130 instead of 240 ms after a pinch, at a cost of 11.4 → 14.6 ms per wheel step at 6x
|
|
slowdown (still no frame over 50 ms).
|
|
|
|
Production lines: Producer (a press making cartons, crates, drums, sacks or parts at a set rate
|
|
per minute, its ram going down once per item) and Conveyor (drawn the way it runs, belt width,
|
|
height, rise, speed; corners join without overlap). A conveyor starting at a producer's output, or
|
|
at another conveyor's end, carries those goods, spaced by speed / rate; tooltips show the numbers.
|
|
`examples/factory`, Factory demo in the web Studio.
|
|
|
|
Robot arm: picks goods off the end of the nearest belt in its reach and puts them on the start of
|
|
another belt or on a pallet, one move per item (or a set cycle), waiting while the line before it
|
|
stands; the belt after it runs in step. Drawn as a 16-pose flipbook (inverse kinematics, links as
|
|
the new native `beam` primitive) shown by a stepped CSS animation.
|
|
|
|
Streets (stdlib/streets.rhai): roads take sidewalks (none, both, left, right; 12 cm high paving with
|
|
kerb faces); Road curve (radius, angle, left / right) carries a street round a bend, its kerbs and
|
|
sidewalks drawn as true arcs so the joints are seamless; a road ending on another road's centre
|
|
line opens that road's kerb and sidewalk (T junction); two roads ending at one corner close it.
|
|
Roundabout: ring radius and width, one or two lanes, up to four arms with flared kerbs, splitter
|
|
islands and give-way lines on the entry side (traffic on the left or right), central island with
|
|
apron (tree, grass or paved). A road run drawn corner by corner gets a curve in each corner (prefab
|
|
meta `corner`). Tooltips list the streets each one meets. New `polyline` primitive (open paths, so
|
|
dashes run on round curves). `examples/streets`, Streets demo in the web Studio.
|
|
|
|
Diagonals: object frames turn by any angle (quarter turns stay exact, so scenes along the axes
|
|
draw as before, byte for byte). Roads, walls, fences, hedges and house walls run at any angle;
|
|
where a piece off the axes meets another, corners are mitred and T-junctions slanted
|
|
(`line_meet`, `cut_box`), fence corners get a post or pillar of their own, side streets come in at
|
|
a slant and open the sidewalk along them, two streets meet in a mitre. The depth sort orders
|
|
sprites whose plan outline is not their box by outline edges, so a long diagonal wall sorts right
|
|
against everything on either side. Studio: runs and drags keep to x or y or go diagonal at 45°
|
|
(Ctrl: any angle), a road run turning 45° gets a 45° curve, Rotation takes any angle. The
|
|
streets demo has a diagonal lane.
|
|
|
|
Wildlife and nature (`wildlife.rhai`): Deer, Wild boar, Fox, Elephant, Rabbits as low-poly solids
|
|
(`loft`, `tube`, parts drawn back to front), herds scattered round a spot, two head poses taking
|
|
turns while grazing, rabbits hopping; Birds and Butterflies as flocks (`swim` shapes, wings flapping
|
|
out of step); Beehives with bees, Bush, Flowers (bed or meadow), Rocks, Log / stump.
|
|
`examples/country`, Country demo in the web Studio.
|
|
|
|
Routes (`routes.rhai`, `travel` primitive): cars, buses, motorbikes, cyclists, people, deer and
|
|
elephants along waypoints drawn point by point in the Studio (`shape: "path"`, `pts`); loops or
|
|
there and back, each way on its side of the line, rounded corners. Every straight piece is a
|
|
sprite whose sort box is its lane strip, so movers pass in front of and behind what stands
|
|
beside the road; keyframes per piece show a mover only while it is on it. Streets demo: traffic
|
|
round the block, a bus, motorbikes, cyclists, people; country demo: cars on the lane.
|
|
|
|
Groups and the drawing order: objects of type `group` draw nothing; members carry the group's id
|
|
in `group` (groups nest), hiding or locking a group hides or locks all of it, removing it keeps
|
|
its members. The Studio's object list is a tree in the document order (each group just after
|
|
its members, so it draws as one block; ground pieces later lie on top): fold groups, eye and lock
|
|
per row, Ctrl+G / Ctrl+Shift+G, drag rows to reorder or into a group, ▲ ▼ and Ctrl+] / Ctrl+[
|
|
(with Shift to the front / back). Every tree edit is one undo step (`order` op: all ids at once).
|
|
|
|
## Phase 2: richer editing
|
|
|
|
- [x] Interior prefabs (see Build your own house); a building `rooms` prop is still open
|
|
- [ ] Path objects in the Studio: click points for roads (polyline with width), fences, walls, pipe
|
|
runs. Done: routes drawn point by point (meta `shape: "path"`); point handles on every object
|
|
with `pts` (move, add on a side, double-click removes); areas get Edit corners (meta `outline`)
|
|
- [x] Multi-select (box select, Ctrl+click, Shift range), group move, turn, copy, delete, edit
|
|
- [x] Groups in the object tree (fold, hide, lock, drag in and out) and the drawing order (drag, ▲ ▼)
|
|
- [ ] Align / distribute the selection
|
|
- [ ] Copy/paste between projects; prefab thumbnails in the palette (rendered icons)
|
|
- [ ] Measure tool and grid overlay; numeric resize handles on the selection
|
|
- [ ] Studio editor for `theme.toml` (colour pickers) and for project parameters
|
|
|
|
## Phase 3: embedding in the other projects
|
|
|
|
- [ ] Host pages on the WASM build (`isokit-wasm` exists, see Web Studio): the same scene
|
|
recomputes in the browser when a host page's calculator changes the parameters (cnx_vinyl
|
|
fleet calculator)
|
|
- [ ] `isokit build --fragment`: `<style>` + `<script>` blocks for the Python build scripts of the
|
|
host pages (replace `inline.py`)
|
|
- [ ] Host API parity with CNXIso (`mount`, `update(cfg)`, `setLevel`, `focus`, `info`, `onPick`)
|
|
- [ ] Port the existing scenes: mooban estate, CNX Scuba centre (section cut), CNX Vinyl plant;
|
|
check each against its old view with the QA checklist from the skill
|
|
|
|
## Phase 4: output and QA
|
|
|
|
- [ ] Section cut layer (underground scenes) from iso-scuba: cut plane, clip-path per cavity
|
|
- [ ] PNG export (static style resolution + resvg) so agents get an image from `render_view`
|
|
- [ ] `isokit check` rules from the QA checklist: props on paved areas, runs ending in the air,
|
|
covers drawn over their contents, tag overlaps
|
|
- [ ] Performance budget test (render ms per view, 60 fps pan) on a 3,500-node scene
|
|
(`tools/bench_web.py` measures it by hand for now)
|
|
- [ ] Packaged desktop app (Tauri); shared projects for the hosted web Studio (behind login)
|