dev:scriptref:mapper

Mapper

Generated from smudgy v0.5.4-dev (smudgy-core.d.ts @ a1c9d1939ffb, smudgy-mapper.d.ts @ 5d586b4dc546). Index: scriptref.

The map API: import { mapper } from "smudgy:core". The map types (Area, Room, …) need no import; import the Area value only for runtime instanceof checks.

For common workflows and coordinate conventions, see Work with maps.

The mapper

mapper

export const mapper: Mapper;

The current session's map API (see Mapper).

Area

export const Area: {
  readonly prototype: Area;
  [Symbol.hasInstance](value: unknown): boolean;
};

The runtime area constructor, for checks such as area instanceof Area. Areas are created by the mapper; the constructor is not a creation API.

Mapper contract

Mapper

interface Mapper {
    refreshAreas(): Promise<void>;
    createArea(name: string, options?: CreateAreaOptions): Promise<Area>;
    listAtlases(): Promise<Atlas[]>;
    createAtlas(name: string, options: CreateAtlasOptions): Promise<Atlas>;
    copyAreas(areas: (Area | AreaId)[], destination: MapDestination): Promise<Area[]>;
    moveAreas(areas: (Area | AreaId)[], destination: MapDestination): Promise<Area[]>;
    copyArea(area: Area | AreaId, destination: MapDestination): Promise<Area>;
    moveArea(area: Area | AreaId, destination: MapDestination): Promise<Area>;
    copyAtlas(atlas: Atlas | AtlasId, storage: "local" | "cloud"): Promise<Atlas>;
    moveAtlas(atlas: Atlas | AtlasId, storage: "local" | "cloud"): Promise<Atlas>;
    setCurrentLocation(areaId: AreaId, roomNumber?: RoomNumber): void;
    getCurrentLocation(): { area: AreaId; room?: RoomNumber } | undefined;
    readonly areas: Area[];
    getAreaById(id: AreaId): Area;
    mutateArea(
        area: Area | AreaId,
        callback: (mutation: AreaMutator) => void | Promise<void>,
        options?: MutateAreaOptions,
    ): Promise<OperationId[]>;
    getPathBetweenRooms(
        fromAreaId: AreaId,
        fromRoomNumber: RoomNumber,
        toAreaId: AreaId,
        toRoomNumber: RoomNumber,
    ): [AreaId, RoomNumber][];
    listRoomsByTitleAndDescription(title: string, description: string): (Room | undefined)[];
    listRoomsByTitleDescriptionAndVisibleExits(
        title: string,
        description: string,
        visibleExitDirections: string[],
    ): (Room | undefined)[];
    renameArea(area: Area | AreaId, name: string): Promise<void>;
    deleteArea(area: Area | AreaId): Promise<void>;
    setRoomTitle(area: Area | AreaId, room: Room | RoomNumber, title: string): Promise<OperationId | null>;
    setRoomDescription(area: Area | AreaId, room: Room | RoomNumber, description: string): Promise<OperationId | null>;
    setRoomColor(area: Area | AreaId, room: Room | RoomNumber, color: string): Promise<OperationId | null>;
    setRoomLevel(area: Area | AreaId, room: Room | RoomNumber, level: number): Promise<OperationId | null>;
    setRoomX(area: Area | AreaId, room: Room | RoomNumber, x: number): Promise<OperationId | null>;
    setRoomY(area: Area | AreaId, room: Room | RoomNumber, y: number): Promise<OperationId | null>;
    setRoomProperty(area: Area | AreaId, room: Room | RoomNumber, name: string, value: string): Promise<OperationId | null>;
    setAreaProperty(area: Area | AreaId, name: string, value: string): Promise<OperationId | null>;
    addRoomTag(area: Area | AreaId, room: Room | RoomNumber, tag: string): Promise<OperationId | null>;
    removeRoomTag(area: Area | AreaId, room: Room | RoomNumber, tag: string): Promise<OperationId | null>;
    findNearestRoomWithTag(from: Room, tag: string): Room | undefined;
    findNearestRoomWithTags(
        from: Room,
        filter: { all?: string[]; none?: string[] },
    ): Room | undefined;
    findNearestRoomInArea(from: Room, area: Area | AreaId): Room | undefined;
    findRoomByExternalId(externalId: string): Room | undefined;
    rescueRoomByExternalId(externalId: string): boolean;
    setRoomExternalId(area: Area | AreaId, room: Room | RoomNumber, externalId: string): Promise<OperationId | null>;
    createRoom(area: Area | AreaId, params: CreateRoomParams): Promise<RoomNumber>;
    updateRoom(area: Area | AreaId, room: Room | RoomNumber, fields: UpdateRoomParams): Promise<OperationId | null>;
    updateRooms(area: Area | AreaId, updates: [RoomNumber, UpdateRoomParams][]): Promise<OperationId[]>;
    createRoomExit(area: Area | AreaId, room: Room | RoomNumber, exit: ExitArgs): Promise<ExitId>;
    setRoomExit(area: Area | AreaId, room: Room | RoomNumber, exitId: ExitId, exit: ExitUpdates): Promise<OperationId | null>;
    mergeRooms(area: Area | AreaId, keep: Room | RoomNumber, remove: Room | RoomNumber): Promise<OperationId | null>;
    deleteRoom(area: Area | AreaId, room: Room | RoomNumber): Promise<OperationId | null>;
    deleteRoomExit(area: Area | AreaId, room: Room | RoomNumber, exitId: ExitId): Promise<OperationId | null>;
    createLink(area: Area | AreaId, link: LinkCreateArgs): Promise<ConnectionId>;
    setConnection(area: Area | AreaId, connectionId: ConnectionId, updates: ConnectionUpdates): Promise<OperationId | null>;
    unlinkRoomExit(area: Area | AreaId, exitId: ExitId): Promise<ConnectionId>;
    pairConnections(area: Area | AreaId, keepConnectionId: ConnectionId, mergeConnectionId: ConnectionId): Promise<OperationId | null>;
    deleteLink(area: Area | AreaId, connectionId: ConnectionId): Promise<OperationId | null>;
    createLabel(area: Area | AreaId, label: LabelArgs): Promise<LabelId>;
    createShape(area: Area | AreaId, shape: ShapeArgs): Promise<ShapeId>;
    deleteLabel(area: Area | AreaId, labelId: LabelId): Promise<OperationId | null>;
    deleteShape(area: Area | AreaId, shapeId: ShapeId): Promise<OperationId | null>;
    setLabel(area: Area | AreaId, labelId: LabelId, updates: LabelUpdates): Promise<OperationId | null>;
    setShape(area: Area | AreaId, shapeId: ShapeId, updates: ShapeUpdates): Promise<OperationId | null>;
    exportArea(area: Area | AreaId): Promise<AreaJson>;
    importAreas(areas: AreaJson[]): Promise<AreaId[]>;
    importArea(area: AreaJson): Promise<AreaId>;
    importAreasIfAbsent(areas: AreaJson[]): Promise<AreasImportedIfAbsent>;
}

The map API for the current session. Each session has its own current location; changes to persistent areas sync to the cloud in the background.

  • refreshAreas — Refresh every visible area from durable storage. Package entry points should await this before a presence-based upsert that can run during startup or after mapping ownership moves between sessions.
  • createArea — Create a new area and return its handle. Without an explicit storage (or an atlas to inherit a tier from), the area is durable in the default tier: cloud when signed in, local otherwise.
  • listAtlases — List local and cloud atlases.
  • createAtlas — Create a durable atlas in an explicit storage tier.
  • copyAreas — Copy areas together, preserving links between members of the set.
  • moveAreas — Move areas together. Cross-tier moves copy completely before deleting sources.
  • copyAtlas — Copy an atlas and all of its areas to another durable storage tier.
  • moveAtlas — Move an atlas and all of its areas to another durable storage tier.
  • setCurrentLocation — Set the current map location (the per-session “you are here” marker).
  • getCurrentLocation — The current map location, or undefined if none is set. room is absent when the location names an area without a specific room.
  • areas — All active areas (areas marked inactive are excluded).
  • mutateArea — Collect related writes to one area and submit them in the fewest practical ordered envelopes. The whole callback is validated and durably staged before anything is published, so a locally invalid batch submits nothing, even when oversized work is split into several envelopes. Each envelope is atomic at the backend; acknowledged envelopes are never rolled back, so if a later envelope fails after earlier ones were accepted, the thrown Error carries the acknowledged prefix on its committedOperations property (an OperationId[]). If the callback throws, nothing is submitted.
  • getPathBetweenRooms — The cheapest route between two rooms, as a list of [areaId, roomNumber] steps (each exit's weight is its cost).
  • renameArea — Rename an area after the backend acknowledges the change.
  • deleteArea — Delete an area and everything in it.
  • setRoomColor — Set a room's color to a CSS color string.
  • setRoomProperty — Set a custom room property (string key/value).
  • setAreaProperty — Set a custom area property (string key/value); the write counterpart of area.data(key). Pass an empty value to clear it.
  • addRoomTag — Add a case-insensitive tag to a room (normalized to UPPERCASE; re-adding is a no-op).
  • removeRoomTag — Remove a tag from a room (case-insensitive).
  • findNearestRoomWithTag — The nearest reachable room carrying tag (case-insensitive) from from, by the same weighted search as getPathBetweenRooms (the start room counts if it carries the tag), or undefined if none is reachable. Path to it with getPathBetweenRooms.
  • findNearestRoomWithTags — The nearest reachable room that carries every tag in all and none of the tags in none (all case-insensitive); undefined if no such room is reachable or the filter is empty. Used by multi-tag speedwalks like \inn.peace and \!peace.guild.
  • findNearestRoomInArea — The nearest reachable room belonging to area from from, by the same weighted search as getPathBetweenRooms (from itself counts if it is already in the area, and naming the area reaches it even when it is marked inactive), or undefined if no room of the area is reachable. Path to it with getPathBetweenRooms.
  • findRoomByExternalId — The room bound to a server-global room id (the room number games send over GMCP or MSDP), or undefined if no loaded room carries it. When the same id is bound in more than one area, one match is returned (rooms in your own maps win over shared ones).
  • rescueRoomByExternalId — Reports whether a room with this server-global id is already mapped for a different server. When it is, the player is offered the chance to show that map here too, and this returns true, so a map drawn as you explore knows the room is accounted for and need not be recreated. Returns false when the id belongs to no other server's map.
  • setRoomExternalId — Bind (or, with an empty string, clear) a room's server-global room id.
  • createRoom — Create a room and return its new room number. The write is a must-not-exist create: if the allocated number is taken by the time the write lands (another client raced it in), it rejects with room_number_exists instead of silently merging into that room.
  • updateRoom — Update multiple fields of a room in one cache update; only present fields change.
  • updateRooms — Batch-update many rooms of one area in a single cache update.
  • createRoomExit — Create an exit on a room and return its new id.
  • setRoomExit — Update an existing exit. Resolves after backend acknowledgement; equal updates resolve to null without sending a mutation.
  • mergeRooms — Merge remove into keep in one durable mutation. The kept room's metadata wins; traversal is deduplicated and rewired. Resolves after backend acknowledgement.
  • deleteRoom — Delete a room.
  • deleteRoomExit — Delete an exit from a room.
  • createLink — Atomically create one Connection and its one or two traversals.
  • setConnection — Update shared Connection geometry or appearance.
  • unlinkRoomExit — Split one traversal out of a bidirectional Connection.
  • pairConnections — Merge reciprocal one-way Connections, preserving the first one's route.
  • deleteLink — Delete a Connection and every member traversal.
  • createLabel — Add a text label to an area and return its new id.
  • createShape — Add a graphical shape to an area and return its new id.
  • deleteLabel — Delete a label from an area.
  • deleteShape — Delete a shape from an area.
  • setLabel — Update an existing label; only present fields change.
  • setShape — Update an existing shape; only present fields change.
  • exportArea — Export an area as a portable AreaJson. Requires copy rights on the area.
  • importAreas — Import exported areas as new local areas (fresh ids). Exits between areas in the set are relinked to the new copies; exits pointing outside the set are kept but left unlinked. Returns the new area ids. Prefer this one-call form for multi-area imports.
  • importArea — Import one exported area as a new local area; returns its id.
  • importAreasIfAbsent — Import exported areas, skipping any whose name is already resident in the mapper. Shared maps, deactivated maps, and maps assigned to other server entries count too. Waits for the session's maps to finish loading first, so it is safe to call as a package starts, on every start, without creating duplicates. Returns the ids of the areas imported and the names skipped.

Atlases & storage

Atlas

interface Atlas {
    readonly id: AtlasId;
    readonly name: string;
    readonly storage: MapStorage;
    toString(): string;
}

An atlas (map folder). Session storage does not support atlases.

  • storage — The atlas's live tier. Moving an atlas creates a new id and invalidates the source handle; use the Atlas returned by moveAtlas afterward.

AtlasId

type AtlasId = readonly [number, number];

An atlas (map folder) identifier, opaque like AreaId.

CreateAtlasOptions

interface CreateAtlasOptions {
    storage: "local" | "cloud";
}

MapStorage

type MapStorage = "session" | "local" | "cloud";

Where a map is stored. Session maps disappear when the session closes.

MapDestination

interface MapDestination {
    storage: MapStorage;
    atlas?: Atlas | AtlasId;
}

A destination used by map copy and move operations.

  • atlas — Omit to leave the area loose (outside an atlas).

AreaMutator

interface AreaMutator {
    createRoom(params: CreateRoomParams): Promise<RoomNumber>;
    updateRoom(room: Room | RoomNumber, fields: UpdateRoomParams): Promise<void>;
    updateRooms(updates: [RoomNumber, UpdateRoomParams][]): Promise<void>;
    setRoomTitle(room: Room | RoomNumber, title: string): Promise<void>;
    setRoomDescription(room: Room | RoomNumber, description: string): Promise<void>;
    setRoomColor(room: Room | RoomNumber, color: string): Promise<void>;
    setRoomLevel(room: Room | RoomNumber, level: number): Promise<void>;
    setRoomX(room: Room | RoomNumber, x: number): Promise<void>;
    setRoomY(room: Room | RoomNumber, y: number): Promise<void>;
    setRoomExternalId(room: Room | RoomNumber, externalId: string): Promise<void>;
    setRoomProperty(room: Room | RoomNumber, name: string, value: string): Promise<void>;
    setAreaProperty(name: string, value: string): Promise<void>;
    addRoomTag(room: Room | RoomNumber, tag: string): Promise<void>;
    removeRoomTag(room: Room | RoomNumber, tag: string): Promise<void>;
    createRoomExit(room: Room | RoomNumber, exit: ExitArgs): Promise<ExitId>;
    setRoomExit(room: Room | RoomNumber, exitId: ExitId, exit: ExitUpdates): Promise<void>;
    deleteRoom(room: Room | RoomNumber): Promise<void>;
    deleteRoomExit(room: Room | RoomNumber, exitId: ExitId): Promise<void>;
    createLink(link: LinkCreateArgs): Promise<ConnectionId>;
    setConnection(connectionId: ConnectionId, updates: ConnectionUpdates): Promise<void>;
}

Callback-scoped collector used by Mapper.mutateArea. Calls update a callback-local draft and are submitted only after the callback completes.

  • createRoom — Draft a room under a number reserved from the live allocator: ambient creators in this client (mapper.createRoom, the map editor, other open mutators) skip reserved numbers, so a create landing while the callback is open cannot collide with the draft. The number is provisional (the room exists only once the mutation commits), and the reservation is released when the callback finishes or aborts, so an aborted draft's numbers become available again. The draft submits as a must-not-exist create: if the number is taken by submission time (another client raced it in), the mutation is rejected (mutateArea throws with room_number_exists in the message) rather than silently merging two logical rooms.

MutateAreaOptions

interface MutateAreaOptions {
    description?: string;
}
  • description — Description shown by save/conflict diagnostics.

OperationId

type OperationId = readonly [number, number];

A queued mapper mutation's identifier, opaque like ExitId.

Areas & rooms

Area

interface Area {
    readonly id: AreaId;
    readonly uuid: string;
    readonly name: string;
    readonly room_numbers: RoomNumber[];
    readonly isEphemeral: boolean;
    readonly storage: MapStorage;
    readonly next_room_number: RoomNumber;
    room(roomNumber: number): Room | undefined;
    data(key: string): string | undefined;
    readonly labels: Label[];
    readonly shapes: Shape[];
    readonly connections: Connection[];
    toString(): string;
}

A map area. You get areas from the mapper (mapper.areas, mapper.getAreaById), never by constructing one. For a runtime check, import the constructor: import { Area } from "smudgy:core".

  • uuid — The area id as its canonical hyphenated lowercase UUID string: the JSON-safe spelling of id, as carried by the map:room event's areaId field and accepted by MapView apply-area scoping.
  • isEphemeral — Whether this is a session map: it lives only for this session and is discarded when the session closes.
  • storage — The area's actual storage tier.
  • next_room_number — The next unused room number in this area.
  • room — The room with this number, or undefined.
  • data — Read a custom area property by key (or undefined if unset).
  • labels — This area's text labels.
  • shapes — This area's graphical shapes.
  • connections — This area's shared link geometry and appearance records.

Room

interface Room {
    readonly room_number: RoomNumber;
    readonly area_id: AreaId;
    readonly title: string;
    readonly externalId: string | undefined;
    readonly description: string;
    readonly level: number;
    readonly x: number;
    readonly y: number;
    readonly color: string;
    readonly exits: Exit[];
    data(key: string): string | undefined;
    readonly tags: string[];
    hasTag(tag: string): boolean;
    update(fields: UpdateRoomParams): Promise<OperationId | null>;
    toString(): string;
}

A room read from the map. Obtain one via area.room(n) or the listRooms* helpers.

  • externalId — The server's own id for this room (the room number games send over GMCP or MSDP), or undefined if none is bound. Bind one at creation (externalId in the room fields) or with mapper.setRoomExternalId.
  • color — A CSS color string.
  • data — Read a custom room property by key (or undefined if unset).
  • tags — This room's tags, normalized to UPPERCASE and sorted.
  • hasTag — Whether this room carries tag (case-insensitive).
  • update — Update multiple fields of this room in one cache update; only present fields change.

Exit

interface Exit {
    readonly id: ExitId;
    readonly from_direction: ExitDirection;
    readonly from_area_id: AreaId;
    readonly from_room_number: RoomNumber;
    readonly to_direction: ExitDirection | null;
    readonly to_area_id: AreaId | null;
    readonly to_room_number: RoomNumber | null;
    readonly is_hidden: boolean;
    readonly is_closed: boolean;
    readonly is_locked: boolean;
    readonly weight: number;
    readonly command: string | null;
}

One exit read back from a room (room.exits). Optional links are present but null when unset (not omitted).

  • weight — Pathfinding cost.
  • command — The command sent to traverse this exit, or null to use from_direction.

CreateAreaOptions

interface CreateAreaOptions {
    storage?: MapStorage;
    atlas?: Atlas | AtlasId;
    ephemeral?: boolean;
}

Options for Mapper.createArea.

  • storage — The authoritative storage tier. When omitted, the area is durable in the default tier: cloud when signed in, local otherwise (or the atlas's tier when atlas is given).
  • atlas — Optionally create the area inside this atlas. The atlas determines the storage tier when storage is omitted; when both are given they must match.
  • ephemeral — Create a session map: it lives only for this session, is never saved or synced, and is discarded when the session closes. Mutually exclusive with storage, which wins if both are supplied.

CreateRoomParams

interface CreateRoomParams {
    title?: string;
    description?: string;
    level?: number;
    x?: number;
    y?: number;
    color?: string;
    externalId?: string;
}

Fields accepted when creating a room (mapper.createRoom). Any omitted field takes its default.

  • level — Map level / z-layer.
  • color — A CSS color string.
  • externalId — The server's own id for this room (the room number games send over GMCP or MSDP). An empty string clears an existing binding.

UpdateRoomParams

type UpdateRoomParams = CreateRoomParams;

Fields accepted when updating a room (mapper.updateRoom/Room.update): the same set as creation. Any omitted field is left unchanged.

ExitArgs

interface ExitArgs {
    from_direction: ExitDirection;
    to_direction?: ExitDirection;
    to_area_id?: AreaId;
    to_room_number?: RoomNumber;
    is_hidden?: boolean;
    is_closed?: boolean;
    is_locked?: boolean;
    weight?: number;
    command?: string;
}

Fields accepted when creating an exit (mapper.createRoomExit). Only from_direction is required. Visual appearance (routing, dash, color, thickness) lives on the shared Connection, not the exit.

ExitUpdates

interface ExitUpdates {
    from_direction?: ExitDirection;
    to_direction?: ExitDirection;
    to_area_id?: AreaId;
    to_room_number?: RoomNumber;
    is_hidden?: boolean;
    is_closed?: boolean;
    is_locked?: boolean;
    weight?: number;
    command?: string;
}

Fields accepted when updating an exit (mapper.setRoomExit). Any omitted field is left unchanged.

AreaJson

type AreaJson = Record<string, unknown>;

A portable area export, produced by Mapper.exportArea and consumed by Mapper.importArea/Mapper.importAreas. Treat it as opaque: export it, store it, import it back, but do not depend on its internal shape.

AreasImportedIfAbsent

interface AreasImportedIfAbsent {
    readonly added: AreaId[];
    readonly skipped: string[];
}

The outcome of Mapper.importAreasIfAbsent.

  • added — Ids of the areas imported by this call.
  • skipped — Names skipped because a resident map already has that name.

Connections

Connection

interface Connection {
    readonly id: ConnectionId;
    readonly endpoint_a: ConnectionEndpoint;
    readonly endpoint_b: ConnectionEndpoint | null;
    readonly kind: ConnectionKind;
    readonly routing: ConnectionRouting;
    readonly segment_shape: ConnectionSegmentShape;
    readonly corner: ConnectionCorner;
    readonly route_points: MapPoint[];
    readonly dash: ConnectionDash;
    readonly color: string;
    readonly thickness: number;
}

Shared topology, route, and appearance for one or two member Exits.

ConnectionEndpoint

interface ConnectionEndpoint {
    room_number: RoomNumber;
    side: RoomSide;
    port_offset: number;
    port_mode: PortMode;
}

A Connection's wall attachment on one room.

  • port_offset — Normalized position along the room wall, from 0 through 1.

MapPoint

interface MapPoint {
    x: number;
    y: number;
}

One interior Connection centerline vertex in area coordinates.

ConnectionUpdates

interface ConnectionUpdates {
    endpoint_a?: ConnectionEndpoint;
    endpoint_b?: ConnectionEndpoint;
    routing?: ConnectionRouting;
    segment_shape?: ConnectionSegmentShape;
    corner?: ConnectionCorner;
    route_points?: MapPoint[];
    dash?: ConnectionDash;
    color?: string;
    thickness?: number;
}

Geometry/appearance fields accepted by Mapper.setConnection.

LinkTraversalArgs

interface LinkTraversalArgs extends ExitArgs {
    room_number: RoomNumber;
}

One directed Exit to create as a member of a new Connection.

  • room_number — Room that owns this traversal.

LinkCreateArgs

interface LinkCreateArgs extends ConnectionUpdates {
    endpoint_a: ConnectionEndpoint;
    endpoint_b?: ConnectionEndpoint;
    traversals: LinkTraversalArgs[];
}

One atomic link creation: Connection first, followed by one or two traversals.

Labels & shapes

Label

interface Label {
    readonly id: LabelId;
    readonly level: number;
    readonly x: number;
    readonly y: number;
    readonly width: number;
    readonly height: number;
    readonly horizontal_alignment: LabelHorizontalAlign;
    readonly vertical_alignment: LabelVerticalAlign;
    readonly text: string;
    readonly color: string;
    readonly background_color: string;
    readonly font_size: number;
    readonly font_weight: number;
}

A text label read back from an area (area.labels).

  • level — Map level / z-layer.
  • color — A CSS color string.
  • background_color — A CSS color string for the background ("" for none).

LabelArgs

interface LabelArgs {
    x: number;
    y: number;
    width: number;
    height: number;
    text: string;
    level?: number;
    horizontal_alignment?: LabelHorizontalAlign;
    vertical_alignment?: LabelVerticalAlign;
    color?: string;
    background_color?: string;
    font_size?: number;
    font_weight?: number;
}

Fields accepted when creating a label (mapper.createLabel). Position, size, and text are required; any omitted field takes its default.

  • level — Map level / z-layer (default 0).
  • horizontal_alignment — Text alignment (defaults: Center / Center).
  • color — A CSS color string for the text (default "#ffffff").
  • background_color — A CSS color string for the background; omit for none.
  • font_size — Text size in px (default 16).
  • font_weight — Text weight (default 400).

LabelUpdates

interface LabelUpdates {
    x?: number;
    y?: number;
    width?: number;
    height?: number;
    text?: string;
    level?: number;
    horizontal_alignment?: LabelHorizontalAlign;
    vertical_alignment?: LabelVerticalAlign;
    color?: string;
    background_color?: string;
    font_size?: number;
    font_weight?: number;
}

Fields accepted when updating a label (mapper.setLabel). Any omitted field is left unchanged.

  • level — Map level / z-layer.
  • color — A CSS color string for the text.
  • background_color — A CSS color string for the background.

Shape

interface Shape {
    readonly id: ShapeId;
    readonly level: number;
    readonly x: number;
    readonly y: number;
    readonly width: number;
    readonly height: number;
    readonly background_color: string | null;
    readonly stroke_color: string | null;
    readonly shape_type: ShapeKind;
    readonly border_radius: number;
    readonly stroke_width: number;
}

A graphical shape read back from an area (area.shapes).

  • level — Map level / z-layer.
  • background_color — A CSS color string, or null for none.
  • stroke_color — A CSS color string, or null for none.

ShapeArgs

interface ShapeArgs {
    x: number;
    y: number;
    width: number;
    height: number;
    level?: number;
    background_color?: string;
    stroke_color?: string;
    shape_type?: ShapeKind;
    border_radius?: number;
    stroke_width?: number;
}

Fields accepted when creating a shape (mapper.createShape). Position and size are required; any omitted field takes its default.

  • level — Map level / z-layer (default 0).
  • background_color — A CSS fill color; omit for none.
  • stroke_color — A CSS stroke color; omit for none.
  • shape_type — Shape kind (default "Rectangle").
  • border_radius — Corner radius (default 0).
  • stroke_width — Stroke width in px.

ShapeUpdates

interface ShapeUpdates {
    x?: number;
    y?: number;
    width?: number;
    height?: number;
    level?: number;
    background_color?: string;
    stroke_color?: string;
    shape_type?: ShapeKind;
    border_radius?: number;
    stroke_width?: number;
}

Fields accepted when updating a shape (mapper.setShape). Any omitted field is left unchanged.

  • level — Map level / z-layer.
  • background_color — A CSS fill color.
  • stroke_color — A CSS stroke color.

Identifiers & enums

AreaId

type AreaId = readonly [number, number];

An area's identifier. Treat it as opaque: take it from one mapper call and pass it back to another, unchanged. Careful: this is not the same as the UUID string the map:room event delivers; mapper calls accept only the pair. Real ids carry BigInt halves (see ConnectionId), which JSON.stringify rejects — so mapper-issued ids cannot travel session-store writes or store bindings. Where an area scope must ride JSON — store-bound MapView apply arrays — use the UUID string spelling instead: MapStyleApplication.area in smudgy:widgets accepts either form.

RoomNumber

type RoomNumber = number;

A room number within an area (a 32-bit integer).

ExitId

type ExitId = readonly [number, number];

An exit's identifier: a 2-element [hi, lo] pair, like AreaId. Opaque.

ConnectionId

type ConnectionId = readonly [number, number];

A Connection's identifier, opaque like ExitId.

Careful: the [hi, lo] halves are 64-bit UUID halves. Values beyond Number.MAX_SAFE_INTEGER (essentially always for real ids) are delivered as BigInt, so despite this type's spelling the halves are bigint at runtime. JSON.stringify throws on BigInt, which means these ids cannot travel session-store writes or store bindings, and coercing a half with Number() rounds it and will silently never match. Pass ids straight back to mapper calls; for widget-facing selection use room + direction exit refs instead (see MapExitRef in smudgy:widgets).

LabelId

type LabelId = readonly [number, number];

A label's identifier: a 2-element [hi, lo] UUID pair, like AreaId. Opaque.

ShapeId

type ShapeId = readonly [number, number];

A shape's identifier: a 2-element [hi, lo] UUID pair, like AreaId. Opaque.

ExitDirection

type ExitDirection =
| "North"
| "East"
| "South"
| "West"
| "Up"
| "Down"
| "Northeast"
| "Northwest"
| "Southeast"
| "Southwest"
| "In"
| "Out"
| "Special"
| "Other";

A compass/special exit direction (the canonical PascalCase names).

RoomSide

type RoomSide = "North" | "East" | "South" | "West";

One of the four walls where a Connection attaches to a room.

PortMode

type PortMode = "AutoPinned" | "Manual";

Whether a port follows automatic wall redistribution or keeps an author-selected offset.

ConnectionKind

type ConnectionKind = "Internal" | "SelfLoop" | "Dangling" | "External" | "CrossLevel";

The topology represented by a Connection.

ConnectionRouting

type ConnectionRouting = "Stub" | "Simple" | "Manual" | "Automatic";

How a Connection's centerline is produced and stored.

ConnectionSegmentShape

type ConnectionSegmentShape = "Direct" | "Orthogonal";

Whether routed segments may be diagonal or must remain axis-aligned.

ConnectionCorner

type ConnectionCorner = "Sharp" | "Rounded";

How turns between Connection segments are drawn.

ConnectionDash

type ConnectionDash = "Solid" | "Dashed" | "Dotted";

The repeating stroke pattern used to draw a Connection.

LabelHorizontalAlign

type LabelHorizontalAlign = "Left" | "Center" | "Right";

Horizontal alignment of a label's text.

LabelVerticalAlign

type LabelVerticalAlign = "Top" | "Center" | "Bottom";

Vertical alignment of a label's text.

ShapeKind

type ShapeKind = "Rectangle" | "RoundedRectangle";

A shape's kind.


Script API reference · ← smudgy:widgets — Canvas · smudgy:params → · Scripting manual