fix(baal_xp): reset the game-length clock when the leech lands back in town

The leech cycle leaves the bot's own game for a public one and comes back.
The controller's max_game_length breaker counts real game time, so the
clock can already be over budget the moment the cycle ends - and it would
kill the game before the next cycle starts. Reset it in on_end_run for
baal_xp.

Also: on char-select failure in the join phases, go home before
end_run (the character is stranded on the character screen otherwise),
and grade the cycle by whether recovery to the own game succeeded -
a cycle that left early (low HP, timer) is a success, only a broken
cycle (join/leave/recovery failure) is a failure.
This commit is contained in:
alexpolo1
2026-09-05 08:17:30 +02:00
parent 0faa31f3d8
commit d0d2a54999
2 changed files with 28 additions and 5 deletions
+18 -5
View File
@@ -984,6 +984,12 @@ class Bot:
return
if not self._curr_loc:
self._curr_loc = self._verify_town_location()
# The leech cycle ends in its own game, but the controller's
# max_game_length breaker counts real game time - and the bot's own
# game has been running since game start, so it can already be over
# budget the moment we land back in town. Reset the clock here or
# the controller kills the game before the next cycle starts.
self._game_stats.reset_game_timer()
set_pause_state(True)
self.trigger_or_stop("maintenance")
return
@@ -1905,6 +1911,7 @@ class Bot:
if not self._baal_xp_select_char():
self._game_stats.set_failure_reason("baal_xp: char select failed")
self._save_error_screenshot("baal_xp", "char_select_failed")
self._baal_xp_go_home()
self.trigger_or_stop("end_run")
return
@@ -1928,6 +1935,7 @@ class Bot:
if not self._baal_xp_select_char():
self._game_stats.set_failure_reason("baal_xp: char select failed")
self._save_error_screenshot("baal_xp", "char_select_failed")
self._baal_xp_go_home()
self.trigger_or_stop("end_run")
return
@@ -1990,13 +1998,18 @@ class Bot:
self._save_error_screenshot("baal_xp", "leave_failed")
# --- Phase 8: Recover to own game ---
self._baal_xp_go_home()
ok = self._recover_to_own_game()
if not ok:
self._game_stats.set_failure_reason("baal_xp: recovery to own game failed")
self._save_error_screenshot("baal_xp", "recovery_failed")
# Log run result
self._game_stats.log_run_finished("run_baal_xp", False, None, loot=[])
self._record_run_result("run_baal_xp", False)
# Log run result. A completed cycle is a success even when it left
# early (low HP, run over) - the XP was collected; only a broken
# cycle (join/leave/recovery failure) is a failure.
self._game_stats.log_run_finished("run_baal_xp", not ok, None, loot=[])
self._record_run_result("run_baal_xp", not ok)
self._game_stats.log_exp()
self._baal_xp_rearm(ok=True)
self._baal_xp_rearm(ok=ok)
self.trigger_or_stop("end_run")
except Exception as e:
import traceback
+10
View File
@@ -371,6 +371,16 @@ class GameStats:
else:
return time.time() - self._timer
def reset_game_timer(self):
"""Restart the game-length clock from now.
The leech cycle leaves the bot's own game for a public one and comes
back - the time spent in the public game is not stuck time in the
bot's game, and the controller's max_game_length breaker would
otherwise kill the game the moment the bot lands back in town."""
self._timer = time.time()
self._paused = False
def get_consecutive_runs_failed(self):
return self._consecutive_runs_failed