fix(cafe): Resolve timing gap causing rank-up cutscene to freeze game during cron run
feat(logs): Add script to pull cron run logs from remote for local reading
This commit is contained in:
parent
3c47fabd87
commit
027e55f7a9
File diff suppressed because one or more lines are too long
@ -64,6 +64,26 @@ both fixed:
|
|||||||
confirm end-to-end, so treat as implemented-but-unverified until one
|
confirm end-to-end, so treat as implemented-but-unverified until one
|
||||||
happens naturally during a real cafe run (same caveat this file already
|
happens naturally during a real cafe run (same caveat this file already
|
||||||
carried for the original rank-up dismiss before it was live-confirmed).
|
carried for the original rank-up dismiss before it was live-confirmed).
|
||||||
|
|
||||||
|
A real rank-up happened naturally via cron (2026-07-16, reported live with a
|
||||||
|
screenshot of the game left stuck on the cutscene) and exposed a THIRD bug,
|
||||||
|
a timing gap rather than a threshold problem: _dismiss_rank_up_if_shown was
|
||||||
|
only ever called once, immediately after a pat, with no wait beforehand --
|
||||||
|
but the cutscene renders with its own client-side animation delay, so that
|
||||||
|
single check could catch the tail end of the still-normal room view (header
|
||||||
|
genuinely still visible in that instant) and conclude "clear" a beat before
|
||||||
|
the actual cutscene appeared. Confirmed live: the log showed the pat
|
||||||
|
printing successfully (i.e. the post-pat check passed), then the following
|
||||||
|
camera-pan drag produced no visible movement (dragging over a static
|
||||||
|
cutscene image), and the game was left stuck on the cutscene even after the
|
||||||
|
whole script finished -- navigation.return_to_home's generic cleanup also
|
||||||
|
failed to recover it, since this specific cutscene's background happens to
|
||||||
|
read under is_on_subscreen/is_modal_open's thresholds too (confirmed via a
|
||||||
|
live screenshot pixel-check: SUBSCREEN_HEADER_PROBE read (180,227,244), r=180
|
||||||
|
< the 200 threshold both checks need), so every "are we home" check
|
||||||
|
downstream falsely agreed nothing was wrong. Fixed by checking on every
|
||||||
|
_pat_current_view poll iteration instead of only right after a pat -- see
|
||||||
|
that function's own comment.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ba_auto import detector, navigation
|
from ba_auto import detector, navigation
|
||||||
@ -133,8 +153,30 @@ def _pat_current_view(driver, config):
|
|||||||
# nothing -- the old Bash loop (and an earlier version of this one) gave
|
# nothing -- the old Bash loop (and an earlier version of this one) gave
|
||||||
# up on the very first miss, which meant it essentially never farmed.
|
# up on the very first miss, which meant it essentially never farmed.
|
||||||
# Keep polling for the full budget instead of bailing early.
|
# Keep polling for the full budget instead of bailing early.
|
||||||
|
#
|
||||||
|
# Real-usage bug (2026-07-16): the rank-up check used to run only once,
|
||||||
|
# immediately after a pat, with no wait beforehand -- but the rank-up
|
||||||
|
# cutscene was confirmed live to render with its own client-side
|
||||||
|
# animation delay, so that single check could catch the tail end of the
|
||||||
|
# still-normal room view (header genuinely still visible in that instant)
|
||||||
|
# and conclude "clear" a beat before the actual cutscene appeared. Once
|
||||||
|
# that happened, nothing ever checked again: find_cafe_sparkle() can't
|
||||||
|
# tell "stuck on an undetected cutscene" apart from the ordinary
|
||||||
|
# "nothing to pat right now" case, so the loop just polled dead air for
|
||||||
|
# the rest of its budget, the following camera pan dragged over a static
|
||||||
|
# cutscene image (no visible movement), and even navigation.
|
||||||
|
# return_to_home's generic cleanup failed to recover afterward -- this
|
||||||
|
# exact cutscene's background happens to read under is_on_subscreen/
|
||||||
|
# is_modal_open's thresholds too, so every "are we home" check downstream
|
||||||
|
# falsely agreed nothing was wrong. Fixed by checking on EVERY poll
|
||||||
|
# iteration, not just right after a pat, so a delayed appearance is
|
||||||
|
# caught (and dismissed, via _dismiss_rank_up_if_shown's own Enter-press
|
||||||
|
# loop) on the next iteration, roughly a second later, instead of never.
|
||||||
patted = 0
|
patted = 0
|
||||||
for _ in range(config.CAFE_MAX_CLICKS_PER_ROOM):
|
for _ in range(config.CAFE_MAX_CLICKS_PER_ROOM):
|
||||||
|
if not _dismiss_rank_up_if_shown(driver, config):
|
||||||
|
print("[cafe] warning: cafe screen not confirmed (rank-up cutscene stuck?) -- stopping this view's pat loop rather than clicking blindly")
|
||||||
|
break
|
||||||
match = detector.find_cafe_sparkle()
|
match = detector.find_cafe_sparkle()
|
||||||
if match is None:
|
if match is None:
|
||||||
driver.wait(1)
|
driver.wait(1)
|
||||||
|
|||||||
10
plan.md
10
plan.md
@ -356,6 +356,16 @@ A related efficiency finding from the same review: `is_header_bar_visible`'s 8-p
|
|||||||
|
|
||||||
Both fixes deployed to nik-gpu; the reviewer independently pixel-verified `is_header_bar_visible` against real captured screenshots (`screenshots/cafe/room1.png`, `screenshots/cafe/student/04_*.png`) and found no false-negative risk against normal cafe/dialog screens. Neither fix has been re-confirmed against a fresh live rank-up or cooldown notice post-deploy — worth watching the next time either occurs naturally.
|
Both fixes deployed to nik-gpu; the reviewer independently pixel-verified `is_header_bar_visible` against real captured screenshots (`screenshots/cafe/room1.png`, `screenshots/cafe/student/04_*.png`) and found no false-negative risk against normal cafe/dialog screens. Neither fix has been re-confirmed against a fresh live rank-up or cooldown notice post-deploy — worth watching the next time either occurs naturally.
|
||||||
|
|
||||||
|
#### Phase 6 follow-up #6: rank-up cutscene stuck the game for real, via cron (2026-07-16)
|
||||||
|
|
||||||
|
Follow-up #5's fix got its "next time either occurs naturally" moment: the account's real `q4h` cron run (17:00 slot) hit a genuine rank-up mid-pat in room 2, and the user reported it live with a screenshot — the game left sitting on the rank-up cutscene (a light-blue triangular background, "絆ランクアップ!" banner, stat-increase card) well after the whole script had already exited.
|
||||||
|
|
||||||
|
The log showed the pat itself printed successfully (`[cafe] patted sparkle at (309, 634), score=0.995`), meaning `_dismiss_rank_up_if_shown`'s post-pat check had passed -- but the very next line, `[cafe] panned to leftmost extreme`, was confirmed by the user to have produced no visible movement, and the room's farming silently found nothing for the rest of the run. Root cause, diagnosed by reproducing the exact stuck state and pixel-checking it live: this is a **timing gap, not a threshold problem**. `_dismiss_rank_up_if_shown` only ever ran once, immediately after a pat, with no wait beforehand -- but the actual cutscene renders with its own client-side animation delay, so that single check could catch the tail end of the still-normal room view (header genuinely still visible in that instant) and conclude "clear" a beat before the real cutscene appeared. Once that happened, nothing checked again: `find_cafe_sparkle()` can't distinguish "stuck on an undetected cutscene" from the ordinary "nothing to pat right now" case, so `_pat_current_view` just polled dead air for the rest of its budget, and the following pan drag visibly did nothing (confirmed by the user) since the whole screen was a static cutscene image, not the room.
|
||||||
|
|
||||||
|
This also explained why the game was left genuinely stuck rather than self-healing via `navigation.return_to_home`'s generic end-of-task cleanup: a live pixel-check of the captured stuck screenshot found `SUBSCREEN_HEADER_PROBE` reading `(180,227,244)` -- r=180, just under the 200 threshold both `is_on_subscreen` and (by extension) `return_to_home`'s `_not_home` check need to detect "not home." This specific cutscene's background happens to read as "not a subscreen, no modal open" -- i.e. it falsely satisfies the exact same conditions as the true home screen -- so every "are we home" check downstream of the pat loop (the room-2 income claim, `run()`'s own final cleanup, and `return_to_home` itself) all falsely agreed nothing was wrong, and the whole `q4h` preset finished logging `OK` with the game actually stuck.
|
||||||
|
|
||||||
|
Fixed by moving the `_dismiss_rank_up_if_shown` check to the top of `_pat_current_view`'s loop, run on every iteration rather than only right after a pat -- a delayed cutscene appearance now gets caught (and dismissed via the function's own existing Enter-press retry loop) on the very next iteration, roughly a second later, instead of never. **Confirmed live**: reproduced the exact real stuck state left by the incident (the game was still sitting on it) and confirmed a single Enter -- the same action `_dismiss_rank_up_if_shown` already takes -- cleared it back to the real cafe room view, then `navigation.return_to_home` confirmed true home afterward. The per-iteration check itself has not yet been re-exercised against a fresh live rank-up trigger end-to-end (same "could not force one on demand" caveat follow-up #5 already carried).
|
||||||
|
|
||||||
### Phase 7: setup.sh update
|
### Phase 7: setup.sh update
|
||||||
|
|
||||||
**Status: Done — `setup.sh` deploys `ba_daily.py` and `ba_auto/`.** `scripts/ba_dailies_legacy.sh` and `scripts/detect_and_click.py` were deleted once mailbox and cafe both migrated off them (Phases 5–6); `setup.sh` no longer references either.
|
**Status: Done — `setup.sh` deploys `ba_daily.py` and `ba_auto/`.** `scripts/ba_dailies_legacy.sh` and `scripts/detect_and_click.py` were deleted once mailbox and cafe both migrated off them (Phases 5–6); `setup.sh` no longer references either.
|
||||||
|
|||||||
23
pull_logs.sh
Executable file
23
pull_logs.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Pulls ~/ba_logs/ (cron run logs -- daily.log, q4h.log, etc., see
|
||||||
|
# ba_cron_run.sh and CLAUDE.md's "Scheduled runs (cron)" section) from
|
||||||
|
# nik-gpu into this repo's scratchpad/ba_logs/ for local reading (e.g. in
|
||||||
|
# VS Code). Local dev tooling only, not part of the ba_dailies.sh
|
||||||
|
# game-automation launcher -- same category as setup.sh/clean_scratchpad.sh.
|
||||||
|
# Read-only on the remote side: never writes back to nik-gpu.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./pull_logs.sh [host]
|
||||||
|
#
|
||||||
|
# host defaults to nik-gpu (the ssh alias used throughout this project).
|
||||||
|
|
||||||
|
HOST="${1:-nik-gpu}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
DEST="$SCRIPT_DIR/scratchpad/ba_logs"
|
||||||
|
|
||||||
|
mkdir -p "$DEST"
|
||||||
|
rsync -av "$HOST:ba_logs/" "$DEST/"
|
||||||
|
|
||||||
|
echo "Synced $HOST:~/ba_logs/ -> $DEST"
|
||||||
Loading…
x
Reference in New Issue
Block a user