Skip to content

Improve bot hunting routes and party recruitment - #82

Merged
pmbstyle merged 6 commits into
mainfrom
agent/bot-hunting-party-recruitment
Aug 6, 2026
Merged

Improve bot hunting routes and party recruitment#82
pmbstyle merged 6 commits into
mainfrom
agent/bot-hunting-party-recruitment

Conversation

@pmbstyle

@pmbstyle pmbstyle commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • make bot hunting-ground selection follow level, class, drop, and travel constraints instead of overusing starter fields
  • add geodata-aware cold travel and improve spot scheduling/observability
  • prioritize required party requests before the bounded candidate window and size background recruitment from actionable backlog
  • add regression coverage for hunting-ground rules, cold travel, population scheduling, gear planning, and party recruitment

Root cause

The previous selection path could keep eligible bots on early fields even when better level-appropriate spots existed. Cold travel and gear planning also caused avoidable state churn. For parties, ordinary eligible solo candidates could fill the bounded query before bots with required objectives were considered, leaving requests waiting despite available capacity.

Validation

  • targeted bot hunting, population, and party recruitment tests
  • full npm test
  • npm run check (780 JavaScript files)
  • git diff --check
  • live x50 server verification: required objectives were selected on target spots, active requests stayed unblocked, and party formation/recruitment continued without scheduler overruns

Summary by CodeRabbit

  • New Features

    • Bots now select hunting grounds based on level suitability, NPC density, and safer target ranges.
    • Bots can relocate between hunting spots by walking or teleport travel, with improved arrival and interruption handling.
    • Gear acquisition supports more reliable source selection, caching, and duplicate reward locations.
    • Population scheduling adapts to player activity and server lag.
    • Party formation prioritizes required requests and improves cold-state prioritization.
    • Added clearer population and scheduler status information.
  • Bug Fixes

    • Prevented stale locations and unsuitable low-level targets from affecting bot activation and hunting decisions.
  • Tests

    • Expanded coverage for hunting rules, travel, scheduling, party recruitment, and gear progression.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a984706a-f7e6-4ea4-a5dc-48f158d5a0da

📥 Commits

Reviewing files that changed from the base of the PR and between 8ac8645 and 366ba34.

📒 Files selected for processing (2)
  • src/GameServer/Bot/Population/BotLifeState.js
  • tests/test_bot_population_state.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_bot_population_state.js
  • src/GameServer/Bot/Population/BotLifeState.js

📝 Walkthrough

Walkthrough

The change adds level-aware hunting rules, controlled spot relocation, gear-source caching, required-party prioritization, scheduler profiles, resolve limits, and population telemetry. It also adds tests for hunting, travel, gear acquisition, party recruitment, and scheduler behavior.

Changes

Bot hunting and travel

Layer / File(s) Summary
Level-aware hunting rules
src/GameServer/Bot/AI/SpotService.js, src/GameServer/Bot/AI/BotTargetScorer.js, src/GameServer/Bot/AI/BotStatus.js, src/GameServer/Bot/Population/SpotProfiles.js, src/GameServer/Bot/Population/HotActivation.js, src/GameServer/Bot/AI/LevelingRoutes.js, tests/test_bot_hunting_ground_rules.js, scripts/run-tests.js
Spot selection, target scoring, activation placement, and starter tagging now use level-aware rules. The hunting-ground test runs sequentially.
Spot relocation flow
src/GameServer/Bot/AI/BotSpotTravel.js, src/GameServer/Bot/AI/States/HuntingState.js, src/GameServer/Bot/Population/PopulationService.js, tests/test_bot_cold_travel_without_spot.js
Bots now use walking or SoE travel with cancellation, arrival handling, physical-spot reconciliation, and travel-state resolution.
Gear source resolution
src/GameServer/Bot/AI/GearAcquisitionPlanner.js, tests/test_bot_gear_acquisition.js
Source indexing retains matching spots. Source results use bounded, rate-aware caches and shared planning options. Candidate scoring evaluates each candidate once.

Population scheduling

Layer / File(s) Summary
Cold-state and party priorities
src/GameServer/Bot/Population/BotLifeState.js, src/GameServer/Bot/Population/PopulationService.js, src/GameServer/Bot/Population/PopulationStatus.js, tests/test_bot_population_state.js, tests/test_bot_background_party_recruitment.js
Equipment replans and required party requests receive priority. Cold-queue summaries and required-request capacity behavior are covered by tests.
Scheduler profiles and limits
src/GameServer/Bot/Population/PopulationConfig.js, src/GameServer/Bot/Population/PopulationService.js, tests/test_bot_population_scheduler_slices.js
Idle and player scheduler profiles now have separate budgets and resolve limits. Event-loop lag can throttle or abort scheduling.
Scheduler metrics and status
src/GameServer/Bot/Population/PopulationMetrics.js, src/GameServer/Bot/Population/PopulationStatus.js
Metrics and status output now report scheduler state, cold batches, queue summaries, and categorized skipped resolves.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HuntingState
  participant BotSpotTravel
  participant BotSession
  HuntingState->>BotSpotTravel: Start spot relocation
  BotSpotTravel->>BotSession: Start movement or SoE cast
  BotSpotTravel->>BotSession: Teleport and assign destination spot
  BotSpotTravel->>HuntingState: Complete arrival after settling
Loading

Possibly related PRs

  • pmbstyle/L2Solo#79: Both changes modify background-party recruitment and population scheduling behavior.
  • pmbstyle/L2Solo#80: Both changes modify population scheduling, metrics, configuration, and bot-state flows.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the pull request’s primary changes to bot hunting routes and party recruitment.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/bot-hunting-party-recruitment

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

@pmbstyle pmbstyle self-assigned this Aug 6, 2026
@pmbstyle
pmbstyle marked this pull request as ready for review August 6, 2026 12:53

@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: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/GameServer/Bot/Population/HotActivation.js (1)

75-88: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Stale saved spot can still relocate a bot that has coordinates.

The comment on lines 76-77 states that coordinates are authoritative. That holds only when SpotService.findCurrentSpot(state.loc) resolves. If the bot stands in an area with no mapped spot, physicalSpot is null and spot falls back to savedSpot. Line 86 then calls SpotService.randomPointNear(spot, ...) and places the bot at the remote saved field, which is the case this change intends to prevent.

Restrict the saved-spot placement path to states without coordinates.

🐛 Proposed fix
     for (let i = 0; i < Config.activationPlacementAttempts; i++) {
-        candidate = spot && !options.playerLoc
+        candidate = spot && !options.playerLoc && (physicalSpot || !state?.loc)
             ? SpotService.randomPointNear(spot, Config.activationPlacementRadius)
             : randomAround(baseLoc, Config.activationPlacementRadius);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/GameServer/Bot/Population/HotActivation.js` around lines 75 - 88, Update
the spot selection and placement logic around physicalSpot, savedSpot, and the
candidate loop so savedSpot is used for randomPointNear only when state.loc is
absent. When coordinates exist but findCurrentSpot returns null, use the
coordinate-based randomAround path instead of relocating via the stale saved
spot.
🧹 Nitpick comments (2)
src/GameServer/Bot/Population/SpotProfiles.js (1)

108-125: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider dropping the unconditional profiles[0] fallback.

Lines 120-125 return profiles[0] when no candidate matches the level band. profiles[0] is arbitrary and can be a starter field that SpotService.isSuitable rejects. That result contradicts the level-aware rules this change introduces, and PopulationService.beginHuntingTravel will then route the bot to a wrong-level ground instead of recording missing_spot.

Return null when no suitable or in-band candidate exists, so callers can record the miss.

♻️ Proposed change
-        return (suitable.length ? suitable : candidates).sort((a, b) => {
+        const pool = suitable.length ? suitable : candidates;
+        return pool.sort((a, b) => {
             const aGap = Math.abs(a.avgLevel - targetLevel);
             const bGap = Math.abs(b.avgLevel - targetLevel);
             if (aGap !== bGap) return aGap - bGap;
             return b.density - a.density;
-        })[0] || profiles[0] || null;
+        })[0] || null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/GameServer/Bot/Population/SpotProfiles.js` around lines 108 - 125, Remove
the unconditional profiles[0] fallback from the final return in the
spot-selection flow, preserving the sorted suitable/candidates result but
returning null when neither list contains a valid entry. Keep the existing
guided-spot behavior unchanged so callers can record missing_spot when no
level-aware candidate exists.
src/GameServer/Bot/Population/PopulationService.js (1)

34-37: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tighten the location guard.

The hasOwnProperty clause on line 36 adds nothing. If state.loc omits locX, then Number(undefined) is NaN and Number.isFinite already returns false. The clause is unreachable protection.

The real gap is coercion. Number(null) and Number('') both return 0, so a state with loc: { locX: null, locY: null } passes the guard. SpotService.findCurrentSpot then resolves grid 0_0 and the bot starts travel from the world origin.

♻️ Proposed change
     const from = { ...(state.loc || {}) };
-    const hasLocation = Number.isFinite(Number(from.locX)) && Number.isFinite(Number(from.locY))
-        && (Object.prototype.hasOwnProperty.call(from, 'locX') || Object.prototype.hasOwnProperty.call(from, 'locY'));
+    const hasLocation = typeof from.locX === 'number' && Number.isFinite(from.locX)
+        && typeof from.locY === 'number' && Number.isFinite(from.locY);
     if (!hasLocation) return null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/GameServer/Bot/Population/PopulationService.js` around lines 34 - 37,
Update the location guard in the population flow to reject null and empty-string
coordinate values before numeric coercion, preventing invalid locations from
resolving to grid 0_0; remove the redundant hasOwnProperty checks and continue
accepting only finite, genuinely provided locX and locY values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/GameServer/Bot/AI/BotSpotTravel.js`:
- Around line 22-35: Update start in BotSpotTravel.js to validate the resolved
destination coordinates from targetLoc or spot.center before assigning
session.spotRelocation. Reject and return false when the destination is missing
coordinates or any coordinate is non-finite; only create the relocation state
and begin the cast for valid destinations.
- Around line 44-49: The delayed relocation check in the setTimeout callback
must cancel spot relocation before returning from either PK-combat branch.
Update both PK branches to call BotSpotTravel.cancel (or the local cancel
helper) before their returns, preserving the existing combat-interrupt
cancellation behavior and preventing relocation during the SoE cast or flee.

In `@src/GameServer/Bot/AI/SpotService.js`:
- Around line 32-45: Update huntBand to normalize targetLevel and both level-gap
inputs to finite numeric values before calculating min and max, ensuring
Infinity and other non-finite values cannot produce an unbounded band. Preserve
the existing defaults and clamping behavior, and keep eligibleDensity’s level
iteration bounded.

In `@src/GameServer/Bot/AI/States/HuntingState.js`:
- Line 275: Reorder the control flow in HuntingState so the incoming-threat/PK
handling block executes before the session.spotRelocation.arrivalPending early
return, allowing combat, fleeing, and relocation cancellation. Move that
relocation gate below the existing HP/MP recovery check so low-health or
low-resource bots can rest before returning; preserve the documented death-loop
prevention behavior.
- Around line 150-163: Update tickSpotRelocation to use relocation.startedAt as
a maximum-duration deadline, clearing session.spotRelocation and returning false
when the deadline expires before arrival. Apply equivalent expiration handling
to the soe_gatekeeper branch so it cannot remain active indefinitely, while
preserving successful arrival completion and normal walk-command throttling.

In `@src/GameServer/Bot/Population/BotLifeState.js`:
- Around line 1989-2012: Update the cache filtering in coldDueSummary to reuse
the stale equipment-plan predicate used by dueCold(), allowing cold hunting
states with an outdated rateModelVersion to count as due even when nextResolveAt
is later. Apply this check before the nextResolveAt timestamp return while
preserving existing exclusions and summary calculations.

In `@src/GameServer/Bot/Population/PopulationConfig.js`:
- Around line 142-145: Cap the scheduler resolve limits used by
schedulerProfile() at the same 100-state maximum enforced by dueCold(). Update
the configuration handling for schedulerIdleMaxResolvesPerTick and
schedulerPlayerMaxResolvesPerTick, or reuse a shared limit, so configured values
above 100 cannot produce mismatched telemetry or exceed the query cap.

In `@src/GameServer/Bot/Population/PopulationService.js`:
- Around line 1103-1112: Update the lag-budget logic around lagThrottle,
lagAbort, and pressure so configuring schedulerLagThrottleMs still reduces
budget when schedulerLagAbortMs is zero or unset. Use a proportional throttle
fallback based on the configured throttle threshold, while preserving the
existing abort behavior and interpolation when lagAbort is configured.

In `@tests/test_bot_cold_travel_without_spot.js`:
- Line 93: Remove the unused _value and _result parameters from the callback
near the planning request handling, and remove the planningAtlasRequests reset
unless this scenario adds an assertion validating the expected count afterward.
Keep the test behavior unchanged otherwise.

---

Outside diff comments:
In `@src/GameServer/Bot/Population/HotActivation.js`:
- Around line 75-88: Update the spot selection and placement logic around
physicalSpot, savedSpot, and the candidate loop so savedSpot is used for
randomPointNear only when state.loc is absent. When coordinates exist but
findCurrentSpot returns null, use the coordinate-based randomAround path instead
of relocating via the stale saved spot.

---

Nitpick comments:
In `@src/GameServer/Bot/Population/PopulationService.js`:
- Around line 34-37: Update the location guard in the population flow to reject
null and empty-string coordinate values before numeric coercion, preventing
invalid locations from resolving to grid 0_0; remove the redundant
hasOwnProperty checks and continue accepting only finite, genuinely provided
locX and locY values.

In `@src/GameServer/Bot/Population/SpotProfiles.js`:
- Around line 108-125: Remove the unconditional profiles[0] fallback from the
final return in the spot-selection flow, preserving the sorted
suitable/candidates result but returning null when neither list contains a valid
entry. Keep the existing guided-spot behavior unchanged so callers can record
missing_spot when no level-aware candidate exists.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ddea9fd6-ceac-4794-b6bc-cac35a6ba246

📥 Commits

Reviewing files that changed from the base of the PR and between ea78401 and 2d6f142.

📒 Files selected for processing (22)
  • scripts/run-tests.js
  • src/GameServer/Bot/AI/BotDecisionService.js
  • src/GameServer/Bot/AI/BotSpotTravel.js
  • src/GameServer/Bot/AI/BotStatus.js
  • src/GameServer/Bot/AI/BotTargetScorer.js
  • src/GameServer/Bot/AI/GearAcquisitionPlanner.js
  • src/GameServer/Bot/AI/LevelingRoutes.js
  • src/GameServer/Bot/AI/SpotService.js
  • src/GameServer/Bot/AI/States/HuntingState.js
  • src/GameServer/Bot/Population/BotLifeState.js
  • src/GameServer/Bot/Population/HotActivation.js
  • src/GameServer/Bot/Population/PopulationConfig.js
  • src/GameServer/Bot/Population/PopulationMetrics.js
  • src/GameServer/Bot/Population/PopulationService.js
  • src/GameServer/Bot/Population/PopulationStatus.js
  • src/GameServer/Bot/Population/SpotProfiles.js
  • tests/test_bot_background_party_recruitment.js
  • tests/test_bot_cold_travel_without_spot.js
  • tests/test_bot_gear_acquisition.js
  • tests/test_bot_hunting_ground_rules.js
  • tests/test_bot_population_scheduler_slices.js
  • tests/test_bot_population_state.js

Comment thread src/GameServer/Bot/AI/BotSpotTravel.js
Comment thread src/GameServer/Bot/AI/BotSpotTravel.js
Comment thread src/GameServer/Bot/AI/SpotService.js
Comment thread src/GameServer/Bot/AI/States/HuntingState.js
Comment thread src/GameServer/Bot/AI/States/HuntingState.js Outdated
Comment thread src/GameServer/Bot/Population/BotLifeState.js
Comment on lines +142 to +145
schedulerIdleBudgetMs: 'BOT_POPULATION_SCHEDULER_IDLE_BUDGET_MS',
schedulerPlayerBudgetMs: 'BOT_POPULATION_SCHEDULER_PLAYER_BUDGET_MS',
schedulerIdleMaxResolvesPerTick: 'BOT_POPULATION_SCHEDULER_IDLE_MAX_RESOLVES',
schedulerPlayerMaxResolvesPerTick: 'BOT_POPULATION_SCHEDULER_PLAYER_MAX_RESOLVES',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cap scheduler resolve limits at the cold-query limit.

dueCold() clamps its limit to 100, but these environment variables can set a larger value. schedulerProfile() then reports the larger limit, while the query returns at most 100 states. This makes coldBatch saturation telemetry incorrect and makes the configured cap ineffective.

Clamp the profile limits to 100, or use one shared limit in both paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/GameServer/Bot/Population/PopulationConfig.js` around lines 142 - 145,
Cap the scheduler resolve limits used by schedulerProfile() at the same
100-state maximum enforced by dueCold(). Update the configuration handling for
schedulerIdleMaxResolvesPerTick and schedulerPlayerMaxResolvesPerTick, or reuse
a shared limit, so configured values above 100 cannot produce mismatched
telemetry or exceed the query cap.

Comment on lines +1103 to +1112
const lagThrottle = Math.max(0, Number(Config.schedulerLagThrottleMs) || 0);
const lagAbort = Math.max(0, Number(Config.schedulerLagAbortMs) || 0);
return lagAbort > 0 && Metrics.currentEventLoopLag() >= lagAbort
? 0
: Math.min(budget, Math.max(25, Config.schedulerIntervalMs - 25));
let budget = baseBudget;

if (lagAbort > 0 && lagMs >= lagAbort) {
budget = 0;
} else if (lagAbort > lagThrottle && lagMs > lagThrottle) {
const pressure = Math.min(1, (lagMs - lagThrottle) / (lagAbort - lagThrottle));
budget = Math.round(baseBudget * (1 - pressure));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Lag throttling is silently disabled when schedulerLagAbortMs is unset.

Line 1109 requires lagAbort > lagThrottle. If an operator configures schedulerLagThrottleMs but leaves schedulerLagAbortMs at 0, lagAbort is 0, the condition is false, and no throttling occurs at any lag value. The scheduler then keeps its full budget under load.

Fall back to a proportional throttle when lagAbort is not configured.

♻️ Proposed change
         if (lagAbort > 0 && lagMs >= lagAbort) {
             budget = 0;
         } else if (lagAbort > lagThrottle && lagMs > lagThrottle) {
             const pressure = Math.min(1, (lagMs - lagThrottle) / (lagAbort - lagThrottle));
             budget = Math.round(baseBudget * (1 - pressure));
+        } else if (lagAbort === 0 && lagThrottle > 0 && lagMs > lagThrottle) {
+            const pressure = Math.min(1, (lagMs - lagThrottle) / lagThrottle);
+            budget = Math.round(baseBudget * (1 - pressure));
         }
📝 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
const lagThrottle = Math.max(0, Number(Config.schedulerLagThrottleMs) || 0);
const lagAbort = Math.max(0, Number(Config.schedulerLagAbortMs) || 0);
return lagAbort > 0 && Metrics.currentEventLoopLag() >= lagAbort
? 0
: Math.min(budget, Math.max(25, Config.schedulerIntervalMs - 25));
let budget = baseBudget;
if (lagAbort > 0 && lagMs >= lagAbort) {
budget = 0;
} else if (lagAbort > lagThrottle && lagMs > lagThrottle) {
const pressure = Math.min(1, (lagMs - lagThrottle) / (lagAbort - lagThrottle));
budget = Math.round(baseBudget * (1 - pressure));
}
const lagThrottle = Math.max(0, Number(Config.schedulerLagThrottleMs) || 0);
const lagAbort = Math.max(0, Number(Config.schedulerLagAbortMs) || 0);
let budget = baseBudget;
if (lagAbort > 0 && lagMs >= lagAbort) {
budget = 0;
} else if (lagAbort > lagThrottle && lagMs > lagThrottle) {
const pressure = Math.min(1, (lagMs - lagThrottle) / (lagAbort - lagThrottle));
budget = Math.round(baseBudget * (1 - pressure));
} else if (lagAbort === 0 && lagThrottle > 0 && lagMs > lagThrottle) {
const pressure = Math.min(1, (lagMs - lagThrottle) / lagThrottle);
budget = Math.round(baseBudget * (1 - pressure));
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/GameServer/Bot/Population/PopulationService.js` around lines 1103 - 1112,
Update the lag-budget logic around lagThrottle, lagAbort, and pressure so
configuring schedulerLagThrottleMs still reduces budget when schedulerLagAbortMs
is zero or unset. Use a proportional throttle fallback based on the configured
throttle threshold, while preserving the existing abort behavior and
interpolation when lagAbort is configured.

Comment thread tests/test_bot_cold_travel_without_spot.js Outdated

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/GameServer/Bot/AI/BotSpotTravel.js (1)

63-70: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Commit arrival after the teleport completes.

TeleportTo returns immediately and updates the actor position after 1 second. The current code assigns currentSpot and records travel_complete before that update. Use a completion callback or Promise before committing arrival state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/GameServer/Bot/AI/BotSpotTravel.js` around lines 63 - 70, Update the
travel flow around TeleportTo so arrival state is committed only after the
teleport’s delayed position update completes. Defer SpotService.assignSpot,
initialSpawnCoord, townRoutePlan, and spotRelocation updates until TeleportTo
signals completion via its supported callback or Promise, while preserving the
existing destination and relocation values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/GameServer/Bot/Population/BotLifeState.js`:
- Around line 24-31: Update hasStaleRateModelPlan() to require plan?.status ===
'active' alongside the existing hunting activity and expectedKills checks.
Preserve the current stale rateModelVersion detection and prevent inactive plans
from being treated as ready for early resolution.

---

Outside diff comments:
In `@src/GameServer/Bot/AI/BotSpotTravel.js`:
- Around line 63-70: Update the travel flow around TeleportTo so arrival state
is committed only after the teleport’s delayed position update completes. Defer
SpotService.assignSpot, initialSpawnCoord, townRoutePlan, and spotRelocation
updates until TeleportTo signals completion via its supported callback or
Promise, while preserving the existing destination and relocation values.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cfa825a0-39e1-45b8-b4fa-5b3870d4c136

📥 Commits

Reviewing files that changed from the base of the PR and between 2d6f142 and 8ac8645.

📒 Files selected for processing (11)
  • src/GameServer/Bot/AI/BotSpotTravel.js
  • src/GameServer/Bot/AI/SpotService.js
  • src/GameServer/Bot/AI/States/HuntingState.js
  • src/GameServer/Bot/Population/BotLifeState.js
  • src/GameServer/Bot/Population/HotActivation.js
  • src/GameServer/Bot/Population/PopulationService.js
  • src/GameServer/Bot/Population/SpotProfiles.js
  • tests/test_bot_cold_travel_without_spot.js
  • tests/test_bot_hunting_ground_rules.js
  • tests/test_bot_population_scheduler_slices.js
  • tests/test_bot_population_state.js
🚧 Files skipped from review as they are similar to previous changes (8)
  • tests/test_bot_cold_travel_without_spot.js
  • tests/test_bot_population_scheduler_slices.js
  • src/GameServer/Bot/Population/SpotProfiles.js
  • tests/test_bot_population_state.js
  • src/GameServer/Bot/Population/HotActivation.js
  • src/GameServer/Bot/AI/SpotService.js
  • src/GameServer/Bot/Population/PopulationService.js
  • src/GameServer/Bot/AI/States/HuntingState.js

Comment thread src/GameServer/Bot/Population/BotLifeState.js
@pmbstyle
pmbstyle merged commit d014d5c into main Aug 6, 2026
4 checks passed
@pmbstyle
pmbstyle deleted the agent/bot-hunting-party-recruitment branch August 6, 2026 13:46
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.

1 participant