- Transitioned the project to a Python-first architecture, moving feature logic from Bash to Python. - Created a new `setup.sh` script to bootstrap the environment on `nik-gpu`, ensuring necessary tools are installed and setting up a Python virtual environment. - Updated project layout in `plan.md` to reflect the new structure and clarify the purpose of each component. - Established a reference mapping table for feature implementation based on the existing reference project. - Outlined a migration phase to transition existing Bash functionality to Python tasks.
505 lines
12 KiB
Markdown
505 lines
12 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code when working with code in this repository.
|
|
|
|
## What this project is
|
|
|
|
This repository is a personal Blue Archive JP daily-automation project.
|
|
|
|
It controls the real Blue Archive PC/Steam/Proton client running on a Linux machine named `nik-gpu`. The development machine is a MacBook named `nik-macbookair`.
|
|
|
|
The automation backend is local desktop control:
|
|
|
|
- `xdotool` for mouse/keyboard/window control
|
|
- `scrot` for screenshots
|
|
- Python/OpenCV for image matching and color/template detection
|
|
- OCR later, when needed
|
|
- no Android emulator control
|
|
- no ADB
|
|
- no uiautomator2
|
|
|
|
The reference project is located at:
|
|
|
|
```
|
|
~/repo/baas-reference/
|
|
```
|
|
|
|
That repository contains the full Blue Archive Auto Script implementation. It should be treated as the behavioral reference for this project.
|
|
|
|
## Core architecture decision
|
|
|
|
This project must be Python-first.
|
|
|
|
**Do not implement new Blue Archive automation logic in `ba_dailies.sh`.**
|
|
|
|
`ba_dailies.sh` is only a thin runtime/deployment launcher for convenience on `nik-gpu`.
|
|
|
|
All feature logic must live in Python.
|
|
|
|
The intended structure is:
|
|
|
|
```
|
|
ba-auto-daily/
|
|
├── ba_dailies.sh
|
|
├── ba_daily.py
|
|
├── ba_auto/
|
|
│ ├── __init__.py
|
|
│ ├── driver.py
|
|
│ ├── detector.py
|
|
│ ├── navigation.py
|
|
│ ├── config.py
|
|
│ ├── tasks/
|
|
│ │ ├── __init__.py
|
|
│ │ ├── mailbox.py
|
|
│ │ ├── cafe.py
|
|
│ │ ├── stamina.py
|
|
│ │ ├── group.py
|
|
│ │ └── ...
|
|
│ └── reference_notes/
|
|
│ └── mapping.md
|
|
├── assets/
|
|
├── screenshots/
|
|
├── scripts/
|
|
├── setup.sh
|
|
├── plan.md
|
|
└── CLAUDE.md
|
|
```
|
|
|
|
The exact layout can evolve, but the architectural rule should not change:
|
|
|
|
- Bash launches Python.
|
|
- Python owns automation logic.
|
|
- The reference repository guides feature behavior.
|
|
- Local driver primitives adapt that behavior to the PC/Steam/Proton setup.
|
|
|
|
## Reference-first rule
|
|
|
|
Before implementing any new feature, inspect the matching reference implementation in:
|
|
|
|
```
|
|
~/repo/baas-reference/module/
|
|
```
|
|
|
|
Do not start by inventing a Bash click sequence.
|
|
|
|
For every feature, first identify:
|
|
|
|
1. Which reference file implements it.
|
|
2. Which class/function contains the main control flow.
|
|
3. What the reference uses for state detection.
|
|
4. What the reference uses for retries/failure handling.
|
|
5. Which parts depend on Android/uiautomator2 and must be replaced.
|
|
6. Which parts can be ported directly as Python control flow.
|
|
7. Which local driver primitives are missing.
|
|
|
|
Then implement the feature in Python under:
|
|
|
|
```
|
|
ba_auto/tasks/
|
|
```
|
|
|
|
## Reference repository usage
|
|
|
|
The reference repository is **read-only**.
|
|
|
|
### Allowed
|
|
|
|
- read reference modules
|
|
- inspect control flow
|
|
- reuse architecture ideas
|
|
- reuse retry/state-machine structure
|
|
- reuse task decomposition ideas
|
|
- reuse constants/config concepts when appropriate
|
|
- write local notes describing how a reference module maps to this project
|
|
|
|
### Not allowed
|
|
|
|
- edit files in `~/repo/baas-reference/`
|
|
- reimplement a reference feature from scratch in Bash
|
|
- create a local solution that ignores the reference flow when a reference implementation already exists
|
|
|
|
## Two-machine architecture
|
|
|
|
Development happens on: `nik-macbookair`
|
|
|
|
Runtime happens on: `nik-gpu`
|
|
|
|
The Blue Archive client and X display live on `nik-gpu`.
|
|
|
|
Assume: (`DISPLAY=:0`, GDM `XAUTHORITY` under `/run/user/1000`)
|
|
|
|
The game runs under Steam/Proton on the Linux desktop.
|
|
|
|
There is no reliable local execution path on macOS. Anything that interacts with the game must be deployed to `nik-gpu`.
|
|
|
|
## Deployment model
|
|
|
|
During iteration, files are pushed from `nik-macbookair` to `nik-gpu`.
|
|
|
|
Typical paths on `nik-gpu`:
|
|
|
|
```
|
|
~/ba_dailies.sh
|
|
~/ba_daily.py
|
|
~/ba_auto/
|
|
~/ba_assets/
|
|
~/.venvs/ba-auto-daily/
|
|
```
|
|
|
|
The current setup may still contain older paths such as:
|
|
|
|
```
|
|
~/ba_scripts/detect_and_click.py
|
|
```
|
|
|
|
When refactoring, prefer consolidating Python code into `ba_auto/`.
|
|
|
|
`setup.sh` should bootstrap or update the runtime layout on `nik-gpu`.
|
|
|
|
For a fresh checkout on `nik-gpu`, run from the repo root:
|
|
|
|
```
|
|
./setup.sh
|
|
```
|
|
|
|
After initial setup, individual changes may be pushed with `scp` or `rsync`.
|
|
|
|
## Runtime dependencies on nik-gpu
|
|
|
|
These are host-level dependencies. Confirm they exist before assuming a bug is in the project code.
|
|
|
|
Required now:
|
|
|
|
- `xdotool`
|
|
- `scrot`
|
|
- `python3`
|
|
|
|
Required Python packages:
|
|
|
|
- `opencv-python` or `opencv-python-headless`
|
|
- `numpy`
|
|
|
|
Expected venv:
|
|
|
|
```
|
|
~/.venvs/ba-auto-daily/bin/python3
|
|
```
|
|
|
|
Quick check:
|
|
|
|
```
|
|
ssh nik-gpu "which xdotool scrot && ~/.venvs/ba-auto-daily/bin/python3 -c 'import cv2, numpy; print(cv2.__version__)'"
|
|
```
|
|
|
|
Future dependency: OCR engine, likely Tesseract or PaddleOCR.
|
|
|
|
Do not introduce OCR casually. Add it only when implementing a feature that actually needs OCR.
|
|
|
|
## Bash policy
|
|
|
|
`ba_dailies.sh` should be a thin launcher only.
|
|
|
|
Preferred shape:
|
|
|
|
```bash
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
VENV_PYTHON="${VENV_PYTHON:-$HOME/.venvs/ba-auto-daily/bin/python3}"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
exec "$VENV_PYTHON" "$SCRIPT_DIR/ba_daily.py" "$@"
|
|
```
|
|
|
|
Acceptable Bash responsibilities:
|
|
|
|
- choose Python binary
|
|
- set environment variables
|
|
- call Python entry point
|
|
- provide compatibility with old command names
|
|
- fail early if the Python entry point is missing
|
|
|
|
Not acceptable in Bash:
|
|
|
|
- feature state machines
|
|
- long click sequences
|
|
- OpenCV logic
|
|
- OCR logic
|
|
- retry loops for game states
|
|
- feature-specific navigation
|
|
- shop/sweep/battle logic
|
|
- new `do_<feature>` game automation functions
|
|
|
|
If an existing Bash function exists, migrate it to Python rather than extending it.
|
|
|
|
## Python entry point
|
|
|
|
The intended Python CLI entry point is:
|
|
|
|
```
|
|
ba_daily.py
|
|
```
|
|
|
|
It should support commands such as:
|
|
|
|
```
|
|
./ba_dailies.sh
|
|
./ba_dailies.sh mailbox
|
|
./ba_dailies.sh cafe
|
|
./ba_dailies.sh stamina
|
|
./ba_dailies.sh group
|
|
```
|
|
|
|
No argument should run the default daily flow.
|
|
|
|
Example default flow:
|
|
|
|
1. focus game
|
|
2. mailbox
|
|
3. cafe
|
|
4. future daily tasks
|
|
|
|
The CLI should dispatch into task modules under `ba_auto/tasks/`.
|
|
|
|
## Driver layer
|
|
|
|
Create and maintain a driver layer in:
|
|
|
|
```
|
|
ba_auto/driver.py
|
|
```
|
|
|
|
The driver layer should wrap the PC/Steam/Proton backend.
|
|
|
|
It should provide reusable primitives such as:
|
|
|
|
```
|
|
focus_game()
|
|
screenshot()
|
|
click(x, y)
|
|
double_click(x, y)
|
|
drag/swipe(start, end, duration)
|
|
keypress(key)
|
|
sleep/wait
|
|
wait_until(...)
|
|
color_at(...)
|
|
region_average_color(...)
|
|
template_match(...)
|
|
find_and_click_template(...)
|
|
```
|
|
|
|
Feature modules should not directly shell out to `xdotool` or `scrot` unless a driver primitive is missing and being added.
|
|
|
|
Prefer:
|
|
|
|
```python
|
|
driver.click(x, y)
|
|
```
|
|
|
|
over:
|
|
|
|
```python
|
|
subprocess.run(["xdotool", "click", ...])
|
|
```
|
|
|
|
This keeps the project close to the reference architecture while replacing only the backend-control layer.
|
|
|
|
## Detector layer
|
|
|
|
Image matching and color matching should live in `ba_auto/detector.py` or in clearly named helper classes/functions.
|
|
|
|
Existing logic from `scripts/detect_and_click.py` should be migrated into reusable Python functions.
|
|
|
|
The detector should support:
|
|
|
|
- screenshot input
|
|
- template matching
|
|
- threshold tuning
|
|
- masked matching
|
|
- click-offset handling
|
|
- debug image output to `./scratchpad`
|
|
|
|
Avoid one Python cold start per click attempt where possible. Prefer long-running Python task logic that can take repeated screenshots and click repeatedly from one process.
|
|
|
|
## Navigation layer
|
|
|
|
Common navigation should live in `ba_auto/navigation.py`.
|
|
|
|
Use this for shared flows such as:
|
|
|
|
- returning home
|
|
- opening main menu
|
|
- opening mailbox
|
|
- opening cafe
|
|
- opening shop
|
|
- opening lesson/schedule
|
|
- closing popups
|
|
- generic back/escape handling
|
|
|
|
Do not duplicate navigation click sequences inside every task if they can be shared.
|
|
|
|
## Task modules
|
|
|
|
Each feature should have a task module: `ba_auto/tasks/<feature>.py`
|
|
|
|
Example:
|
|
|
|
```
|
|
ba_auto/tasks/mailbox.py
|
|
ba_auto/tasks/cafe.py
|
|
ba_auto/tasks/group.py
|
|
ba_auto/tasks/stamina.py
|
|
```
|
|
|
|
Each task module should expose a clear function such as:
|
|
|
|
```
|
|
run(driver, config)
|
|
```
|
|
|
|
or:
|
|
|
|
```
|
|
run_mailbox(driver, config)
|
|
```
|
|
|
|
Keep task files feature-focused.
|
|
|
|
## Reference mapping notes
|
|
|
|
Maintain a mapping file at:
|
|
|
|
```
|
|
ba_auto/reference_notes/mapping.md
|
|
```
|
|
|
|
Before or during implementation of a feature, update the mapping.
|
|
|
|
Use this format:
|
|
|
|
| Local feature | Reference file | Reference functions/classes | Local file | Backend replacements | Status |
|
|
|---|---|---|---|---|---|
|
|
| Cafe | `module/cafe.py` or relevant file | `...` | `ba_auto/tasks/cafe.py` | uiautomator2 tap -> xdotool click, screenshot -> scrot/OpenCV | In progress |
|
|
|
|
## Working conventions
|
|
|
|
Use `./scratchpad` for temporary or intermediate files.
|
|
|
|
Examples:
|
|
|
|
- cropped calibration images
|
|
- debug screenshots
|
|
- annotated match results
|
|
- temporary investigation notes
|
|
|
|
Do not use `/tmp` or `/private/tmp` unless there is a strong reason.
|
|
|
|
`screenshots/` contains human reference captures. They are useful for calibration and documentation, but they are not necessarily automated test fixtures.
|
|
|
|
`assets/` contains local template images. These should be captured from the local game setup where possible.
|
|
|
|
## Testing and checks
|
|
|
|
Because the game only runs on `nik-gpu`, local macOS testing is limited.
|
|
|
|
Before deploying, run static/syntax checks locally:
|
|
|
|
```
|
|
bash -n ba_dailies.sh
|
|
python3 -m py_compile ba_daily.py
|
|
python3 -m py_compile ba_auto/*.py
|
|
python3 -m py_compile ba_auto/tasks/*.py
|
|
```
|
|
|
|
On `nik-gpu`, run real integration tests against the live game.
|
|
|
|
Example:
|
|
|
|
```
|
|
ssh nik-gpu "~/ba_dailies.sh cafe"
|
|
```
|
|
|
|
When debugging image matching, write debug images to `./scratchpad`.
|
|
|
|
## Existing features
|
|
|
|
Current project state before Python-first refactor:
|
|
|
|
- mailbox claim exists
|
|
- cafe affection/income exists
|
|
- cafe uses OpenCV template matching for sparkle detection
|
|
- existing Python helper is `scripts/detect_and_click.py`
|
|
- existing Bash entry point is `ba_dailies.sh`
|
|
|
|
Migration goal:
|
|
|
|
- preserve existing behavior
|
|
- move feature logic from Bash into Python
|
|
- keep `ba_dailies.sh` as launcher only
|
|
- make detection logic reusable
|
|
- prepare for future features by copying the reference project's structure where appropriate
|
|
|
|
## Known cafe gaps to verify during migration
|
|
|
|
When migrating cafe logic, verify these manually against the actual current behavior:
|
|
|
|
- whether student rotation popups are handled
|
|
- whether rank-up popups are handled
|
|
- whether the view is zoomed/centered before sparkle detection
|
|
- whether detection still works when text overlaps the student
|
|
- whether one Python process can handle repeated sparkle detection faster than repeated cold starts
|
|
- whether both cafe rooms are handled consistently
|
|
- whether cafe income claim is robust against popup timing
|
|
|
|
Do not assume the old Bash implementation handles these correctly.
|
|
|
|
## Anti-patterns
|
|
|
|
Do not:
|
|
|
|
- add new `do_<feature>` Bash functions
|
|
- build a giant Bash automation script
|
|
- recreate reference logic as fixed coordinate Bash click chains
|
|
- skip reading the reference module before implementing a feature
|
|
- put OCR in Bash
|
|
- put OpenCV state machines in Bash
|
|
- make every feature shell out independently to `xdotool`
|
|
- duplicate common navigation in every task
|
|
- copy reference image assets blindly
|
|
- edit `~/repo/baas-reference/`
|
|
- implement event-specific features before the generic reusable machinery exists
|
|
|
|
## Feature implementation workflow
|
|
|
|
For every new feature:
|
|
|
|
1. Read the relevant `~/repo/baas-reference/module/...` file.
|
|
2. Summarize the upstream feature flow in notes or comments.
|
|
3. Add/update the reference mapping table.
|
|
4. Identify missing local driver primitives.
|
|
5. Implement or improve those primitives in `ba_auto/driver.py` or `ba_auto/detector.py`.
|
|
6. Implement the feature in `ba_auto/tasks/<feature>.py`.
|
|
7. Add CLI dispatch in `ba_daily.py`.
|
|
8. Keep `ba_dailies.sh` unchanged unless launcher behavior changes.
|
|
9. Run syntax checks.
|
|
10. Deploy to `nik-gpu`.
|
|
11. Test against the live game.
|
|
12. Update `plan.md` status.
|
|
|
|
## Priority when uncertain
|
|
|
|
When uncertain, prefer this order:
|
|
|
|
1. Preserve existing working behavior.
|
|
2. Follow the reference project's control flow.
|
|
3. Keep logic in Python.
|
|
4. Add reusable driver primitives instead of feature-specific hacks.
|
|
5. Use local screenshots/assets only when backend differences require it.
|
|
6. Avoid large rewrites that do not move the project closer to reference-driven Python architecture.
|
|
|
|
## User preference
|
|
|
|
The user wants this project to be as close to the original Blue Archive Auto Script architecture as practical, without recreating logic that already exists.
|
|
|
|
The user specifically does not want Claude Code to keep converting feature work into Bash.
|
|
|
|
Respect that preference.
|