# ba-auto-daily implementation plan Personal Blue Archive **JP** daily-automation script. Controls the game via `xdotool` over a remote X11 session (Steam+Proton on `nik-gpu`), using OpenCV template/color matching for detection. No OCR is set up yet (see Prerequisites). Feature list and priority ordering below is derived from studying `~/repo/baas-reference` (pur1fying/blue_archive_auto_script, GPL-3.0, read-only reference — **not copied from**, reimplemented fresh in our own style). Its own default scheduler priority, complexity, and JP-relevance were used to rank the backlog. See "Reference" under each feature for the baas file(s) that describe the mechanic, for research purposes only. ## Status snapshot | Feature | Status | |---|---| | Mailbox claim | ✅ Done (`do_mailbox`) | | Cafe (pats + income) | ✅ Done (`do_cafe`) | | Everything else below | Not started | ## Prerequisites (cross-cutting, unblock multiple tiers) - **OCR.** Not set up. Needed for currency/ticket-count readouts, region/tab name search, and a few other read-a-number moments. When we get there, evaluate Tesseract vs PaddleOCR in the existing `~/.venvs/ba-auto-daily` venv. Until then, stick to features that are pure color-check / template-match. - **Auto-fight primitive.** A shared "start fight → max speed + auto-mode → detect win/lose" routine that Arena, and any future story/raid automation, all need. Build once, early, before Tier 3 combat features. Reference: `module/main_story.py` (`auto_fight`/`enter_battle`). --- ## Tier 1 — High priority, no OCR needed ### Stamina/AP sweep (free + task-menu power) Claim the daily free 10 AP purchase and the daily task-menu AP/pyroxene rewards. Pure color-check state detection, fixed clicks. High value: AP is capped and this is free currency/materials left on the table every day. Reference: `module/collect_daily_free_power.py`, `module/collect_daily_task_power.py`. ### Club/Group AP claim Claim 10 AP from the club/dorm menu. Trivial fixed click + color check. Reference: `module/group.py` (29 lines). ### Momo Talk (chat app conversations) Auto-complete unread chat conversations, including relationship-rank-up story beats, claim pyroxene. No OCR — pure pixel-column scanning state machine (reply bubble / "enter story" prompt detection by color). Runs on its own ~3h cadence like cafe. Moderate build effort but no new dependencies. Reference: `module/momo_talk.py` (183 lines, `getConversationState`). --- ## Tier 2 — Medium priority, sweep-style AP consumption These three share the same shape: buy tickets (optional), sweep N times per sub-area, detected mostly by color (a multi-pixel "sss/star-rank" signature, not OCR). Minor OCR only for optional coin-balance readouts — can hardcode/skip that part initially and just sweep until out of stamina/tickets. ### Commissions ("Special Task" / 委託) Two sub-dungeons (Base Defense = EXP, Item Retrieval = credits). Reference: `module/clear_special_task_power.py` (148 lines). ### Scrimmage (学院交流会) Three academies, ticket purchase available on JP. Reference: `module/scrimmage.py` (166 lines). ### Bounty ("Rewarded Task" / 悬赏通缉) Three sub-areas, ticket purchase (0–12). Needs a little OCR for bounty-coin balance if we want auto-refresh; otherwise skippable. Reference: `module/rewarded_task.py` (204 lines). ### Normal/Hard story AP sweep (re-clear already-cleared stages) Sweep already-cleared main-story stages by region/mission count to burn AP. Needs OCR for current-region-number + a fuzzy swipe-search over mission buttons — more OCR-dependent than the three above, so ranked after them. Reference: `module/explore_tasks/sweep_task.py`, `module/explore_tasks/task_utils.py`. --- ## Tier 3 — Needs real OCR investment Do these once OCR is actually set up. ### Battle Pass claim (JP-only feature upstream — relevant to us) Claim pass mission points + tier rewards. Simple template claim-flow; OCR only needed for the optional level/points stat readout (can stub that part). Reference: `module/collect_pass_reward.py` (146 lines). ### Common Shop + Tactical (Arena) Shop Auto-buy configured items, auto-refresh when affordable. OCR needed for currency balances and shop-tab name search. Reference: `module/shop/common_shop.py`, `module/shop/tactical_challenge_shop.py`, `module/shop/shop_utils.py`. ### Arena (PvP ladder) Fight until out of tickets or rank 1, claim season + daily rewards. Needs the Tier-1-prerequisite auto-fight primitive, plus OCR for ticket count and self/opponent level. High value (decays twice daily, at 06:00/20:00 reset) but gated on OCR + auto-fight both being ready. Reference: `module/arena.py` (173 lines). --- ## Tier 4 — Heavy investment, lower ROI (defer) ### Lesson / Schedule (affection farming via classes) Structurally the most complex non-crafting feature: fuzzy OCR region-name matching, per-region student-portrait templates, multi-page swipe search, and a bespoke isometric-grid pixel-sampling helper for locating a specific favorite student. A stripped-down "just pick the highest-affection lesson in a fixed region" version would be much cheaper than full favorite-student targeting — consider that subset first if we ever pick this up. Reference: `module/lesson.py` (615 lines). ### Crafting (自动制造) The single most complex feature in the reference project (1000+ lines): 3-phase material selection, priority-list + rarity-tier config, quantity-stepper OCR, filter/sort UI manipulation. Large one-time build cost for recurring but non-urgent value (crafting mats don't decay the way AP/tickets do). Reference: `module/create.py` (1028 lines). ### Main story / Normal-Hard story "push" (auto-clear next uncleared stage) Distinct from the Tier-1/2 "sweep already-cleared stages" — this is unlocking new content. baas ships ~920KB of hand-authored per-stage click/formation-swap JSON scripts for "grid mode"; "simple mode" (plain auto-fight, no positioning) is far cheaper but doesn't work on every stage. Only worth building incrementally, per-stage, on demand — not a batch feature. Reference: `module/main_story.py`, `module/explore_tasks/explore_task.py`. ### Group Story / Mini Story (side-plot cleanup) OCR-detect a "NEW" badge across a paged grid, clear each unread plot. Pure convenience, optional. Reference: `module/group_story.py`, `module/mini_story.py`. ### Event content (Activities: story/mission/challenge push) Shape mirrors Tier-2 sweep work, but the content is 100% ephemeral — a new JSON/script per event, expires when the event ends. Recommendation: only build the generic "event AP sweep" (reuses Tier-1/2 sweep logic almost as-is) as a standing capability; don't try to pre-build specific named events. Note also that per baas's own docs, current JP/Global events have mostly moved away from grid-walking challenges, so "challenge push" content increasingly needs manual play anyway — low automation ROI there specifically. Reference: `module/activities/activity_utils.py`, `module/sweep_activity.py`. --- ## Skip list (not relevant to this project) | Feature | Why skip | |---|---| | Total Assault (raid) | Stubbed/dead code upstream too (`return True` before any real logic) and disabled by default; low value to chase. | | Joint Firing Drill (综合战术测试) | Hard-disabled for JP server in baas's own code (`if self.server == "JP": return True`) despite being in their README — it's a no-op on JP regardless. | | De-clothes localization toggle | CN-only. | | Restart / refresh-uiautomator2 | Android/ADB housekeeping for baas's mobile control backend; not applicable to our PC/Steam/Proton setup. | | Auto-unfriend | Disabled by default upstream too; low value, mildly risky (deletes friends). | | Daily minigame dispatcher | Event-specific and changes every campaign — not a stable feature to pre-build. Handle ad hoc if/when a specific live minigame is worth automating. | --- ## Notes on cadence Several features are time-decaying rather than "any time" farmable, which should inform how often the script runs (cron/scheduler), not just build order: - Cafe income + Momo Talk: effectively continuous, ~3h internal cadence. - Arena: resets twice daily (06:00, 20:00 UTC). - Everything else: once-daily, JP/Global reset at 20:00 UTC (03:00 UTC+8).