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:
- Query current client state through
com.n3plugins.sdk.query.*. - Dispatch through
com.n3plugins.Api.actions.*. - 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 type | RuneLite/n3 type | Query owner | Result-aware action owner |
|---|---|---|---|
GameObject | TileObject | TileObjects / TileObjectQuery | ObjectActions |
NPC | NPC | NPCs / NPCQuery | NPCActions |
GroundItem | ETileItem | TileItems / TileItemQuery | GroundItemActions |
WidgetChild | Widget | Widgets and domain widget APIs | WidgetActions or a domain action owner |
Player | Player | Players | PlayerActions |
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.
| Action | Minimum useful observation |
|---|---|
| Chop or mine | Local-player animation, XP gain, inventory delta, or resource-object change tied to the target. |
| Fish | Fishing animation, catch inventory delta, XP gain, or fishing-spot state change. |
| Attack | Actor interaction/combat state, combat animation, hitsplat/health change, target death, or disengagement. |
| Take ground item | Inventory quantity increase or target ground item disappearance. |
| Use item on item/object/NPC | Selected-widget state followed by the expected inventory, interface, animation, or var change. |
| Open, pass, or climb | Position, plane, region, route-step, or interface change. |
| Production widget | Input consumption, output gain, production animation, interface closure, or batch completion. |
| Dialogue option | Dialogue 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_FOUNDorTARGET_STALEwhen 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
IdMapRegistrywhere 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.