Interface DrawAPI

All Known Subinterfaces:
GameAPI

public interface DrawAPI
Debug drawing: retained overlay commands the producer renders over the client.

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():

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 Details

    • draw

      Draw draw()
      Debug-drawing facade. Singleton per GameAPI; 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

      String drawSet(DrawCommand.Primitive command)
      Set one command (debug_draw_set), answering the key it is stored under. One round-trip; prefer Draw.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

      String drawHighlight(DrawCommand.Highlight highlight)
      Set one highlight, answering the key it is stored under — one round-trip to highlight_entity, highlight_tile or highlight_area, chosen from the command's own variant.

      Separate from drawSet(DrawCommand.Primitive) because these are separate wire methods, and the parameter type is DrawCommand.Highlight rather than DrawCommand so the two cannot be crossed: a highlight has no kind a debug_draw_set would accept, and a primitive has no highlight_* 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

      DrawBatchResult drawHighlights(List<DrawCommand.Highlight> highlights)
      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_batch applies debug_draw_set items, whose kind field cannot name a semantic highlight, so one call per highlight is the only shape available. It is here as the path DrawFrame takes, and it is named plurally rather than drawHighlightBatch so 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

      DrawBatchResult drawSetBatch(List<DrawCommand.Primitive> commands)
      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_ITEMS is a hard error on the producer, not a truncation, and it loses the whole batch — DrawFrame splits 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 items array, 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 than List<DrawCommand> deliberately: a DrawCommand.Highlight cannot be applied by a batch item, so the type system refuses one here rather than the producer refusing it as unknown kind after the round-trip. drawHighlights(List) is where those go.

    • drawClear

      int drawClear(List<String> keys)
      Remove the named commands (debug_draw_clear), answering how many went.
    • drawClearAll

      int drawClearAll()
      Remove everything this connection drew (debug_draw_clear_all), answering how many went. Deliberately never widened to the producer's scope: "all": a script must not be able to erase another client's drawings.
    • drawList

      List<DrawEntry> 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).