A Windows desktop application that drives Clash of Clans running inside MuMu Player 12. Gemini reads the screen; the app turns its answers into ADB taps and verifies the outcome on the next screenshot.
Other Languages: English | 繁體中文 | 简体中文
✨ What it does
- Detects MuMu Player 12 instances, starts the emulator and launches the game
- Captures the screen over ADB and asks Gemini what is on it, with structured replies validated through Pydantic
- Runs an agent loop that taps, swipes and goes back, re-observing after every step
- Imports village JSON exports and battle scripts, keeping unknown fields and unknown
data_ids instead of failing on them - Persists every agent command as a task, so an interrupted run is picked up again on the next start
- Stores the Gemini API key through Windows DPAPI, never in plain settings
Live battle tactics are deliberately out of scope: battle scripts are validated for army requirements and stop at a reserved handoff boundary.
📋 Requirements
- Windows. The app talks to
mumu-cli.exe, reads the registry throughwinregand calls DPAPI throughctypes.windll, none of which exist elsewhere - MuMu Player 12 with Clash of Clans installed, running at 1600x900
- A Gemini API key, entered in the app's settings tab
🚀 Install and run
From PyPI, without installing anything permanently:
Or as a regular install:
Prebuilt Windows executables are attached to every release.
🛠️ Local development
git clone https://github.com/Mai0313/ai_coc.git
cd ai_coc
uv sync --group test # install dependencies
uvx pre-commit install # install git hooks
uv run ai_coc # start the app
Two command-line hooks exist for smoke tests. --live-test captures a frame and asks Gemini to describe it; --agent-command=<text> types a command into the AI tab and runs it. Both save a proof screenshot when COC_LIVE_TEST_SCREENSHOT / COC_AGENT_SCREENSHOT point at a path.
🧰 Commands Reference
# Development
make help # List available make targets
make clean # Clean caches, artifacts and generated docs
make fmt # Run all pre-commit hooks
make test # Run pytest across the repository
make gen-docs # Generate docs from src/ and scripts/
# Dependencies (via uv)
make uv-install # Install uv on your system
uv add <pkg> # Add production dependency
uv add <pkg> --dev # Add development dependency
# Sync optional groups
uv sync --group dev # Install dev-only deps (pre-commit, poe, notebook)
uv sync --group test # Install test-only deps
uv sync --group docs # Install docs-only deps
🧱 Architecture
The three layers are directories, so an import that crosses them is visible in the import line:
- UI and orchestration —
ui/main_window.pyholds the window and every workflow,ui/workers.pythe thread-pool workers,ui/render.pythe Markdown and log rendering.cli.pyis onlymain() - Adapters —
adapters/mumu.py(emulator lifecycle),adapters/adb.py(every ADB call),adapters/ai.py(Gemini),adapters/secrets.py(DPAPI),adapters/database.py(SQLite) - Pure parsers —
parsers/village.py,parsers/battle.py
Every structured value is a Pydantic model, collected in models.py. Blocking calls go through a QThreadPool worker and come back to the UI thread as a signal.
Application state lives in ~/.ai_coc: the SQLite database, captured frames, imported account JSON and the DPAPI-protected key file.
📚 Documentation
Documentation is built with Zensical and auto-generated from source code via scripts/gen_docs.py.
uv sync --group docs
make gen-docs # generate markdown from source
uv run zensical serve # http://0.0.0.0:9987
make gen-docs recreates docs/, copies the three READMEs in, then runs gen_docs.py over ./src and ./scripts.
📦 Packaging and Distribution
Build artifacts with uv (wheel and sdist go to dist/):
Publish to PyPI (requires UV_PUBLISH_TOKEN):
Pushing a v* tag runs build_release.yml, which derives the version from git via dunamai, builds the wheel and sdist, publishes to PyPI, packages a Windows build with PyInstaller and attaches everything to the GitHub Release.
That build is --onedir by default: the zip holds the executable next to an _internal/ folder, which starts several seconds faster than a single-file build that has to unpack itself on every launch. Running the workflow by hand offers a package_mode choice if you want the single .exe instead.
🧭 Optional task runner (Poe the Poet)
Convenience tasks are defined under [tool.poe.tasks] in pyproject.toml and available after installing the dev group (uv sync --group dev) or via uvx:
uv run poe docs # generate + serve docs (requires dev group)
uv run poe gen # generate + deploy docs (gh-deploy) (requires dev group)
uv run poe main # run the app (same as uv run ai_coc)
# or ephemeral via uvx (no local install)
uvx poe docs
🔁 CI/CD Actions Overview
All workflows live in .github/workflows/.
-
Tests (
test.yml)- Trigger: pushes and pull requests to
mainorrelease/*(ignores md files) - Runs pytest on Python 3.12/3.13/3.14 with coverage and comments a summary
- Trigger: pushes and pull requests to
-
Code Quality Check (
code-quality-check.yml)- Trigger: pull requests
- Runs ruff and the rest of the pre-commit suite
-
Docs Deploy (
deploy.yml)- Trigger: push to
mainand tagsv* - Builds the
zensicalsite and publishes to GitHub Pages - Setup needed: enable GitHub Pages for the repo (Settings → Pages → Source: GitHub Actions)
- Trigger: push to
-
Build and Release (
build_release.yml)- Trigger: tags
v*push or manual workflow dispatch - Builds a Windows x64 executable with PyInstaller, plus the wheel and sdist
- Publishes to PyPI (requires the
UV_PUBLISH_TOKENsecret) and uploads every artifact to the GitHub Release
- Trigger: tags
-
Publish Docker Image (
build_image.yml)- Trigger: push to
mainand tagsv* - Builds and pushes an image to GHCR:
ghcr.io/<owner>/<repo>
- Trigger: push to
-
Release Drafter (
release_drafter.yml)- Trigger: push to
mainand PR events - Maintains a draft release based on Conventional Commits
- Trigger: push to
-
Code Scanning (
code_scan.yml)- Trigger: push and PR
- Runs gitleaks; the CodeQL job needs GitHub Advanced Security and stays skipped while the repo is private
-
Semantic Pull Request (
semantic-pull-request.yml)- Trigger: PR open/edit/sync
- Enforces Conventional Commit style PR titles
CI/CD Configuration Checklist
- Conventional commits for PR titles (enforced by the workflow)
- Set the
UV_PUBLISH_TOKENsecret to publish to PyPI (Settings → Secrets and variables → Actions) - Optional: enable GitHub Pages for docs deployment (Settings → Pages → Source: GitHub Actions)
- Container Registry permissions are handled automatically via
GITHUB_TOKEN
🤝 Contributing
- Open issues/PRs
- Follow the coding style (ruff, type hints)
- Use Conventional Commit messages and descriptive PR titles
📄 License
MIT — see LICENSE.