Skip to content

QuestScript: multiple unchecked getDefinedPoint().getWorldPoint() calls throw NPE through EventBus #3

@runsonmypc

Description

@runsonmypc

Summary

QuestScript.applyNpcStep and several sibling methods call step.getDefinedPoint().getWorldPoint() without a null check. When a step has no defined point, getDefinedPoint() returns null, and the resulting NPE propagates up through the RuneLite EventBus as an uncaught subscriber exception, spamming the log.

Likely the same path also explains how invalid coordinates (e.g. instance-template coords) leak through to Rs2Walker.walkTo — see #2.

Location

runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestScript.java

Unchecked sites (at least):

Line Context
1325 if (step.getDefinedPoint().getWorldPoint().distanceTo(Rs2Player.getWorldLocation()) > 3) {
1326 Rs2Walker.walkTo(step.getDefinedPoint().getWorldPoint(), 2);
1378 if (step.getDefinedPoint().getWorldPoint() != null && ... (partial check — getDefinedPoint() itself still unchecked)
1381 WorldPoint stepLocation = object == null ? step.getDefinedPoint().getWorldPoint() : object.getWorldLocation();
1400 if (path.get(path.size() - 1).distanceTo(step.getDefinedPoint().getWorldPoint()) <= 1)
1429 if (!Rs2Walker.walkTo(step.getDefinedPoint().getWorldPoint()))
1431 else if (!Rs2Player.getWorldLocation().equals(step.getDefinedPoint().getWorldPoint()))
1432 Rs2Walker.walkFastCanvas(step.getDefinedPoint().getWorldPoint());

DetailedQuestStep.getDefinedPoint() returns null by default (field is only set when the step is constructed with an explicit DefinedPoint or WorldPoint).

Line 1171 already demonstrates the safe pattern:

WorldPoint worldPoint = questStep.getDefinedPoint() != null ? questStep.getDefinedPoint().getWorldPoint() : null;

…it's just not used consistently.

Repro in live log

Repeating ~8+ times during a quest helper session:

[Client] WARN  n.runelite.client.eventbus.EventBus - Uncaught exception in event subscriber
java.lang.NullPointerException: Cannot invoke
  "net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint.getWorldPoint()"
  because the return value of
  "net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep.getDefinedPoint()"
  is null

Impact

  1. Log spam — every NPE fires through EventBus, one full stack trace per occurrence.
  2. Silent step skip — the exception aborts the current event-handler invocation; subsequent logic in the same method never runs, so the walker may never be told to move for the step, making the script appear stuck.
  3. Possible secondary cause of invalid coordinates — the same code paths are handing WorldPoint values to Rs2Walker.walkTo. Bad DefinedPoint data (e.g. instance-template coords resolved outside an instance world view) would propagate through these unchecked calls.

Suggested fix

Extract a helper to centralize the check, or inline null-check at each site.

Inline pattern (minimum diff):

DefinedPoint dp = step.getDefinedPoint();
WorldPoint wp = dp == null ? null : dp.getWorldPoint();
if (wp != null && wp.distanceTo(Rs2Player.getWorldLocation()) > 3) {
    Rs2Walker.walkTo(wp, 2);
}

Helper pattern:

private static WorldPoint safeWorldPoint(DetailedQuestStep step) {
    DefinedPoint dp = step == null ? null : step.getDefinedPoint();
    return dp == null ? null : dp.getWorldPoint();
}

Then every call site becomes WorldPoint wp = safeWorldPoint(step); if (wp != null) { ... }.

Consider also adding a debug log at the skip site so future stuck-looking-but-silent cases are easier to trace.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions