Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

World drawing helpers

mod-api is the Rust SDK for personal mods. drawing::api exposes the generated cinnabar:world-draw/drawing WIT interface. drawing::shapes builds its geometry records directly, without another geometry schema or graphics dependency.

The builders return a list of independent local-coordinate polylines:

HelperGeometry
box_wireframeTwelve independent edges from minimum and maximum bounds
entity_bounding_boxThe same twelve edges from caller-supplied authorized bounds
circleOne closed XZ ring, starting at +X towards +Z
sphere_wireframeThree closed great circles in XZ, XY and YZ order
arrowA shaft and two independent head wings
polylineAn open path or closed line, preserving repeated points
path_gradientAn open path with linear RGBA interpolated by distance
gridAn XZ grid including its boundary, with caller-selected subdivisions
chunk_borderTwelve edges from caller-supplied local chunk bounds

Closed rings use the contract’s closed flag without repeating the first vertex. The host computes cumulative line distances. UV and custom attributes default to zero. Line width, joins and caps belong to each instance. Builders reject invalid dimensions, non-finite values, out-of-range colors and shapes that exceed an empty owner’s geometry or callback budget. Limits come from mod-api; host validation also accounts for the owner’s other resources and instance transforms. Uploading each geometry uses one import. Other drawing and render imports in the same callback share that allowance.

For example, these statements can run during an authorized mod callback:

#![allow(unused)]
fn main() {
use mod_api::drawing::{api, instance, shapes};

let shape = shapes::circle(2.0, 32, [0.2, 0.6, 1.0, 1.0]).expect("valid circle");
let geometry = api::create_geometry(&shape[0]).expect("drawing geometry admitted");
let mut draw = instance(geometry, api::Anchor::World(api::WorldAnchor {
    dimension: 0,
    origin: (0.0, 64.0, 0.0),
}));
draw.width = 2.0;
draw.width_mode = api::WidthMode::Pixels;
let drawing = api::create(&draw).expect("drawing instance admitted");
}

Retain both handles in the mod’s state and update the instance to move it, without rebuilding geometry. Remove instances before their geometry. For callback-only output, pass instances referencing retained geometry to api::replace_frame_group. Groups expire on the next successful callback; explicit instances persist until removed or revoked. The example traps on an admission failure so the host rolls back the whole callback. Returning normally after a handled error still commits earlier successful calls.

instance defaults to depth testing, premultiplied blending, white tint, identity placement, world-unit width, bevel joins and butt caps. Helpers do not query entities or blocks and do not grant observation, entity attachment or through-wall drawing. Check api::capabilities and handle host errors. Availability of renderer and anchor support is separate from building a geometry record.

The existing render::draw, render::draw_lines and position-box APIs remain available with their existing output and callback lifetime. Their compatibility paths currently remain in place:

Existing primitiveRequired behavior beyond the retained unlit contract
draw_linesExisting feathered coverage, dash/dot phase and pixel expansion
DecalsGround lift and procedural, animated coverage
RibbonsTaper, head-to-tail fade and emissive coverage
BeamsAnimated core, halo and intensity
BillboardsCamera-facing/upright placement and procedural patterns
Position boxesTranslucent faces plus the existing feathered edge coverage

These paths must keep their compatibility implementation until retained presets can preserve that output. A wireframe bounding box is a new shape convenience; it does not replace the translucent position-box primitive.

Experience client parts continue to use experience-sdk and their separate server-experience capability interfaces. The current drawing helpers target the personal-mod Rust/WIT interface. A future TypeScript author package should generate records, operations, limits and feature detection from the same contract after component packaging is available. No TypeScript bridge is supplied here.

Player HUD consumers can use player-state.read-revisions to observe equipment and effects independently. Import only changed families with read-equipment and read-effects; effect ticks do not invalidate equipment. The records retain session/dimension authority and the existing player-state read budget. The original read-snapshot and read-revision APIs retain their exact-content semantics.