Bundled assets — portable files without path guessing
Manic scenes can use small, documented production assets through a stable
asset: URI. The URI works from the desktop CLI, a different working
directory, the Docker image, or the production backend. No render flag is
needed.
image(mark, (cx, 260), "asset:manic-logo.png", 180, 180);
model3(beacon, "asset:models/manic-pyramid.obj", (0,0,0), 1);
assembly3(console, "asset:models/manic-console.obj", (3,0,0), 1);
svg(logo, (cx, 480), "asset:svg/heart.svg", 320);
The same image URI can be used in a Creator profile:
creator(me, "@anish2good name=Manic logo=asset:manic-logo.png footer=signature");
socials(me);
Available public assets
| Stable URI | Kind | Useful for |
|---|---|---|
asset:manic-logo.png | PNG | image(...), Creator logo=, a Manic-branded example |
asset:models/manic-pyramid.obj | Geometry-only OBJ | model3(...), a beacon, monument, marker, or placeholder model |
asset:models/manic-console.obj | Grouped geometry-only OBJ | assembly3(...), addressable base/screen/key parts, staged technical stories |
asset:svg/lucide/<name>.svg | SVG icons — Lucide (ISC) | svg(...), themeable line icons (recolour to taste) |
asset:svg/heroicons/<name>.svg | SVG icons — Heroicons (MIT) | svg(...), solid glyphs |
asset:svg/flags/<cc>.svg | SVG flags — flag-icons (MIT) | svg(...), country flags in real colours |
asset:svg/emoji/<name-or-codepoint>.svg | SVG emoji — Twemoji (CC-BY 4.0) | svg(...), flat colour emoji; fire.svg/1f525.svg |
asset:svg/heart.svg · pin.svg · robot.svg · map-region.svg | SVG demo art (CC0) | svg(...), the import demos |
asset:svg/physics/effusion-reservoir.svg | SVG scientific apparatus (CC0) | reusable thermal-reservoir/nozzle shell for process stories |
The SVG sets are a curated, permissively-licensed starter pack (see
assets/svg/LICENSES.md). List what’s bundled — and what a file imports as — with
manic svgcheck assets/svg.
The catalog stays deliberately small. Do not invent an asset name that is not
listed here. Manic reports a clear error if a bundled URI is missing, and it
rejects .. traversal. OBJ files also retain the normal file-size and geometry
safety limits.
Vector import — SVG as native geometry
svg() brings vector artwork in as native path entities — not a texture. Each
subpath of the SVG becomes a real Polyline/Polygon you can draw, morph, recolour,
and animate exactly like a shape you authored by hand. It’s the 2D twin of model3’s
OBJ import.
svg(logo, (cx, cy), "asset:svg/heart.svg", 320);
Reposition — the second argument is the centre. Move it, or animate it; every piece follows because the whole drawing shares one tag:
svg(pin, (cx, cy), "asset:svg/pin.svg", 200); // centred at (cx, cy)
move(pin, (cx, cy - 200), 1.0); // glide the whole drawing up
Resize — the last argument is the width in pixels; the height follows the artwork’s own aspect ratio:
svg(small, (300, cy), "asset:svg/robot.svg", 120); // 120 px wide
svg(big, (800, cy), "asset:svg/robot.svg", 360); // same file, 3× bigger — still crisp
Recolour — imported fills reproduce faithfully (they are not re-themed by the template, even if a colour happens to match a palette name). Change them whenever you like:
recolor(logo, cyan); // whole drawing → cyan
hue(logo, 200, 0.9, 0.6); // …or by HSL
gradient(logo, gold, magenta); // …or a gradient across it
Animate — one verb drives the whole drawing (it is tagged with the id):
hidden(logo); show(logo, 0.8); // reveal
pulse(logo, 0.9); // emphasise
Address one piece — subpaths are named {id}.p0, {id}.p1, … in document
order, so you can single one out:
recolor(pin.p1, gold); // just the pin's inner hole
Layering — imported art defaults to z = 0. Raise it above another layer
(a grid, a backdrop) with z:
z(logo, 6);
What v1 imports (and what it skips)
Imported: paths plus the basic shapes (rect, circle, ellipse, line,
polygon, polyline) with their transforms resolved, and solid fill/stroke
colours. Curves are flattened to smooth polylines.
Imported gradients: linear and radial fill gradients come in faithfully (mapped
onto Manic’s gradient(), multi-stop ramps resampled) — so gradient icons,
illustrations, and emblems keep their shading.
Skipped for now: SVG <text> and embedded <image>, clipPath/mask, filters and
blurs, pattern paint, and gradient strokes (fills are supported). Keep artwork
reasonably simple — there’s a point-budget guard and the usual file-size limit.
Two things worth knowing:
currentColor— most icon sets (Lucide, Heroicons, …) paint withcurrentColor, a host-themed placeholder. Manic imports those as themeable geometry: they take the entity’s own colour, sorecolor(icon, cyan)just works. Artwork with real colours (flags, illustrations) keeps them faithfully.- Concave fills are triangulated (ear-clipping), so stars, notched glyphs, and blobs fill correctly — not just convex shapes.
Screen a set before you rely on it
Downloaded a folder of SVGs? Vet them against the importer first:
$ manic svgcheck assets/svg/lucide
✓ rocket.svg — 4 paths, 199 pts, themeable (0 with fill/stroke)
✓ map-pin.svg — 2 paths, 147 pts, themeable (0 with fill/stroke)
…
Each file reports its subpath/point count and whether it’s themeable (recolour it)
or coloured (keeps its own colours); anything empty, over-budget, or unparseable is
flagged with ✗. scripts/fetch-svg-assets.sh vendors the bundled sets the same way.
Your own images and models
Ordinary paths still work:
image(photo, (cx,cy), "uploads/my-photo.jpg", 720, 480);
model3(product, "uploads/my-product.obj", (0,0,0), 1);
svg(logo, (cx,cy), "uploads/my-logo.svg", 300);
Bring in any SVG this way — an icon you downloaded, a logo, a map outline. The
caller must make those files available to the renderer. This is the right
choice for uploads and private brand assets; asset: is for the small catalog
that ships with Manic.
Adding a new bundled asset to Manic
- Put it under
assets/in a typed folder such asmodels/, with a lowercase, descriptive filename. - Add its stable URI to this page and
assets/README.md. - Add or update a checked
.manicexample using the URI. - Keep models geometry-only; do not add scripts, arbitrary shaders, or remote dependencies.
- Run the tests and mdBook build.
The release machinery copies the entire directory. Docker installs it at
/usr/local/share/manic/assets; Linux builds produce
dist/manic-assets.tar.gz; the EC2 deploy installs that archive; and the
playground sync mirrors the same catalog. Future entries therefore need no
per-file pipeline edit. A custom deployment may point MANIC_ASSETS_DIR at a
different catalog root.