Skip to main content
Task-indexed quick reference. “I want to express X — which primitive do I reach for?” Each recipe is copy-paste ready. Both humans and agents read this. Agents should treat it as the authoritative mapping from natural-language intent to DSL primitive. For what makes a scene look DESIGNED (hero/accent rules, effect budget, composition patterns) see the scene design guide. For full field grammar see ../reference/dsl-yaml.md and ../reference/dsl-d2.md. For the machine-readable inventory call isotopo capabilities or read CAPABILITIES.md. For complete worked scenes see the samples index. The one rule that matters: never hand-compute coordinates. Position parts with layout (containers) and place (sibling relations); all gaps are in cells (1 cell = gridStep, default 40 world units). offset exists only as a fine-tune delta on top of a solved position.

Positioning

I want B next to A

One constraint per ground axis: rightOf/leftOf pins world x, inFrontOf/behind pins world y (front = toward the viewer). The unconstrained axis aligns to the referenced sibling — align: start|center|end (default center). References must be SIBLINGS in the same parts: list.

I want a pipeline / chain of parts

Chain place along one axis; the solver resolves the chain topologically:

I want a staircase climbing the iso axis

Each tile is right of AND in front of its predecessor (gap 0 = corner-to-corner):
See samples/topology/rag-pipeline for a two-step stair anchoring a full scene (substrates along the iso diagonal).

I want a grid / dashboard of cells

One container, layout: grid — the substrate auto-sizes:
mode: row marches along world +x, column along +y. See samples/topology/langchain-app for 2×2 grid service boards carrying glyph icons.

I want a part stacked ON TOP of another (plinth, ghost volume)

above pins world z — flush on the sibling’s top, centred on its footprint, no copied heights:
See samples/topology/training-compute.
Connectors + elevation: above / wz is for decorative parts with no wiring. If a stacked part needs a connector, the rule below (tiers) applies — keep it coplanar with what it links to.

I want a multi-tier architecture (gateway → service → data)

Group each tier and give the whole tier ONE wz, so connectors inside a tier stay flat 2D and only tier→tier links cross planes — that vertical drop then reads as a deliberate cross-layer call:
Never give two peer nodes in the SAME tier different wz — that produces a riser with no semantic meaning (the noir-sandbox bug).

I want a hub with satellites around it

One rule — ring: first child is the hub, the rest distribute clockwise from the back:
See samples/topology/ai-platform — the eight-tile ring is exactly this.

I want different gaps per axis

gapX / gapY override gap independently:

I want to nudge one part a few pixels

Keep the place/layout, add an offset — it’s applied as a delta AFTER solving, and parts placed relative to this one follow along:

I want absolute coordinates anyway

offset: {wx, wy, wz} without place is still honored (legacy documents render byte-identically). Reach for this only for free-form artistic scatter that relations can’t express.

Containers

I want to wrap N elements in a labeled container

Give the group a layout; never position children by hand:
Or .d2 (auto-layout does everything):
Children may also use place against each other instead of a layout — the substrate still auto-sizes around the solved bbox:

I want a nested container hierarchy (cluster > region > pod)

Nest parts: arbitrarily deep; inner groups are solved first so outer layouts see their final size:
Or .d2 — same dot-path semantics:

I want N replicas of one element

count = total layers, gap = world-Z step. Top layer’s id is pod~2, second from top pod~1, bottom keeps pod. Stacking is vertical — it composes freely with place/layout on the ground.

I want to lay out a graph automatically

Use .d2 instead of YAML. iso-topology runs dagre by default (polyline edges) or elk for orthogonal right-angle routing.

Annotations & connectors

I want a labeled callout pinned to a part

Document-level annotations: block:
Sides: top | right | bottom | left. Multi-line via \n. Default leader-line distance is 60 world units; override with distance: 90.

I want a directed arrow between two parts

For specific face-centers: from: api.right-mid, to: db.top-back.

I want grid-aligned (Manhattan) routing

Orthogonal paths ride the iso ground axes — every segment projects to exactly ±30°, in register with canvas.grid: iso. Use this for architecture flows; the default straight cuts across the grid. Golden rule for picking endpoints: connect nodes at the SAME height (wz/tier). Same-height pairs route as flat, clean 2D L-shapes. When several nodes could be the source or target, prefer the coplanar one. Only span heights for a deliberate cross-tier link (e.g. a hovering control plane projecting down) — that renders a vertical drop segment, which should be intentional, never an accident of mismatched wz. Same orthogonal routing as everything else — async is expressed by dash, NOT by a different geometry:
routing: bezier exists for non-iso freeform sketches only — in an iso scene a curve cuts across the grid and breaks the projection.

I want a dashed connector

dash uses SVG stroke-dasharray syntax: "4 3" = 4 on, 3 off.

Shapes & styling

I want a database / queue / stored-data icon

All three lower to the iso cylinder:

I want a user / actor icon

c4-person is also accepted as an alias.

I want a cloud / external system icon

I want a text-only label (no extruded box)

Low-extrusion panel, just text on the top face. Good for titles.

I want an icon on the top face instead of text

The preferred look for showcase scenes — keep top faces visual, push words into screen-space labels or annotations.
Glyph names (generic, stroke style): cloud, database, bolt, chart, globe, shield, lock, gear, cpu, code, layers, rocket, user, mobile, browser, search, bell, queue. Real brand logos (iso://si/<slug>): ~150 marks vendored from Simple Icons (CC0) — mysql, postgresql, redis, apachekafka, docker, kubernetes, terraform, openai, anthropic, pytorch, grafana, … with the same /light and /RRGGBB color variants. Letter badges (iso://brand/<name>) remain as fallbacks for non-vendored marks. Any other icon: value is treated as a URL / data-URI. Full browsable index with previews: ICONS.md.

I want flat / low / tall extrusion

Adjust geom.h. Conventions: For .d2 input, the height comes from d2ShapeCatalog’s multiplier × base height. Override per-shape via the YAML path if you need different heights.

I want brand colors on a specific shape

For document-wide branding, put it in theme: once and every part inherits:
See ../reference/dsl-theme.md for the full cascade.

I want to reuse one style across many parts

Define a named preset in the theme, reference it by name — no YAML anchors, works in JSON, typos get “did you mean” suggestions:
Per-part style still overrides individual preset fields. For which presets a good scene needs, read the scene design guide.

I want a gradient face / glow / shadow / texture

pattern: {kind: hatch|dots, color, spacing, angle} overlays a texture on box top faces, cylinder top ellipses, and sphere discs. Use ONE hero treatment per scene — backglow on everything reads as noise.

I want line-art / wireframe ghosts

effects.wireframe: true keeps strokes and drops every fill — pair with a dashed stroke for floating “ghost” frames. None-filled and wireframe parts are exempt from overlap warnings, so they can sit on or around solid parts freely:

I want a film-grain / print texture

effects.grain overlays monochrome noise — the editorial “print ad” register (see duckdb-handdrawn):
Works on boxes (plain + rounded) and cylinders. Keep intensity ≤ 0.5 on dark fills or the noise greys them out.

I want a screen-horizontal row (editorial layout)

In iso projection a plain rightOf row slopes down-right. To march straight across the screen, pair rightOf with behind and tune per-axis gaps so Δx = −Δy:

Canvas / backdrop

I want an iso ground grid

gridStep doubles as the layout/place CELL size — keep them equal so arranged parts and orthogonal pipes land on the grid texture.

I want dots / hatch / solid instead

I want a transparent / no backdrop

Omit canvas: entirely.

Common composite patterns

Stat card (icon + value + caption)

Region / zone container

Stacked replicas inside a worker node

Hero-anchored marketing scene

Pick the central element, give it no place (it anchors the world origin), chain every satellite off it. See samples/topology/ai-platform / clickhouse-hub / training-compute — all coordinate-free.

Validation

I want my agent’s output checked before render

JSON output is JSONPath-located with “did you mean” suggestions — apply them programmatically and re-validate. See PROMPT_TEMPLATE.md for the agent-side boilerplate.

What the validator checks

Errors (block render):
  • Unknown shape names, with “did you mean” suggestions
  • Connector from/to referencing a non-existent part id
  • Duplicate part ids; place cycles and dangling references
  • Negative dimensions or gaps; invalid anchor suffixes
Warnings (render succeeds, quality suffers): Contrast ratios use WCAG relative luminance (sRGB linearised). Only #RRGGBB / #RGB colours are evaluated; named colours and rgba(…) are skipped silently.

I want to track whether an edit improved quality (golden diff)

DiffIssues matches issues by (Path, Message) pair. Use it in an agent loop to confirm each iteration moves toward zero issues, not just changes them:

When you want behaviour we don’t have

These are the recurring asks. If you hit one: For everything else, search this file. If it’s not here and not in the references, it’s probably a missing primitive.