New route prefab (routes.rhai): cars, buses, motorbikes, cyclists, people,
deer or elephants move along waypoints, round a loop or there and back.
Each way keeps to the left of the line (or right), corners are rounded
into pieces of at most 45 degrees; there-and-back routes become loops with
U-turns, so the two directions never share a strip.
Engine: Prim::Travel / sprite.begin_travel / script travel(a, b, dur,
windows) ... end(): the mover is drawn at a piece's start and slides to
its end while it is on that piece, hidden otherwise. The renderer writes
keyframes per piece (named by a hash of their content) into one <style>
per view. Each piece is its own sprite with the lane strip as its sort
extent (ext_reset), mitred at the corners, so movers pass in front of and
behind trees, lamps and houses. Movers that look alike and never meet on
a piece share one drawing. iso-travel pauses (not hides) in still,
reduced-motion and ghosted views.
Studio: meta shape "path" draws point by point (snapping like runs) and
saves one object with pts; ending on the first point closes the loop.
MCP: pts in the object schema, route guidance.
Demos: streets gets traffic round the block, a bus, motorbikes, cyclists
and strolling people (replacing the one-axis cars); country gets cars on
the lane.
Tests: Rust 79 (each mover on exactly one piece at every moment, in every
rotation), Studio 125, web 99.
New stdlib module wildlife.rhai:
- Animals (new palette category): Deer (stag with antlers, does, fawns),
Wild boar, Fox, Elephant (bull with tusks, cow, calf), Rabbits. Low-poly
solids from faces (loft, tube), parts drawn back to front by depth, faces
edged in their own shade (class beast). Herds scatter round a spot, each
animal its own sprite facing about the object's rotation. Grazing
animals switch between two head poses (iso-pose2 groups), elephants curl
their trunks, rabbits hop.
- Birds and Butterflies as flocks: swim() takes a shape (bird, fly, bee);
wings flap out of step. Fish output unchanged.
- Beehives on stands with supers, lids, entrances and bees flying round;
Bush (round, flowering, berries); Flowers (bed in rows or meadow); Rocks;
Log or stump. g-meadow and g-soil ground materials.
- polyline() takes 3D points as documented (antlers).
Theme colours for dark and light, viewer CSS for poses, flapping, hopping.
examples/country: elephants in a paddock with a cut corner, deer at a
forest edge, boar, fox, rabbits, an apiary by a meadow, a pond, a lane,
fence and hedgerow at angles; Country demo in the web Studio and deploy.
MCP guidance, README, SCRIPTING, ROADMAP.
Tests: Rust 78, Studio 122; existing examples draw the same (only the
embedded theme CSS grew).
Object frames turn by any angle (quarter turns stay exact, so scenes along
the axes render byte for byte as before); a box in a turned frame is a
prism with its own corners. Rotation is kept as given (normalised to
0..360), no longer snapped to quarter turns.
Depth sort: sprites whose plan outline is not their box carry their convex
outline; when boxes overlap, an outline edge that separates two sprites
orders them. A long diagonal wall sorts right against both sides.
Joints (line_meet, end_cut, cut_box in util.rhai): where a piece off the
axes is involved, corners are mitred and T-junctions slanted; fences put a
corner post or pillar in its own sprite and mitre stone bases; Y joints let
the lowest id run through. Streets: every end part is a cut e + k*w, so
side streets come in at any angle (slanted sidewalk gaps), two streets meet
in a mitre with seam patches; fixes a curve's outer sidewalk that was
skipped when its kerb and back lines had different point counts.
Studio: runs and drags keep to x/y or snap to 45 degree diagonals, Ctrl
gives any angle; a road run turning 45 degrees gets a 45 degree curve;
Rotation is a number box. Streets demo: a diagonal lane with a hedge.
MCP guidance, SCRIPTING/README/ROADMAP.
Tests: Rust 76, Studio and web checks green.
Roads take sidewalks (none, both, left, right): 12 cm high paving with
kerb faces drawn where they face the viewer. Road curve (radius, angle,
left/right) carries a street round a bend; centre lines are true arcs
when cut and offset, so curve 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, give-way lines on the entry side (traffic on the left
or right) and a central island with apron.
Studio: a road run drawn corner by corner gets a curve in each corner
(prefab meta `corner`). Tooltips list the streets each one meets.
Engine: open `polyline` primitive (Prim::Poly open) so dashes run on
round curves. examples/streets and a Streets demo in the web Studio;
MCP guidance, docs. ROADMAP: backlog 5-7 done; multi-select and the
hosted copy marked done.
Tests: Rust 72, Studio 113, web 95.
- Robot arm (category Industry): picks goods off the end of the nearest conveyor within its reach
and puts them on the start of another conveyor within reach, or on a pallet a quarter turn on
(pick / put: auto or a side). One move per item coming in (cycle 0) or a set cycle; waits while
the line before it stands. The belt it feeds carries its goods at its pace and starts its loop
when they land (feeds carry a time offset `ph`), so arm and belts stay in step.
- Drawn as a 16-pose flipbook: two-link inverse kinematics per pose, each pose shown for a
sixteenth of the cycle by a stepped CSS animation (iso-flip; pose 0 alone when unanimated).
Poses pointing away from the viewer are drawn before the base, the others after it.
- New sprite method beam(a, b, n, w, mat): a square bar between two 3D points, six faces culled
and shaded like face(). Native, so the factory demo renders in 4.7 ms instead of 18.8 ms.
- Factory demo: a palletiser at the end of the carton line, a loading robot passing drums from the
incline onto the loading belt into the truck. MCP instructions on robot arms.
Checks: 70 Rust tests (arms and belts in step, waiting arm, beam faces from every side),
Studio 109/109, web 90/90.
Selection: S.sel stays the object picked last; S.selIds holds everything
selected.
- In the object list, Ctrl+click adds or removes an object and
Shift+click selects a range.
- On the map, Ctrl/Shift+click toggles an object and Shift+drag draws a
box that selects what lies wholly inside it (locked and hidden objects
are left out).
- Ctrl+A selects everything that is not locked; Esc selects nothing.
- Clicking a wall or fence a second time selects every piece of the same
type joined to it; another click goes back to that one piece.
- Dragging one selected object moves them all, together with the windows
and doors on them, as one undo step. Arrow keys, R (turns the group
about its middle), Ctrl+D, Delete, Lock and Hide all work on the whole
selection.
- When all selected objects share a type, the property form edits them
all; fields where they differ show "mixed".
- The agent's system prompt lists the selected objects.
The viewer outlines several objects with selectObj([ids]) and passes the
click event to onPick. A batch op now answers `ids`, one per operation,
so the copies from a group duplicate get selected.
Pond (Nature): natural, round or square, with a stone or grass edge,
fish, lily pads, spreading ripples and reed clumps. The fish come from a
new Swim primitive (script: s.swim). One matrix maps the object's frame
to the screen. Each fish turns round its ellipse with a CSS rotation,
so off-screen pausing and reduced motion apply as for the other
animations. The house demo gets a koi pond in the back garden.
Tests: ponds in every shape and rotation have the right number of fish,
no NaN and no depth-sort cycles, and stay inside their rectangle.
check_studio covers list and map multi-select, a group drag undone in
one step, joined-fence selection, a mixed-value form applied to all, box
select, delete and undo, Ctrl+A, Esc, and a new pond's fish.