Skip to content

draw()

Put a shape on the map — a spell zone, a blast template, a wall.

Part of the Action API · Function reference

Signature

draw(args: DrawArgs): Promise<string>

Asynchronous. Resolves with the id of the shape it created.

draw is not always defined. It exists only when the action runs against a map that can accept drawings. Check before calling:

if (typeof draw === 'function') {
  await draw({ area, text: 'Wall of Fire' });
}

Parameters

draw() takes a single options object. Give it either an area or a shape.

Drawing a targeted area

Field Type Description
area TargetedArea | null The area the player placed with the targeting reticle, available in scope as area. Supplies shape, position, and size.

When area is present, shape, origin, and size are ignored — the drawing is exactly the region the player aimed at, which is the point. Circle, rectangle, cone, and line areas can be drawn; a wall or path area throws.

Drawing a shape yourself

Field Type Default Description
shape 'circle' | 'square' | 'rectangle' | 'cone' | 'line' | 'wall' — Required when there is no area.
origin { x?, y? } { x: 0, y: 0 } Offset from the token's position.
size number 100 Radius for circle and cone; side length for square; both dimensions for rectangle.
width number size Rectangle width.
height number size Rectangle height.
angle number 0 Cone facing in degrees. 0 points right, 90 points down.
arcAngle number 60 Cone arc width in degrees.
points Array<{x, y}> — Required for line and wall; at least two vertices, each an offset from the token plus origin.

Walls

Only meaningful with shape: 'wall', which is stored as a vision-blocking shape rather than a drawing.

Field Type Default Description
blockingMode 'both' | 'vision' | 'movement' 'both' What the wall stops.
blocksVision boolean true false gives concealment rather than a hard block.
wallHeight number none Height in feet, used by shadow casting.

Lifetime, labels, and style

Field Type Default Description
duration number 0 Rounds to persist. 0 or omitted is permanent.
text string | null null A label drawn on the shape.
metadata string null Tooltip text shown when someone hovers the shape.
baseColor string | null null One colour to derive the whole palette from — see Colour.
fillColor string | null #ff00004d Explicit fill. Overrides baseColor.
strokeColor string | null #ff0000 Explicit outline. Overrides baseColor.
strokeWidth number 2 Outline thickness in pixels.
opacity number 1 Opacity of the whole shape.

Returns

Promise<string> — the id of the created drawing or wall. Keep it if you want to remove the shape later through another mechanism; draw() itself has no delete counterpart.

Colour

Pass baseColor and the house style is derived from it: the fill is that colour at 40% opacity, the outline is the same hue halfway to black at 20px, and any text label matches the outline. That is how a module tints a zone by school or category and still gets a consistent look.

await draw({ area, baseColor: '#c92a2a', text: 'Fireball' });

Colours must be hex. The map's renderer reads #RGB, #RRGGBB, and #RRGGBBAA — and only those. An rgba(255, 0, 0, 0.3) fill renders fully opaque, hiding the tokens standing in the zone. Write the alpha as the last two hex digits instead: #ff00004d.

Expiry

With duration set, the shape is removed once the initiative round counter reaches the current round plus duration. Rounds, not turns, and it needs initiative to actually be running — outside combat the counter never advances and the shape stays.

Examples

Leave a zone where the player aimed

if (area && typeof draw === 'function') {
  await draw({
    area,
    baseColor: '#e8590c',
    text: 'Wall of Fire',
    metadata: '2d6 fire damage on entry',
    duration: 10,
  });
}

A burst centred on the caster

await draw({
  shape: 'circle',
  size: 300,
  baseColor: '#1971c2',
  text: 'Aura of Cold',
  duration: 3,
});

A cone

await draw({ shape: 'cone', size: 350, angle: 90, arcAngle: 60, baseColor: '#2f9e44' });

A temporary barricade

await draw({
  shape: 'wall',
  points: [{ x: -150, y: 0 }, { x: 150, y: 0 }],
  blockingMode: 'both',
  duration: 5,
});

Errors

draw() throws — which surfaces as a red error in chat — when:

  • neither shape nor area is given
  • shape is not one of the six supported values
  • shape: 'line' or 'wall' is given fewer than two points
  • shape: 'wall' is used where the host cannot create vision-blocking shapes
  • area.type is 'wall' or 'path', neither of which can become a drawing

Notes and gotchas

  • Known issue: manual placement is off. origin and points are added to the token's stored grid coordinates but drawn in pixels, so a shape positioned this way lands near the map's top-left corner rather than on the token. draw({ area }) converts correctly and is the reliable path today.
  • draw() really draws in the Test panel. Only chat is captured there; the shape is created on the map for everyone.
  • metadata is hover-only. A zone nobody can identify without mousing over it is a coloured blob during someone else's turn — use text for anything that matters at a glance.
  • await it if you need the id or want later steps to run after the shape exists.

See also