[path] — for shape_field
The one table that carries geometry rather than a selector or a size, and the
only place a preset draws a silhouette nobody put in the marks roster. Inline
SVG path data, parsed once at load into a closed contour, rendered as the same
signed distance field the roster is rendered as — so an authored figure gets
palette_steps, palette_contour, gamma and both coord_modes for free.
coord_mode = "1"has one precondition your contour may not meet: every ray from the figure’s centre has to leave the outline exactly once. A crescent, a figure with fins and a silhouette with deep sinuses do not, and the scene draws the distance instead and warns at load — see Two coordinates for what qualifies and what does not.
| Key | Values | Notes |
|---|---|---|
d | SVG path data | The silhouette, as one closed contour. Required — the table exists to carry it. |
morph_to | SVG path data | A second silhouette the bindable morph param travels towards. Optional; absent, morph is inert. |
samples | integer 3..=64 | The arity both contours are resampled to, by arc length. Default 64. Optional — and a lever downward. |
Coordinates read the way SVG writes them: y increases downward, so M 0,-1
sits above M 0,1. That is what a design tool exports and what a browser draws,
so a path pasted out of one arrives the right way up with nothing to edit.
system = "shape_field"
[path]d = "M 0,-1 C 0.9,-0.4 0.9,0.4 0,1 C -0.9,0.4 -0.9,-0.4 0,-1 Z"morph_to = "M 0,-1 L 0.87,0.5 L -0.87,0.5 Z"
[params]morph = "beat" # an ordinary binding; [smoothing] reaches it like any otherstroke = "0" # 0 fills the figure; above 0 draws its outline at that widthThe subset, and what it refuses
Accepted: M m L l H h V v C c S s Q q T t Z z — moveto, the three line
forms, cubic and quadratic Béziers with their smooth-continuation shorthands, and
closepath. Relative commands, implicit repeats (M x y x y is a moveto and a
lineto), missing separators and exponent notation all parse, because that is what
an exported file actually contains. A path with no Z is closed anyway: a filled
silhouette has no open form.
Two things are refused by name, and you will meet them holding a file a browser renders correctly:
A/a, the elliptical arc. Every design tool can re-export the same curve as cubics; look for a “convert arcs to paths” or “flatten” option.- A second subpath — a second
Manywhere after the first. Any letterform with a counter has one, as does any shape with a hole. There is no natural point correspondence between two paths with different subpath counts, which is what a morph needs, so the pair that could not be aligned is refused at the one path rather than guessed at the morph.
Everything else that goes wrong is a load error carrying the character offset
into d — a mis-parsed path would otherwise render as a plausible wrong figure,
which reads as a design decision rather than as a mistake.
The arity ceiling, and the measurement behind it
samples is capped at 64, and asking for more is a load error naming both
your number and the ceiling. It is not a memory bound: the field is fullscreen
and evaluates a distance to every segment at every pixel of every frame,
whether or not the figure is on screen.
The number is measured rather than reasoned. At 1920x1080 on an integrated GPU — the class Non-functional requirements’s floor tier is calibrated against — the contour walk costs about 0.095 ms per segment (measured 2026-09-17), so 64 segments is 43 % of the 60 fps frame budget; 128 measured 87 % on the day the ceiling was set. A traced logo pasted at 500 points is refused rather than quietly decimated, because a reduced contour would draw a figure you did not author and never say so.
A curved path can be cheaper than that, because it need not be drawn as segments: a contour is fitted at load to a chain of circular arcs, and where the fit is kept the leaf above costs 4.15 ms as 16 arc pieces where its 64-point polyline costs 7.09 ms.
But the axis is total curve detail, not smoothness, and most real silhouettes are outside it. Nothing in the table selects the fit, and there is no setting that asks for it. The fit is measured against a lateral tolerance fixed at the tightest figure size an author would reach for, and then it is discarded unless it clears both of these:
- at most 32 pieces — the chain’s own bound;
- at most half the
samplesarity, because an arc piece costs more per pixel than a line segment, so a chain that did not collapse the count is worse than the polyline it replaced. At the defaultsamples = 64that means 32; atsamples = 32it means 16.
The measured figures that do fit, from core/tests/path_cost.rs’s arc
comparison: a circle written as 4 cubics fits in 6 pieces, the leaf above in
16, and a 4-cubic blob in 24. That is the whole reachable band — a
figure’s detail at a fixed tolerance is what decides it, and a detailed contour
is discarded however smooth every one of its curves is. A 39-vertex outline with
every vertex smooth was discarded and rendered faceted, identically to a spiky
maple.
So: a figure of a handful of curves gets the chain, a drawn silhouette usually
does not, and a figure carrying a morph_to never does (see below). If your
authored figure reads faceted, that is the ceiling and not a setting you missed.
Set samples low for a polygonal figure. A hexagon needs 6, not 64, and pays
for what it asks.
What morphs well
A pair travels well when both are single closed contours of comparable complexity. That is the thing you can act on; the alignment does the rest:
- Winding is normalized for you. A clockwise path morphing into a counter-clockwise one would turn inside out through the middle — every intermediate frame a valid shape, the whole motion wrong — so the target is reversed where the two disagree. You do not have to draw them the same way round.
- The start point is chosen for you, by minimising how far the points travel in total. Without it a square morphing into the same square from another corner unwinds through a spiral.
- Both endpoints resample by arc length, not per command, so a shape whose commands are unevenly sized does not bunch its correspondence where you happened to click.
What no alignment fixes is a mismatch of kind. Two figures of very different complexity — a triangle into a thirty-point starburst — correspond point for point, so most of the starburst’s detail collapses onto three corners on the way. Sweep the travel and look at the middle rather than at the two ends: the intermediate is a shape nobody authored, and it is where a bad pair shows.
A morphing pair draws through its polyline, not through the arc fit — two arc
chains have no point correspondence to interpolate. So a morph_to costs the
samples arity above, and a figure that does not morph does not.
A long path stops being readable
This is a real cost of the feature and not something to discover in review. A
64-point traced outline is one very long unreadable line in a file format whose
whole value has been that a person can read what a look does. Prefer a path you
could redraw from the numbers — a dozen commands, round coordinates — and keep
the shapes that genuinely need tracing rare. If a preset’s d is longer than the
rest of the file put together, the file has stopped explaining itself.
Built from 13c7582 at version 0.158.0. This site tracks main and is not versioned per release.