Sitelet https://github.com/mod-playerbots/mod-playerbots/pull/2865
Skip to content

fix(Bot): Recover stalled taxi flights - #2865

Open
ShaneBair wants to merge 2 commits into
mod-playerbots:test-stagingfrom
ShaneBair:fix/recover-stalled-taxi
Open

ShaneBair wants to merge 2 commits into
mod-playerbots:test-stagingfrom
ShaneBair:fix/recover-stalled-taxi

Conversation

@ShaneBair

Copy link
Copy Markdown

Pull Request Description

Fixes random bots becoming permanently stuck in taxi state when their flight movement spline stops progressing.

Taxi recovery is moved into PlayerbotAI, where it runs consistently for every bot currently marked as in flight instead of depending on the New RPG travel action being selected.

The watchdog:

  • Tracks changes in map, taxi route node, spline index, and physical position.
  • Continues valid taxi routes across map boundaries.
  • Attempts one controlled restart when a same-map flight spline stalls.
  • After 15 seconds without progress, safely cleans up the taxi state.
  • Teleports the bot to the route’s validated final taxi node when recovery cannot resume.
  • Leaves normal maintenance and stuck recovery to handle the bot when no valid final destination is available.

Healthy taxi flights retain their existing behavior.

Closes #2863

Feature Evaluation

  • Describe the minimum logic required to achieve the intended behavior.

    A small per-bot watchdog records the most recent taxi progress indicators. Recovery is attempted only when the bot is currently in flight and the spline has stopped progressing. It first attempts to resume the existing route, then uses a bounded cleanup fallback.

  • Describe the processing cost when this logic executes across many bots.

    All bots perform a cheap IsInFlight() check during their normal AI update. Bots that are not flying immediately bypass the remaining logic. Flying bots perform a small number of integer comparisons and a squared-distance calculation. There are no database queries, path searches, or unbounded loops. Recovery and destination lookups occur only while handling a taxi flight.

How to Test the Changes

  1. Build and start the server with random Playerbots enabled.
  2. Allow bots to use normal taxi routes, including routes that cross map boundaries.
  3. Confirm healthy taxi flights continue and finish normally.
  4. Observe a bot whose flight spline becomes finalized or stops moving while it remains in taxi state.
  5. Confirm the watchdog attempts one route or spline recovery.
  6. If the flight still makes no progress for 15 seconds, confirm that:
    • The flight movement generator is removed.
    • Taxi state and flags are cleared.
    • The bot is placed at the validated final taxi node when one is available.
    • The bot resumes normal AI behavior instead of remaining permanently stuck.
  7. Review the playerbots log messages for cross-map continuation, restart attempts, and fallback cleanup.

The change was exercised on a live local realm during two approximately 24-hour soak test. Follow-up checks did not find bots remaining indefinitely stuck in taxi state.

Impact Assessment

  • Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots?

      • No, not at all
      • Minimal impact (explain below)
      • Moderate impact (explain below)

    The normal per-bot cost is an IsInFlight() check. Additional progress comparisons run only for bots actively using a taxi. The watchdog has a fixed amount of state and all recovery attempts are bounded.

  • Does this change modify default bot behavior?

      • No
      • Yes (explain why)

    It changes failure handling for bots whose taxi movement stops progressing. Normal, progressing taxi flights are not intentionally changed.

  • Does this change add new decision branches or increase maintenance complexity?

      • No
      • Yes (explain below)

    It adds a contained taxi-recovery state machine to PlayerbotAI. The additional branches distinguish healthy progress, cross-map continuation, one restart attempt, and final cleanup. Recovery is bounded to keep its behavior predictable.

AI Assistance

Was AI assistance used while working on this change?

    • No
    • Yes (explain below)

I used GPT-5.6 Sol High to assist in investigating the flight failures and architecting a solution for flight recovery. I also utilized it's assistance in implementation, monitoring bot health after the changes over two 24 hour peroids, and making sure I had everything lined up to try to contribute back in the least headache inducing way possible for the team.

Code Provenance / Attribution

Was any code in this PR copied or adapted from a sister / upstream project (e.g. CMaNGOS playerbots, MaNGOS, another module)?

    • No, all code in this PR is original
    • Yes (name the project and the original author(s) below)

Final Checklist

    • Changes are understood and tested for server stability and performance impact.
    • Any new bot dialogue lines are translated. (No dialogue was added.)
    • New source files use the GPLv2 header. (No new source files were added.)
    • Documentation updated if needed. (No configuration, commands, or user-facing behavior require documentation changes.)
    • New and modified files do not introduce new compiler warnings.

Notes for Reviewers

  • Is PlayerbotAI::UpdateAI the appropriate centralized location for taxi recovery?
  • Are the 15-second timeout and single restart attempt are suitable defaults?
  • Does the final taxi-node validation and cleanup sequence cover all expected incomplete-route states?

Random bots can remain in taxi state when movement splines stop making progress. Centralize taxi handling in PlayerbotAI, track route and position progress, relaunch a stalled spline once, and safely finish at the validated final destination when recovery cannot resume.

Closes mod-playerbots#2863
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

📝 Walkthrough

Walkthrough

The RPG flight action now sets in-flight state after taxi activation and no longer continues cross-map travel through its removed helper. PlayerbotAI tracks taxi progress and handles stalled flights by restarting eligible movement or clearing flight state and taxi cleanup flags.

Priority: ⬆️ High

Severity of issue fixed: High

Merge Risk: 🟡 Moderate · up to ce846

Bots whose taxi splines stall may keep restarting instead of being cleaned up, which could leave them stuck in flight. The 15-second cleanup is meant to prevent this. Confirm or fix how restart attempts are counted before merging.

Security Architecture Review

Security architecture risk: 🔵 Low · up to ce846

Recovery now affects all eligible bots in taxi flight and can restart movement or relocate a stalled bot. Destination checks constrain this behavior, but interrupted recovery and cleanup have not been fully verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The supported behavioral scope is every PlayerbotAI-managed bot marked in flight whose update passes the existing eligibility gates, not merely bots using the New RPG travel action. Recovery can mutate each affected bot's movement, taxi bookkeeping, PvP state, and location.

Trust Boundaries and Controls

  • observed — The inspected RPG status-command path restricts mutation to the bot's master or a GM and selects the taxi route server-side. Taxi Execute ignores its event argument, consumes stored flight data, requires a live nearby flight master, and checks core activation success. Recovery subsequently reads live taxi state rather than accepting new caller-supplied coordinates.

Resilience and Maintainability Implications

  • observed — Locally, terminal recovery expires the controlled movement slot only if it remains flight-owned, clears in-flight state, invokes taxi cleanup, updates PvP state, removes the taxi benchmark flag, and resets the watchdog before optional final relocation. Leaving flight also clears watchdog state. These calls show cleanup intent but do not establish the unavailable core operations' interruption or concurrency guarantees.
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: mod-playerbots/mod-playerbots/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 78379c90-85ba-4e6c-8af4-535b11129af5

📥 Commits

Reviewing files that changed from the base of the PR and between 7a1d7a1 and ce846f4.

📒 Files selected for processing (4)
  • src/Ai/World/Rpg/Action/NewRpgAction.cpp
  • src/Ai/World/Rpg/Action/NewRpgAction.h
  • src/Bot/PlayerbotAI.cpp
  • src/Bot/PlayerbotAI.h
💤 Files with no reviewable changes (1)
  • src/Ai/World/Rpg/Action/NewRpgAction.h

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread src/Bot/PlayerbotAI.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Comment thread src/Bot/PlayerbotAI.cpp
if (!CanUpdateAI())
return;

if (HandleTaxiFlight())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pauses the whole bot AI for every bot in flight, not only stalled ones. HandleTaxiFlight() returns true on every path once the bot is in flight, so UpdateAI() returns here until the bot lands. Chat commands, packet handlers and the strategy engine all wait. That includes altbots, so healthy flights don't keep their existing behavior.

I ran this on a test server with an altbot flying Stormwind to Booty Bay (about 3 minutes). On test-staging, who whispered mid-flight was answered at once, and summon pulled the bot off the gryphon. With this PR, both only ran after the bot landed.

The pause may be what you want: no engine action can touch the taxi spline mid-flight, and that's where #2863 is now looking. If so, please say it in the description, since it changes every bot. If not, return false from HandleTaxiFlight() when the progress check passes, so only stalled flights skip the rest of the update. The engine then runs in flight again, though, so an action that stops the spline goes through the restart path instead of being prevented.

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.

2 participants