Skip to main content

Entities and Interactions

Purpose

This report maps DreamBot entity lookup and boolean interaction calls to current n3Plugins query and action owners. The full development plan owns module scope and delivery order.

New AIO code must keep three concerns separate:

  1. Query current client state through com.n3plugins.sdk.query.*.
  2. Dispatch through com.n3plugins.Api.actions.*.
  3. Advance the workflow after a later event or state observation proves the domain postcondition.

The legacy Api.actions facade has been removed. Use Api.actions.* for writes; several older entity methods returned boolean; they do not expose pacing, readiness, target, mapping, or dispatch status. New AIO workflows must use the result-aware action classes.

Entity mapping

DreamBot typeRuneLite/n3 typeQuery ownerResult-aware action owner
GameObjectTileObjectTileObjects / TileObjectQueryObjectActions
NPCNPCNPCs / NPCQueryNPCActions
GroundItemETileItemTileItems / TileItemQueryGroundItemActions
WidgetChildWidgetWidgets and domain widget APIsWidgetActions or a domain action owner
PlayerPlayerPlayersPlayerActions

Do not cache live entity or widget objects across ticks. Rebuild the query near the interaction and retain stable data such as an item ID, NPC name, object ID, or WorldPoint when the workflow needs continuity.

Query translation

DreamBot code often selects the first or Euclidean-nearest object:

GameObject tree = GameObjects.closest(object ->
"Oak".equals(object.getName()) && area.contains(object));

The current n3 query uses withinArea, local reachability filtering, and path-aware selection:

Optional<TileObject> tree = TileObjects.search()
.withName("Oak")
.withinArea(area)
.walkable()
.nearestByPath();

Use .walkable() for a current-scene reachability filter. Use .nearestByPath() when path cost should choose among the retained candidates. Neither result proves that a later interaction will remain reachable after the query returns.

QueryResults.nearestTo(...) and sortedByDistanceTo(...) use straight-line WorldPoint distance. They do not perform reachability or line-of-sight checks.

Interaction translation

DreamBot combines target dispatch and a blocking wait:

if (npc.interact("Attack")) {
Sleep.sleepUntil(() -> Players.getLocal().isInCombat(), 3000);
}

An n3 state handler dispatches once and moves to a verification state:

InteractionResult result = NPCActions.interact(npc, "Attack");
if (result.getStatus() == InteractionStatus.PACED
|| result.getStatus() == InteractionStatus.MOVEMENT_IN_PROGRESS) {
return CarouselResult.stay("attack_wait", result.getMessage());
}
if (result.accepted()) {
return CarouselResult.transitionTo(
State.WAITING_FOR_COMBAT,
"attack_dispatched",
result.getMessage());
}
return CarouselResult.fail("attack_failed", result.getMessage());

The WAITING_FOR_COMBAT state must observe combat entry, an interaction target, a combat animation, a hit, or another module-specific postcondition. DISPATCHED proves submission. CONFIRMED requires an observed postcondition. SUCCESS remains a legacy status whose confirmation level is unspecified.

Postcondition ownership

Each module must name the observation that advances its state.

ActionMinimum useful observation
Chop or mineLocal-player animation, XP gain, inventory delta, or resource-object change tied to the target.
FishFishing animation, catch inventory delta, XP gain, or fishing-spot state change.
AttackActor interaction/combat state, combat animation, hitsplat/health change, target death, or disengagement.
Take ground itemInventory quantity increase or target ground item disappearance.
Use item on item/object/NPCSelected-widget state followed by the expected inventory, interface, animation, or var change.
Open, pass, or climbPosition, plane, region, route-step, or interface change.
Production widgetInput consumption, output gain, production animation, interface closure, or batch completion.
Dialogue optionDialogue text/options change, widget closure, var change, quest state, or location transition.

Do not use an unfiltered global event as proof. An AnimationChanged event for another actor, an unrelated inventory delta, or any widget load does not confirm the requested action.

Failure handling

Handle current statuses at the immediate decision point:

  • Retry PACED, MOVEMENT_IN_PROGRESS, and selected transient UI states on a later tick.
  • Re-query after TARGET_NOT_FOUND or TARGET_STALE when the module expects targets to respawn or move.
  • Fail or choose another candidate after ACTION_NOT_FOUND, ACTIONS_NULL, or invalid mapping/readiness failures.
  • Start or continue a Walker flow after a path-related status only when the module owns that recovery decision.
  • Bound repeated failures. Record the module, state, target, status, and last observed postcondition.

Use StepResult.fromInteractionPaced(...) when pacing is the only retryable failure. Use fromInteractionTransient(...) only when every status in its retry set is transient for the current step.

Development requirements

  • Port names, IDs, action strings, areas, and target priorities from the old module source.
  • Resolve item and entity IDs through current RuneLite constants or IdMapRegistry where revision ownership requires it.
  • Reuse ActionResolver; do not strip tags or normalize actions with module-local regexes.
  • Keep one action per tick and one state owner for retries.
  • Preserve target continuity with stable keys, not cached entity instances.
  • Separate target selection failure, dispatch failure, postcondition timeout, and terminal module failure in snapshots and logs.

Tests

Each entity-driven module needs focused coverage for:

  • No target, stale target, wrong action, paced action, and accepted dispatch.
  • Multiple targets where path-aware choice differs from straight-line choice.
  • Target movement or despawn between query and interaction.
  • Unrelated events that must not satisfy the postcondition.
  • Postcondition success on a later tick.
  • Timeout followed by bounded re-query, alternate target, or terminal failure.

Live acceptance must observe the requested game-state transition. Static query tests and DISPATCHED do not prove gameplay completion.