Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
test.png

# Local Python environment
.venv/

# Python cache
__pycache__/
*.pyc

# Development screenshot/debug output
development/cosmic_test/

# Local configuration / secrets
credentials.json
*.credentials.json
.env
.env.*

# Editor / OS files
.DS_Store
Thumbs.db
.vscode/
.idea/

# Python tooling
.pytest_cache/
.mypy_cache/
.coverage

# Temporary / backup files
*.bak
*.tmp
*~

# PyInstaller build output
build/
TotalBattleHelper.exe
346 changes: 317 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,332 @@
# Total Battle Automation

Total Battle is a terrible game that manipulates its players into spending as much money and time on it as possible.
This project contains some scripts intended to reduce the amount of time spent.
Automation tools for reducing repetitive tasks in Total Battle.

To maximise cross-platform applicability, the scripts are tailored to operate on the web version of the game, running in a browser such as Firefox.
Note that some browsers do not allow number inputs when for example selecting troops.
Sadly the web version of the game will crash relatively often.
To counter this, the scripts will try to refresh the game whenever they feel they got stuck.
The recommended interface is **TotalBattleHelper**, which provides a GUI for running Citadel and Crypt automation and opening the Citadel configuration tools.

## Crypting
The command-line interfaces remain available for testing, diagnostics, and advanced use.

The `crypt.py` script runs automatic crypting via the watchtower.
By default the script will recognise common crypts; use the `-t` flag to select rare or epic crypts.
Note that the watchtower needs to be aligned with this selection before running the script.
The automation interacts with the game visually, so the game must be visible and the expected UI elements must be available on screen.

The script should be started with Carter selected as the only captain while the game is on the worldmap, zoomed in to the maximum 125%.
It takes a careful approach to selecting crypts.
From the watchtower screen, a random one of the visible locations is chosen.
Once the location on the map is loaded, the script will find the location of a crypt according to the `-t` flag.
It will filter out any crypts that have pre-existing blue or red lines over them in order to not steal any crypts.
It will also refuse to march on any rare crypts that are already opened.
## TotalBattleHelper

Note that the crypt actually marched on may not be the one that was originally selected via the watchtower.
In particular, it may not be one of the same level.
TotalBattleHelper is the recommended way to run the automation.

You can still start it directly with Python:

```bash
python total_battle_helper.py
```

For normal day-to-day use, Linux and Windows can both be configured so TotalBattleHelper launches like a regular desktop application without opening a terminal.

### Linux Application Launcher

From the project directory, run the one-time installer:

```bash
python install_total_battle_helper_linux.py
```

This creates a user application entry for **TotalBattleHelper**. After installation:

1. Open the Applications menu.
2. Search for **TotalBattleHelper**.
3. Launch it once.
4. Pin that running application to the dock if desired.

The launcher uses the project's `.venv` Python environment and starts TotalBattleHelper with no terminal window.

### Windows Standalone EXE

Windows can build a standalone `TotalBattleHelper.exe` launcher with:

```powershell
.\build_total_battle_helper_windows.ps1
```

The build script uses PyInstaller from the project's `.venv` and creates:

```text
TotalBattleHelper.exe
```

in the project root.

The EXE can be launched directly or pinned to the Windows taskbar. It opens without a PowerShell or Command Prompt window while Citadel, Crypt, and tool subprocesses still use the project's `.venv\Scripts\python.exe`.

PyInstaller must be installed in the Windows virtual environment before the first build:

```powershell
python -m pip install pyinstaller
```

TotalBattleHelper provides four main sections:

- **Citadels** - run Citadel automation and select run options.
- **Crypts** - run Crypt automation and select Watchtower Crypt filter behavior.
- **Citadel Stacks** - open the Citadel stack configuration GUI.
- **Troop Catalog** - open the troop catalog and troop-ordering GUI.

An **Under Development** section contains useful tools that are not yet considered part of the fully polished production workflow. **Watch Exchange** is currently available there.

Automation output is displayed in the **Activity** area.

Only one Citadel or Crypt automation process can run from TotalBattleHelper at a time. While automation is running, the run settings are locked to prevent accidental changes.

The **Stop** button requests a graceful shutdown so the active automation can perform its normal cleanup before exiting.

### Citadel Controls

The Citadel panel provides:

- **Successful launches** - stop after this many successful Citadel launches. Leave blank to run without a launch-count limit.
- **Loss handling** - use each Citadel configuration or override it with Stop, Revive, Delete All, or Delete Silver.
- **Apply MAX march speedup** - enabled by default.
- **Verbose diagnostic output** - display detailed automation diagnostics.

Loss handling options:

- **Use Citadel Setting** - use the configured `loss_policy`.
- **Stop** - leave losses untouched and stop before another Citadel is launched.
- **Revive** - revive all outstanding losses.
- **Delete All** - permanently remove all outstanding losses.
- **Delete Silver** - permanently remove Silver Troops and revive remaining protected losses.

### Crypt Controls

The Crypt panel provides:

- **Successful launches** - stop after this many successful Crypt launches. Leave blank to run continuously.
- **Crypt Type** - Leave As Is, Common, Rare, or Epic.
- **Apply MAX march speedup** - enabled by default. Disable it to let Carter complete the march normally.
- **Verbose diagnostic output** - display detailed automation diagnostics.

**Leave As Is** keeps the current Watchtower Crypt filters unchanged.

Selecting **Common**, **Rare**, or **Epic** sets the Watchtower filters for that Crypt type.

When MAX march speedup is disabled, Carter is still tracked until his natural return. Another Crypt is not launched while Carter is still away.

## Crypts

`crypt.py` runs the production Crypt loop through the Watchtower.

```bash
# Run continuously
python crypt.py

# Stop after 10 successful Crypt launches
python crypt.py --count 10

# Select a specific Watchtower Crypt type
python crypt.py --type common
python crypt.py --type rare
python crypt.py --type epic

# Short form
python crypt.py -t rare

# Do not apply MAX march speedup
python crypt.py --no-speedup

# Show detailed diagnostic output
python crypt.py --verbose
python crypt.py -v

# Flags can be combined
python crypt.py --type rare --count 10 --no-speedup --verbose
```

If `--type` is omitted, the current Watchtower Crypt filters are left unchanged.

If `--type common`, `--type rare`, or `--type epic` is supplied, the automation selects that Crypt type in the Watchtower.

The Crypt loop finds a Crypt through the Watchtower, launches Carter, applies MAX march speedup by default, waits for Carter to return, and repeats. While waiting, it also clicks Clan Help when available.

With `--no-speedup`, MAX is not applied. Carter is still tracked until his return before another Crypt can be launched.

## Citadels

`citadel.py` runs the production Citadel loop.

```bash
# Run continuously
python citadel.py

# Stop after 10 successful launches
python citadel.py --count 10

# Use a different Citadel configuration
python citadel.py --config my_citadel_stacks.json

# Do not apply MAX march speedup
python citadel.py --no-speedup

# Override Citadel loss handling for this run
python citadel.py --loss stop
python citadel.py --loss revive
python citadel.py --loss delete
python citadel.py --loss silver

# Show detailed diagnostic output
python citadel.py --verbose
python citadel.py -v

# Flags can be combined
python citadel.py --count 10 --loss silver --verbose
python citadel.py --count 10 --no-speedup --loss revive --verbose
```

The Citadel loop finds a supported Citadel through the Watchtower, confirms its type, loads its configured troop stack, launches the attack, applies MAX march speedup by default, tracks the active march, handles configured losses, and repeats.

While a Citadel march is active, the automation continues checking for Clan Help.

For `revive`, `dismiss`, and `dismiss_silver` policies, it also periodically checks for outstanding Citadel losses while the march is still active. If losses are found, they are handled according to the selected policy, the automation returns to the World map, and tracking of the same active march continues.

For the `stop` policy, losses are deliberately left untouched while the march remains active. After the march finishes, outstanding losses are detected and the automation stops before launching another Citadel.

Citadel behavior is configured in `citadel_stacks.json`. Individual troop stacks are stored in `citadel_troops/`.

Currently supported Citadels:

- Cursed 20
- Cursed 25
- Elven 20
- Elven 25
- Elven 30

### Citadel Loss Policies

Each Citadel configuration has a `loss_policy`.

- `stop` - stop Citadel automation if outstanding losses are detected.
- `revive` - revive all outstanding losses before continuing.
- `dismiss` - permanently remove all outstanding losses before continuing.
- `dismiss_silver` - permanently remove Silver Troops, then revive any remaining protected losses such as mercenaries, monsters, Heroes, and Captains.

The configured policy is used normally. It can be overridden for an entire `citadel.py` run with `--loss`:

```bash
python citadel.py --loss stop
python citadel.py --loss revive
python citadel.py --loss delete
python citadel.py --loss silver
```

The command-line values map to the existing Citadel policies as follows:

- `--loss stop` -> `stop`
- `--loss revive` -> `revive`
- `--loss delete` -> `dismiss`
- `--loss silver` -> `dismiss_silver`

When `--loss` is supplied, it takes precedence over the `loss_policy` configured for individual Citadels for the duration of that run. Omitting `--loss` preserves normal per-Citadel configuration.

Examples:

```bash
# Run 18 Citadels and revive every loss
python citadel.py --count 18 --loss revive

# Permanently remove Silver Troops and revive protected losses
python citadel.py --count 18 --loss silver

# Permanently remove every outstanding loss
python citadel.py --count 18 --loss delete
```

## Citadel Stack Configuration

The easiest way to manage Citadel troop stacks is through **Citadel Stacks** in TotalBattleHelper.

The standalone Citadel stack GUI remains available:

```bash
python citadel_stack_gui.py
```

The troop catalog and troop ordering used by Citadel stacks can be managed through **Troop Catalog** in TotalBattleHelper.

The standalone troop catalog GUI remains available:

```bash
python troop_catalog_gui.py
```

`citadel_stack_tool.py` provides the command-line configuration interface.

```bash
# List configured Citadels
python citadel_stack_tool.py list

# Show a Citadel configuration and troop stack
python citadel_stack_tool.py show elven_30

# Set a troop amount
python citadel_stack_tool.py set elven_30 vulture7 5000

# Remove a troop from a stack
python citadel_stack_tool.py remove elven_30 vulture7

# Set the loss policy
python citadel_stack_tool.py policy elven_30 dismiss

# Enable or disable a Citadel
python citadel_stack_tool.py enable elven_30 on
python citadel_stack_tool.py enable elven_30 off

# Validate all Citadel configuration
python citadel_stack_tool.py validate
```

## Troop Selection

The `troops.py` script should be executed while on the troop selection window ahead of an attack.
It must be provided with the location of a JSON file that contains an object with unit names as its keys and numbers as its values.
The available unit names correspond to the images in the `samples/units/` directory.
Note that most lower level units are currently missing.
`troops.py` loads a troop selection from a JSON file while the Battle troop-selection screen is open.

## Chest Counter
```bash
python troops.py my_troops.json
```

The `chest_counter.py` script is an experimental chest counter implementation that has not been tested in production.
For each chest counted it outputs a JSON object on a single line, which can be processed by other software.
It will also regularly click the help button.
The JSON object maps troop names to quantities.

## Login

The `login.py` script will automatically login given a JSON file containing an object with `"username"` and `"password"` keys.
The idea was that this could be combined with other scripts to fully automate workflows running in for instance Xvfb, which would then allow multiple sessions on the same machine.
This concept could use some further thought and convenience scripts, which I may or may not add here later.
`login.py` can log into the game using a JSON credentials file containing `username` and `password`.

```bash
python login.py credentials.json

# Login and continue to the World map
python login.py --worldmap credentials.json

# Short form
python login.py -w credentials.json
```

## Other Tools

Files prefixed with `dev_` are retained development or manual-assist tools. They may be useful for testing, diagnostics, or partially automated workflows, but are not part of the primary production automation interface.

The project also contains sample-capture and development utilities, and experimental tools such as the chest counter. These are not part of the primary production automation interface.

## Citadel Hero Frame Requirement

Citadel automation requires the **standard/default Hero portrait frame**
while the automation is running.

Custom, decorative, or event Hero frames can extend visually into the
Hero selection-checkbox area on the Battle screen. This can interfere
with the image-based safety check that verifies whether the Hero is
selected and available before a Citadel march is prepared.

The Citadel automation verifies the Hero and all three Captain selection
slots before loading troops. A Citadel is allowed to proceed only when
all four slots are positively detected as selected.

If any Hero/Captain slot is still on a march, is not selected, or cannot
be classified confidently, the Citadel is not launched and the
automation recycles through the World map and Watchtower.

**Required setup:** Set the Hero portrait frame back to the
standard/default frame before running Citadel automation.
Loading