Documentation
    Preparing search index...

    Function registerShapeSerializers

    • The §79 node-type pair for §50's shape family — the nine classes R-23 shipped on 2026-08-09 (Circle, Ellipse, Rectangle, RegularPolygon, Polygon, Star, Sector, Ring, PathShape).

      const io = registerSceneNodeTypes({
      materials: resourceCatalog([["material/ink", ink]]),
      });

      Separated from registerRenderSerializers for registerPhysicsSerializers's reason and no other: nine classes and the §51 path parser behind PathShape are a real bundle unit, and a 3D or UI application that saves scenes should not carry the 2D vector stack to do it (§91). registerSceneNodeTypes calls this, so an application that wants everything still makes one call.

      A material key (see the module header — a shape points at a material it does not own), the two ordering fields, §49's two shadow flags, the flattening tolerance, §58's fill and stroke, and the shape's own parameters. There is deliberately no geometry key: a shape derives its fill and stroke from those parameters and owns the result (§83), exactly as a Sprite derives its quad, so the payload rebuilds it exactly and a document that named one would be naming a resource the application never created.

      A paint-derived shape (the §58 object tier, 2026-08-29) writes no material key, for the geometry key's exact reason: its material is derived from the paints the payload carries whole, and the reader re-derives it. The one resource inside a paint — a pattern's texture — travels as a logical key against SceneNodeTypeOptions.textures.

      fill and stroke are written only when they differ from the class's own default — "inherit"/null for the nine closed primitives, "none" for the three stroke-only ones. So a shape that names no paint writes the byte-identical document R-23 wrote, and a document written before §58 existed restores a fill-only shape with no field missing. A paint this build cannot draw — an unknown kind (§58's conic, or a later build's), a malformed object paint, or any object paint in a build that never called registerShapePaints() — is dropped rather than refused wherever a material key exists to fall back to: the shape reloads in that material's colour, visible and recoverable, where refusing the node would lose the artwork entirely. A paint-derived document has no such fallback, so there the drop becomes a loud FourError naming the paint and the registration call — inventing a material the document never named is the substituted triangle again. A paint the material cannot draw at all is a different matter and is refused, the way a Sprite whose material key resolves to a lit one is.

      §96's rule is that data from outside is filtered rather than trusted, and the A-12/R-18 precedent is that a corrupted field restores its default rather than taking the whole scene down. That applies to every field the class itself defaults — tolerance, radius, width, height, rotation, a rectangle's corner radius, the ordering and shadow fields.

      The other rule covers the parameters a shape's constructor makes required, because they are the shape: a regular polygon's side count, a star's two radii, a sector's angles, a ring's hole, a polygon's points, a path's commands. A document that does not carry one of those, carries one the class would refuse, or carries a pair that contradicts itself, is refused loudly with a FourError — the same answer registerRenderSerializers gives a missing material key, and for the same reason: the alternative is to invent a shape the document never described and hand it back as if it had. A substituted triangle looks like a bug in the author's data; a refusal names the node, the type, and the field.

      §51's arc command stores a signed sweep; §51's builder — the only parse that preserves the well-formedness every reader assumes, which is why Path has no fromCommands — takes a start angle and an end angle. So an arc is written as [startAngle, endAngle] and read back through ellipse(…), which recomputes the sweep. The recomputed sweep can differ from the original by a few ulps when the start angle is large beside the sweep (measured: up to 1.8e-15 rad over 200 000 samples), because fl(fl(s + d) − s) is not d in general and no choice of end angle can make it one.

      Writing the end angle rather than the sweep is what keeps the document exact anyway: fl(s + arcSweep(s, e)) is e for every pair measured (0 mismatches in 500 000), so a document round-trips byte for byte even though the path's stored sweep may move in its last bit. Whole turns and zero sweeps are exact in both, since arcSweep returns ±2π and 0 by early exit. Nothing else in the family is affected: the eight parametric shapes store their own parameters and restore them bit for bit.

      Matched by exact class identity, like every other pair here.

      Parameters

      Returns SceneNodeTypeSupport

      the writer and reader halves; pass both or neither