Skip to content

Comments

Poh transports added on runtime#1506

Merged
chsami merged 15 commits intochsami:developmentfrom
Krulvis:feature/rework-tsv
Sep 11, 2025
Merged

Poh transports added on runtime#1506
chsami merged 15 commits intochsami:developmentfrom
Krulvis:feature/rework-tsv

Conversation

@Krulvis
Copy link
Contributor

@Krulvis Krulvis commented Sep 11, 2025

Since we can't reliably say where PoH is, it required TSV data for all posibilities, creating an enormous amount of useless data. In this PR I rework PoH transports to be dynamically added during runtime when pathfinder refreshes its available transports. Based on Rs2PohCache the available PohTransports are added to the PathfinderConfig. The pathfinder is able to deal with them like regular transports and doesn't require any modifications.

This implementation keeps the ShortestPathfinder plugin as similar as possible to the original plugin. The TSV's remain unaffected. There's only one additional function added to the PathfinderConfig to merge runtime transports with persistent transports. Additionally, some constructors were added to the Transport class and one was made public.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR restructures POH transport handling across the shortest path system. It introduces PohTransport, adds PohTeleports.getTransportsToPoh(), and updates Rs2PohCache with new public APIs, fairy-ring integration, and spawn/despawn handling. PathfinderConfig now merges TSV, PoH, and world-to-PoH transports, adds Spirit Tree gating, and refines consumable-teleport filtering. Transport gains several public constructors, removes POH enum-tracing fields, and stops loading POH TSVs. Rs2Walker refactors transport selection and executes PohTransport directly. HouseStyle renames its POH location field to pohExitWorldPoint, adds getPohExitPoint, and HouseLocation updates TSV mapping. Minor formatting and serialization-variable renaming are included.

Possibly related PRs


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java (2)

268-315: Method createMergedList() should be static

The method doesn't access any instance fields and is only called from within the instance method refreshTransports. Making it static would improve clarity about its dependencies.

-    private Map<WorldPoint, Set<Transport>> createMergedList() {
+    private static Map<WorldPoint, Set<Transport>> createMergedList(Map<WorldPoint, Set<Transport>> allTransports) {
         Map<WorldPoint, Set<Transport>> mergedTransports = new HashMap<>();
 
         // Start with putting all the TSV imported persistent transports

And update the call site at line 268:

-        for (Map.Entry<WorldPoint, Set<Transport>> entry : createMergedList().entrySet()) {
+        for (Map.Entry<WorldPoint, Set<Transport>> entry : createMergedList(allTransports).entrySet()) {

475-476: Simplify conditional logic for Spirit Tree check

The Spirit Tree check can be simplified by directly returning the result.

-        // Check Spirit Tree specific requirements (farming state for farmable trees)
-        if (transport.getType() == TransportType.SPIRIT_TREE) return isSpiritTreeUsable(transport);
+        // Check Spirit Tree specific requirements (farming state for farmable trees)
+        if (transport.getType() == TransportType.SPIRIT_TREE) {
+            return isSpiritTreeUsable(transport);
+        }
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/cache/Rs2PohCache.java (2)

136-145: Inconsistent logging between addTeleport and removeTeleport

The removeTeleport method logs "Removing X Teleport from Y" while addTeleport logs "Adding X Teleport to Y". The remove log should use past tense for consistency with the operation's completion.

-        log.info("Removing {} Teleport from {}", teleport.name(), key);
+        log.info("Removed {} Teleport from {}", teleport.name(), key);

147-156: Inconsistent logging in addTeleport

Similar to removeTeleport, the log message should use past tense.

-        log.info("Adding {} Teleport to {}", teleport.name(), key);
+        log.info("Added {} Teleport to {}", teleport.name(), key);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9b477a and 632c03f.

⛔ Files ignored due to path filters (5)
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/fairy_rings.tsv is excluded by !**/*.tsv
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_items.tsv is excluded by !**/*.tsv
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_poh.tsv is excluded by !**/*.tsv
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_portal_poh.tsv is excluded by !**/*.tsv
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_spells.tsv is excluded by !**/*.tsv
📒 Files selected for processing (10)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathPlugin.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/Transport.java (3 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java (4 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/cache/Rs2PohCache.java (5 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/cache/serialization/PohTeleportDataAdapter.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (3 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTransport.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/HouseLocation.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/HouseStyle.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/cache/serialization/PohTeleportDataAdapter.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTransport.java (1)
  • PohTransport (15-34)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTransport.java (1)
  • PohTransport (15-34)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (1)
  • PohTeleports (37-254)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTransport.java (1)
  • PohTransport (15-34)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (1)
  • PohTeleports (37-254)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java (1)
  • Rs2Player (67-2076)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/Transport.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (1)
  • PohTeleports (37-254)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTransport.java (1)
  • PohTransport (15-34)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/cache/Rs2PohCache.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (1)
  • PohTeleports (37-254)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTransport.java (1)
  • PohTransport (15-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (10)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/HouseStyle.java (3)

30-30: Rename clarifies intent; no issues.
Field rename to pohExitWorldPoint improves semantics and matches downstream usage.


43-43: Deduped exit points is correct.
Mapping via getPohExitWorldPoint() with distinct() avoids duplicate coordinates.


50-53: Helper is fine.
Static accessor reads Varbit and returns the exit point or null; callers already null-check upstream.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/HouseLocation.java (1)

51-51: Destination switch to exit point is correct.
Using style.getPohExitWorldPoint() aligns with the new data model.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/Transport.java (2)

134-134: Public merge ctor is acceptable.
Surface area increases but behavior is unchanged; no blockers.


11-15: New POH-related imports.
No action; leaving as-is.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathPlugin.java (1)

203-203: No-op whitespace change

Nothing to review here.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/cache/serialization/PohTeleportDataAdapter.java (2)

28-33: Serializer variable rename and field usage look correct

Using the teleport variable consistently and emitting class + name aligns with the deserializer logic.


6-6: No action on added import

No immediate issue detected for this change in isolation.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/PohTeleports.java (1)

235-252: Confirm null-keyed transport visibility at runtime

These PoH teleports are stored under a null key. Rs2Walker.handleTransports() currently looks up transports by the current path tile only; unless ShortestPathPlugin.getTransports() merges/null-propagates these, the walker may never consider them. Please verify that null-keyed entries are surfaced to the walker during execution. If not, either:

  • also index them under insidePoint, or
  • update the walker to union the null-keyed set when evaluating transports (see suggested change in Rs2Walker below).

Set<PohTransport> pohTransports = getAvailablePohTransports();
Map<WorldPoint, Set<Transport>> transportsMap = new HashMap<>();
if (pohTransports.isEmpty()) return transportsMap;
WorldPoint exitPortal = pohTransports.stream().findFirst().get().getOrigin();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential NPE when pohTransports is empty

Line 195 assumes pohTransports is not empty after checking isEmpty() returns false. However, between the check on line 194 and access on line 195, the set could theoretically become empty in a concurrent environment.

-        if (pohTransports.isEmpty()) return transportsMap;
-        WorldPoint exitPortal = pohTransports.stream().findFirst().get().getOrigin();
+        if (pohTransports.isEmpty()) return transportsMap;
+        Optional<PohTransport> firstTransport = pohTransports.stream().findFirst();
+        if (!firstTransport.isPresent()) return transportsMap;
+        WorldPoint exitPortal = firstTransport.get().getOrigin();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
WorldPoint exitPortal = pohTransports.stream().findFirst().get().getOrigin();
if (pohTransports.isEmpty()) return transportsMap;
Optional<PohTransport> firstTransport = pohTransports.stream().findFirst();
if (!firstTransport.isPresent()) return transportsMap;
WorldPoint exitPortal = firstTransport.get().getOrigin();

@Voxsylvae
Copy link
Contributor

Similar what I'm doing in my current local version!
Would you like me to submit my current version so you can build and improve upon it?
Includes all the changes from your PR so far, plus these additional enhancements:

  • POH cache refactor - caching of all objects and varbits for a player
  • Class renaming - cleaned up the teleport POH classes for better maintainability
  • Optimal route planning - implemented but needs testing which i would be happy to do
  • House advertisement support
  • Extended POH utility classes and functions - additional helper methods and APIs

Since we're tackling the same core problem with similar approaches, collaborating on this could be really beneficial. Should I make a PR for it ? So you don't tackle the same problem I have already implemented.
What do you think?

@Krulvis
Copy link
Contributor Author

Krulvis commented Sep 11, 2025

Similar what I'm doing in my current local version! Would you like me to submit my current version so you can build and improve upon it? Includes all the changes from your PR so far, plus these additional enhancements:

* POH cache refactor - caching of all objects and varbits for a player

* Class renaming - cleaned up the teleport POH classes for better maintainability

* Optimal route planning - implemented but needs testing which i would be happy to do

* House advertisement support

* Extended POH utility classes and functions - additional helper methods and APIs

Since we're tackling the same core problem with similar approaches, collaborating on this could be really beneficial. Should I make a PR for it ? So you don't tackle the same problem I have already implemented. What do you think?

Let's tackle all of them in separate PRs so it doesn't get too large and incomprehensible in a single PR. I'm definitely down to helping with all of those features!

@Krulvis
Copy link
Contributor Author

Krulvis commented Sep 11, 2025

@Voxsylvae After this PR we won't have to deal with annoyances from adding everything in TSV's and can really lay the foundations for a more dynamic web.
I can see the next PR being the rework of Rs2PohCache since it's very limited atm and only serves the goal of tracking which teleports are available, not where they are. Like you're saying the objects that relate to the teleports and their position is a very useful stepping stone for implementing pathing inside the POH. But I don't believe they have to be done in one PR.

@Voxsylvae
Copy link
Contributor

Voxsylvae commented Sep 11, 2025

Sure, then i will add the cache rework + the rework for the teleports, need for the cache rework, after your PR. if you are fine with it. Im happy when we can collaborate together.

@chsami chsami merged commit 70035e7 into chsami:development Sep 11, 2025
2 checks passed
This was referenced Sep 11, 2025
This was referenced Sep 23, 2025
This was referenced Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants