poqpoq imports content from OpenSim and Second Life. Both pipelines render the same geometry — but not the same way. The story of how one tiny convention disagreement cascaded through 1,500 columns, and the architectural discipline that finally stopped it.
Second Life and OpenSim ship one parametric mesh generator. When their viewer renders a torus, when their physics engine meshes it, when their export tool dumps it to disk — every layer reads vertex layout, axis orientation, and profile direction from the same source. There is no second pipeline that produces a torus differently and then needs reconciling.
poqpoq is built on a different engine entirely. Its parametric shape generators have their own reasonable defaults — for "which axis is up," for which direction profiles wind, for whether a default torus stands upright or lies flat. These defaults are internally consistent. They just aren't the same as the source-world's. Every disagreement is a place where a small correction could be applied to make the visible shape match.
The first time you write that correction, it looks local. A single shape, a single prim, one rotation tweak, and the visible donut renders correctly. The fifth time, it is a pattern. The fiftieth time, something has happened to the orientation field on every imported object: it has stopped meaning "where the user wanted this facing" and started meaning "where the user wanted this facing, plus whatever geometry corrections accumulated along the way."
That distinction sounds academic until the day a builder imports 1,500 Doric columns into a sim and watches all of them tilt.
Why columns? Doric columns are composed of small linked pieces — a base, a shaft, a capital. The capital is a torus. When the torus's orientation field carries an injected correction, and the column inherits that torus's frame as its reference, every child piece of the column gets the same correction applied to it. One Post-it stuck on one field, multiplied across an entire imported world.
The bug was a cascade because the orientation field had two readers who fundamentally disagreed about what it meant. The geometry pipeline read it as "rotate this shape this much." The linkset system read it as "this is the user's reference frame, so everything attached to this object positions relative to it." When the field carries only user intent, both readers agree. When the field carries user intent plus a geometry-correction quietly injected at import time, the readers split, and the children of the rotated parent come along for the ride.
Fixing the visible tilt would have meant patching every reader. The real fix was somewhere else entirely: in the geometry pipeline, before anything reached the orientation field.
Linden Lab built the entire viewer pipeline themselves. There is no second engine inside their system that disagrees with the first about how a torus should be oriented — so their orientation field can carry pure user intent, and every consumer downstream can trust that reading. The field is clean because nothing in their pipeline contaminates it.
poqpoq has a different rendering engine. Every place where its defaults disagree with the source-world's defaults is a place where a correction could land. The mantra answers where: the correction belongs in the place where vertices are made — baked into the geometry itself — not in the orientation field that seven other systems read. Vertex baking is inside the geometry pipeline; what gets baked there cannot leak. Orientation fields sit between systems; what lands there cascades through every reader.
The mantra surfaced an architectural framing that turned a single bug-cluster fix into a durable design contract. Every parametric shape is really two independent things, and those things must never share a field:
| Layer | What it is | Who owns the convention |
|---|---|---|
| Shape | The vertex positions, baked at generation time, frozen. | The geometry pipeline. |
| Placement | Where the user put it. How the user oriented it. | The user. |
Shape carries the canonical-orientation convention internally: an identity-rotation torus looks like a barrel because the vertices were baked that way, not because a placement correction made it so. Placement carries pure user intent — what the build tool emitted when the user dragged the gizmo, what the import source said the user had oriented the object as.
The moment a geometry correction lands in Placement, every downstream consumer that reads Placement inherits the contamination. The linkset frame inherits it. Scripts that ask "what direction is this object facing?" inherit it. The gizmo's reference-axis display inherits it. Re-exporting the world to another platform inherits it. Federation across other worlds inherits it.
The opposite is also true: keeping Placement clean unlocks every consumer to behave correctly by default. The fix did not have to visit each consumer. It only had to visit the place where the contamination was being introduced.
Architectural mantras are useful when they have an operational form you can use mid-debug. This one does:
When you find a Post-it in the Placement layer — a rotation tweak conditional on prim type, a per-shape axis swap, a special-case offset added at export time — strip it. Push it into vertex generation. The downstream cascade goes with it. The question is small enough to be a habit, and big enough to close every bug in this class.
Every system that imports from another system faces this question somewhere. Game engines that import models from other modeling tools negotiate axis conventions. Physics engines that bridge between simulators negotiate units. Networking layers that bridge two protocols negotiate byte order. The pattern is universal: when two internally-consistent systems meet, every disagreement is a place where a correction could be applied at the wrong layer.
What does the source system promise? What does our system deliver by default? The disagreement might be one axis, one sign, one byte order — tiny individually, expensive in the wrong place.
Who downstream reads the field where the correction could land? If only one reader exists, a transform-layer correction is harmless. If five readers exist, the correction contaminates all five of them.
Move the bridge into the layer that is inside your own pipeline — the layer where what gets baked cannot leak. The cascade through downstream readers disappears when its source does.
Document the canonical orientation for every shape. Future you (or the next developer) needs a lookup table answering "what does identity-rotation produce for this shape?" so the next analogous problem never has to be rediscovered empirically.
This chapter handled one cross-engine bridge. The next two chapters handle two more architectural disciplines that emerged from the same family of bug-clusters — both of them constitutional rules rather than local fixes.