Interface DrawAPI
- All Known Subinterfaces:
GameAPI
Scripts use draw() and the fluent surface behind it. The methods on
this mixin are the wire primitives that facade is built from, exposed because
every other facade in this API is built the same way — not because a script is
expected to call them.
Three properties shape all of it:
- Keyed, not handled. Setting the same key again replaces rather than appends, so redrawing every tick is idempotent, and there is nothing to free.
- Connection-scoped. Keys cannot collide between clients, a clear only ever removes your own, and the producer drops everything a connection drew when its pipe closes.
- TTL is mandatory. This host always puts one on the wire, defaulting
to
DrawLimits.DEFAULT_TTL_MS.
Producer-side coupling: every method here maps to one handler in
NXTLibrary/src/rpc/Handlers.cpp. The group is additive over the RPC pipe
and does not move Layout.PROTOCOL_VERSION, which gates the shared
memory snapshot layout only.
Migrating past the highlight binding. Additive on the wire, but not on this
interface — binding the semantic highlights changed it in three ways, all of which break
a third-party implementor and none of which break a caller of
draw():
drawSet(DrawCommand.Primitive)anddrawSetBatch(List)narrowed their parameters toDrawCommand.Primitive. That narrowing is the point: it is what makes a batched highlight a compile error rather than a producer-sideunknown kind.drawHighlight(DrawCommand.Highlight)anddrawHighlights(List)are new abstract methods, so an existing implementation of this interface no longer compiles until it supplies them.MockGameAPIinbot-test-supportshows the shape: throw, since a producer-side overlay has no in-memory analogue and a mock that silently "drew" nothing is worse than one that says so.
Scripts that only call api.draw() and the fluent surface behind it are
unaffected except for DrawTarget.npc(String, Npc)'s return type —
see its javadoc.
-
Method Summary
Modifier and TypeMethodDescriptiondraw()Debug-drawing facade.intRemove the named commands (debug_draw_clear), answering how many went.intRemove everything this connection drew (debug_draw_clear_all), answering how many went.drawHighlight(DrawCommand.Highlight highlight) Set one highlight, answering the key it is stored under — one round-trip tohighlight_entity,highlight_tileorhighlight_area, chosen from the command's own variant.drawHighlights(List<DrawCommand.Highlight> highlights) Set several highlights, answering the aggregate the way a batch does.drawList()Every command this connection currently holds (debug_draw_list).drawSet(DrawCommand.Primitive command) Set one command (debug_draw_set), answering the key it is stored under.drawSetBatch(List<DrawCommand.Primitive> commands) Set many commands in one round-trip (debug_draw_set_batch).The producer's overlay counters and renderer health (debug_draw_stats).booleanWhether the producer is currently drawing at all (debug_draw_enable).booleansetDrawEnabled(boolean enabled) Switch drawing on or off (debug_draw_enable), answering the state that took effect.
-
Method Details
-
draw
Draw draw()Debug-drawing facade. Singleton perGameAPI; the entry point a script uses.Draw draw = api.draw(); draw.rect("target-box", x, y, w, h).color(Colors.GREEN).thickness(2).ttl(1200).submit(); -
drawSet
Set one command (debug_draw_set), answering the key it is stored under. One round-trip; preferDraw.frame()for more than a couple of commands in the same tick.- Throws:
RuntimeException- the transport's unchecked RPC error when the producer refuses the command — a full store, an exhausted text or polyline slot, an out-of-range coordinate, or world space
-
drawHighlight
Set one highlight, answering the key it is stored under — one round-trip tohighlight_entity,highlight_tileorhighlight_area, chosen from the command's own variant.Separate from
drawSet(DrawCommand.Primitive)because these are separate wire methods, and the parameter type isDrawCommand.Highlightrather thanDrawCommandso the two cannot be crossed: a highlight has nokindadebug_draw_setwould accept, and a primitive has nohighlight_*call that would take it.- Throws:
RuntimeException- the transport's unchecked RPC error when the producer refuses the highlight — a full store, an out-of-range tile, or an entity reference it will not take
-
drawHighlights
Set several highlights, answering the aggregate the way a batch does.This is N round-trips, not one. There is no highlight batch on the wire:
debug_draw_set_batchappliesdebug_draw_setitems, whosekindfield cannot name a semantic highlight, so one call per highlight is the only shape available. It is here as the pathDrawFrametakes, and it is named plurally rather thandrawHighlightBatchso nobody reads it as a wire primitive it is not.It reports refusals the way a batch does — counted into
DrawBatchResult.dropped()with the first message kept — rather than throwing, because that is the contract a frame's caller already has and a debug overlay must not be able to take a script's tick down. A transport failure still propagates, because a dead pipe is not the overlay failing and swallowing it would hide it. Unlike a batch, each highlight is a single store operation, so every one before a propagated failure is applied and the failing one is not — there is no half-applied call. -
drawSetBatch
Set many commands in one round-trip (debug_draw_set_batch).This call reports per-item failure as success. The producer answers a normal result carrying the number applied, the number refused and the first error string only; a batch that drew nothing still looks like a successful call at the envelope level. Read
DrawBatchResult.dropped().A list longer than
DrawLimits.MAX_BATCH_ITEMSis a hard error on the producer, not a truncation, and it loses the whole batch —DrawFramesplits rather than risk that.An exception from this call means the store is in an unknown state, not a clean one. The producer applies each item as it walks the array, so an envelope-level failure part-way through leaves everything before it already drawn, and the error reply carries no count. The two exceptions are an over-size
itemsarray, which is refused before the walk begins, and a failure that closes the pipe, after which the producer drops everything this connection drew.Draw.list()is the way to find out what is actually retained.The parameter is
List<DrawCommand.Primitive>rather thanList<DrawCommand>deliberately: aDrawCommand.Highlightcannot be applied by a batch item, so the type system refuses one here rather than the producer refusing it asunknown kindafter the round-trip.drawHighlights(List)is where those go. -
drawClear
-
drawClearAll
int drawClearAll()Remove everything this connection drew (debug_draw_clear_all), answering how many went. Deliberately never widened to the producer'sscope: "all": a script must not be able to erase another client's drawings. -
drawList
Every command this connection currently holds (debug_draw_list).The wire is paged at 128 rows, so this costs one round-trip per 128 retained commands. Note
DrawEntry.remainingTtlMs()is what is left, not what you sent. -
isDrawEnabled
boolean isDrawEnabled()Whether the producer is currently drawing at all (debug_draw_enable). -
setDrawEnabled
boolean setDrawEnabled(boolean enabled) Switch drawing on or off (debug_draw_enable), answering the state that took effect. Process-wide on the producer, not per connection. -
drawStats
DrawStats drawStats()The producer's overlay counters and renderer health (debug_draw_stats).
-