The scripts contained in this repository allow you to automatically play any gamemode on any map in Bloons Tower Defence 6.
This can be used for automatically farming monkey money, player xp, tower xp, medals, achievements or collection event rewards.
Additionally the scripts allow you to record your own playthroughs to a textual description which can be automatically replayed afterwards.
The scripts have only been tested on Windows.
The config files (list of maps, monkey upgrade costs) are currently set up for Bloons TD6 v46.0.
If Ninja Kiwi releases a new major version of Bloons TD6 and the repository is outdated you can easily update it yourself.
For more information refer to supporting new versions of Bloons TD6.
Please be aware Ninja Kiwi doesn't support modding or use of external scripts for automated farming and may flag or ban accounts as a result when using this or similar scripts (although this hasn't happend to any of my accounts yet).
- How the replay of a playthrough works
- Usage / Modes of operation
- Playing a specific playthrough
- Playing a random map
- Play a map with increased collection event rewards
- Play playthroughs that grant missing achievements
- Playing playthroughs that grant missing medals
- Play the most efficient maps for player xp farming
- Play the most efficient maps for monkey money farming
- Validate playthroughs
- Determine cost of each monkey, upgrade and hero
- Gamemode parameter
- Category parameter
- Map parameter
- Hero parameter
- Optional arguments
- Examples
- Pausing / Stopping execution
- Playing a specific playthrough
- Requirements / Installation
- Supported maps
- Recording playthroughs
- Additional scripts
- Supported resolutions
- Supporting new collection events
- Supporting new versions of Bloons TD6
- Known issues
Playthroughs consist of actions like placing or upgrading a monkey, each associated with a specific cost. The replay of a playthrough works by periodically taking screenshots of BTD6 to determine what menu you are in or how much money you have available. If there is more money available than required for the next action in the playthrough it performs the corresponding action. This repeats until the game is won, lost or all actions have been performed.
Outside of a playthrough the script is able to navigate through BTD6 e. g. to select a hero or map and gamemode.
The general command structure is py replay.py <mode> <mode arguments...> <flags>
Usage: py replay.py file <filename> [gamemode] [continue <(int start|-)> [until (int end)]] <flags>
Replays the specified file. Navigates to ingame if continue is not set.
If filename
contains /
or \
filename
is used as the path. otherwise the script lookes for filename
in own_playthroughs
, then in playthroughs
gamemode
can be specified to overwrite the gamemode in the files title. (e. g. py replay.py file dark_castle#chimps#2560x1440#noMK#noLL.btd6 medium -nomk
to play dark castle on medium using the recorded playthrough for chimps)
if continue is set:
- it is assumed you are already in the correct game
- the script starts with instruction start (0 for first instruction)
- if
start
=-
all instructions are executed before the game is started - if
until
is specified the script ends before instructionend
(e. g. start=0, end=1 -> only first instruction is executed) - continue is mostly useful for debugging playthroughs
flag -r
only works if continue
is not specified
Usage: py replay.py random [category] [gamemode] <flags>
Plays a random game from all available playthroughs (which fullfill the category and gamemode requirement if specified)
Combined with the -r
flag a playthrough is selected at random each iteration.
Usage: py replay.py chase <event> [category] [gamemode] <flags>
Chases increased rewards for the specified event. Currently supported events are:
totem
: Totem collection eventhalloween
: Halloween collection eventpresent
: Christmas collection eventeaster
: Easter collection eventindependence
: Independence day collection eventbirthday
: BTD6 Birthday collection event
If category is not provided it finds the map with increased rewards in expert category and if a playthrough is available plays it. If not it searches the advanced category and so on.
If category is provided only said category is searched.
Category and gamemode can be specified to restrict the considered playthroughs.
If there are no suitable playthroughs available the script exits.
To be implemented
e. g. so spiiicey ninja kiwi
- beat spice islands on alternate bloons rounds with only land towers
To be implemented
Usage: py replay.py xp [int n=1]
Plays a random playthrough out of the n
most efficient (in terms of xp/hour) playthroughs.
Efficiency is calculated using the average of win_times
in playthrough_stats.json
. This means new playthroughs need to be played at least once to get considered.
For some context: currently the most efficient of the included playthroughs is dark castle on chimps which will earn you about 800k XP/hour(given your game doesn't lag)
Usage: py replay.py mm [int n=1]
Plays a random playthrough out of the n
most efficient (in terms of monkey money/hour) playthroughs.
Efficiency is calculated using the average of win_times
in playthrough_stats.json
. This means new playthroughs need to be played at least once to get considered.
For some context: currently the most efficient of the included playthroughs is bloody puddles on hard which will earn you about 760 Monkey money/hour (given your game doesn't lag) (836 Monkey Money/Hour if you have mo' monkey money
unlocked).
Usage: py replay.py validate file <filename>
or py replay.py validate all [category] [gamemode]
Validates a or multiple playthroughs in regards to monkey positions by setting them up in sandbox mode and checking if all actions have been performed correctly. Validation is restricted to your screens resolution, different resolutions must be validated seperately.
When run as py replay.py validate all
all playthroughs will be validated. When appending the -nv
flag only non validated playthroughs will be validated!
This mode requires monkey knowledge to be disabled!
If used with file
parameter:
Validates playthrough filename
.
If used with all
parameter:
Validates all playthroughs which fullfill the category and gamemode requirement if specified.
-r
flag has no effect for this mode.
Usage: py replay.py costs [+heros]
Determines the cost of each monkey and each upgrade of each monkey. Additionally determines the base cost of each hero if +hero
is specified.
If +hero
is set all heros will be tested.
This mode requires monkey knowledge to be disabled!
This mode requires all upgrades to be unlocked!
Can be used after an update to BTD6 to automatically update towers.json
.
Creates a backup of the old towers.json
file under towers_backup.json
.
The gamemode
parameter can be one of the following:
easy
(for standard in easy difficulty)primary_only
deflation
medium
(for standard in medium difficulty)military_only
reverse
apopalypse
hard
(for standard in hard difficulty)magic_monkeys_only
double_hp_moabs
half_cash
alternate_bloons_rounds
impoppable
chimps
The category
parameter can be one of the following:
beginner
intermediate
advanced
expert
The map
parameter can be one of the following:
monkey_meadow
tree_stump
town_center
tinkerton
middle_of_the_road
one_two_tree
scrapyard
the_cabin
resort
skates
lotus_island
candy_falls
winter_park
carved
park_path
alpine_run
frozen_over
in_the_loop
cubism
four_circles
hedge
end_of_the_road
logs
luminous_cove
sulfur_springs
water_park
polyphemus
covered_garden
quarry
quiet_street
bloonarius prime
balance
encrypted
bazaar
adoras_temple
spring_spring
kartsndarts
moon_landing
haunted
downstream
firing_range
cracked
streambed
chutes
rake
spice_islands
last_resort
ancient_portal
castle_revenge
dark_path
erosion
midnight_mansion
sunken_columns
x_factor
mesa
geared
spillway
cargo
pats_pond
peninsula
high_finance
another_brick
off_the_coast
cornfield
underground
glacial_trail
dark_dungeons
sanctuary
ravine
flooded_valley
infernal
bloody_puddles
workshop
quad
dark_castle
muddy_puddles
ouch
The hero
parameter can be one of the following:
quincy
gwendolin
striker_jones
obyn_greenfoot
rosalia
captain_churchill
benjamin
ezili
pat_fusty
adora
admiral_brickell
etienne
sauda
psi
geraldo
the hero corvus
is currently not supported
Flag | Description |
---|---|
-r | repeat objective indefinitely (e. g. `py replay.py file dark_castle#chimps#2560x1440#noMK#noLL.btd6 -r` to repeatedly play the map dark castle on chimps) |
-ns | disable stats logging. if not disabled the number and duration of playthroughs will be logged to `playthrough_stats.json`. Some modes use this information to determine the most efficient playthrough for farming. Disabling is mainly for testing purposes. |
-mk | consider playthroughs with arbitrary monkey knowledge as a requirement. also adjust monkey pricing according to your monkey knowledge (`userconfig.json`) |
-nomk | ignore playthroughs with monkey knowledge as a requirement. also don't adjust monkey pricing according to your monkey knowledge (`userconfig.json`) |
-nv | include non validated playthroughs in selection. not recommended as non validated playthroughs might not work due to invalid monkey positions. |
-l | list all found playthroughs and exit. can only be used with modes other than `file` |
Play dark castle on chimps. Pricing in chimps is identical with and without monkey knowledge:
py replay.py file dark_castle#chimps#2560x1440#noMK#noLL.btd6 -mk
Indefinitely farm XP on the 3 most efficient maps:
py replay.py xp 3 -mk -r
Indefinitely farm XP on the 3 most efficient maps that don't require any monkey knowledge:
py replay.py xp 3 -nomk -r
Indefinitely farm monkey money on the most efficient map:
py replay.py mm -mk -r
Indefinitely farm increased totem collection event rewards on the most rewarding maps even considering playthroughs that aren't reproducable without monkey knowledge:
py replay.py chase totem -r -mk
Play a random map on double hp moabs in beginner category that doesn't require any monkey knowledge:
py replay.py random beginner double_hp_maobs -nomk
Validate all unvalidated playthroughs in category beginner:
py replay.py validate all beginner -nomk -nv
Validate playthrough file dark_castle#chimps#2560x1440#noMK#noLL.btd6
:
py replay.py validate file dark_castle#chimps#2560x1440#noMK#noLL.btd6 -nomk
While ctrl
is pressed or Bloons TD6 is not your active window the execution of the script will be paused.
Furthermore you can order the script to exit after finishing the current playthrough by pressing ctrl
and space
while in Bloons TD6.
You can immediately stop execution by sending SIGINT to the script (pressing ctrl
+ c
while in the command window the script is running in).
To run the scripts you must have Python 3 (3.5 or higher) (www.python.org) installed.
Aditionally all pip packages listed in requirements.txt
must be installed.
This can be achieved by running:
pip install -r requirements.txt --user
The required packages also include Tensorflow which requires additional DLLs (Microsoft C++ Redistributable for Visual Studio [...]) to run. When running replay.py for the first time Tensorflow will output an error and list what dlls are missing and where they can be downloaded from.
Additionally the python ahk
library requires AutoHotkey (www.autohotkey.com) to be installed.
For some reason keystrokes send using PyAutoGUI
don't get registered by BTD6, thats why the script also requires the ahk
library even if PyAutoGUI
theoretically provides the required functions.
Additionally some specific ingame settings are required:
- setting your ingame language to english (under settings -> language)
- BTD6 running at your screens native resolution and on your primary screen
- disabling any big/small tower or bloon effects (under settings -> extras)(they get unlocked by specific achievements, if not unlocked they are disabled)
- in the escape menu while ingame:
- placement mode: drag & drop
- game hints: off
- auto start: on (optional but recommended)
If you changed your keybinds for placing or upgrading towers, retargeting, monkey special or selling they should be reset or you need to specify them inside keybinds.json
.
Latter requires the python keyboard library names of the corresponding keys or their scancode in categories "monkeys", "path" and "recording". Scancodes are the safer option. You can find out the scancodes/names of keys by running log_keypresses.py
. This will print both values when pressing a key.
The entries in category "others" require the AHK Keynames.
When using the script in a mode other than file
configurating userconfig.json
is required so the script can tell which playthroughs you can play.
The most importants segments are heros
where you can specify whether you have a specific hero unlocked (true
= unlocked, false
= not unlocked), unlocked_maps
where you can specify whether you have a specific map unlocked (true
= unlocked, false
= not unlocked) and medals
where you can specify whether you have a specific medal for a specific map already (true
= medal acquired, false
= medal not acquired). The medals
section will be updated automatically when the script gets a new medal.
The default configuration has all maps and heros unlocked.
Due to not having a default hotkey assigned using the mermonkey requires setting its hotkey to o
or changing the hotkey in keybinds.json
.
Additionally you should make sure to move or ideally disable popups that may appear in the lower right corner of the screen (e. g. from Steam) as they might interfere with the script and cause you to lose playthroughs.
The following table lists which gamemodes for which maps have recorded playthroughs available.
By hovering over a listing you can see what monkeys (and upgrades) are required for the playthrough.
By clicking a listing you are redirected to the corresponding file to view it or copy its name for replaying.
Listings follow the following format:
Format: status, hero, comments/flags, native: <playthroughs native resolution>, tested: <resolutions the playthrough has been tested for>
Status:
- supported: playthrough works with Monkey Knowledge disabled
- with MK: playthrough uses arbitrary Monkey Knowledge, not necessarily reproducable
Hero: hero used for playthrough
Heroname
: heroHeroname
required-
: no hero used
Flags:
Flag | Meaning |
---|---|
* | lifes lost |
(*) | lifes lost without monkey knowledge, no lifes lost with specific monkey knowledge (mainly mana lives and free roadspikes) |
An italic listing means the corresponding playthrough is derived from a playthrough for an harder gamemode on the same map.
(1): Maps with changing monkey positions are currently not recordable/replayable in any mode other than deflation
(2): Maps with changing position and monkey accessibility are currently not recordable/replayable in any mode other than deflation
Playthroughs can be recorded using record_playthrough.py
.
Usage: py record_playthrough.py [-e]
-e
flag is used when you want to extend upon an existing playthrough file.
After starting the script you must specify which map, gamemode and hero you are using.
If you are not using a hero just specify any like quincy
.
After that you can switch to BTD6 and do the playthrough.
Actions are only recorded when BTD6 is your active window and your cursor is inside BTD6.
To place a monkey first select it in the GUI and hover to the position you want to place it at (to check whether it can be placed there). After that press escape to unselect the monkey and then press the keybind corresponding to the monkey you want to place and place it. When pressing the keybind the position of your cursor will be logged as the monkeys position.
If your keybinds differ from the default keybinds you will need to change them in keybinds.json
(see Keybinds).
To log the removal of an obstacle you must press the right shift button while at a position the obstacle is clickable from.
After finishing the recording (by pressing ctrl + c) you are prompted to enter the cost of each obstacle removal in the order they were removed.
The following operations all require a monkey to be selected. This can be done by pressing the left ctrl key while in proximity of the monkey to select. This will select the monkey closest to your cursors position. The name of the selected monkey will be printed in the console.
To upgrade a monkey you can, after selecting the monkey, simply press the key corresponding to the path you want to upgrade.
To retarget a monkey you can, after selecting the monkey, simply press the key corresponding to the right retarget arrow (defaults to tab) as many times as required.
For dartling and mortar monkeys retargeting requires a position. A retarget with a position can be logged by pressing space while pressing tab. This will use your cursors current position.
To activate/deactivate a monkeys monkey special (e. g. prioritize camo) you can, after selecting the monkey, simply press the corresponding key (defaults to page down).
To sell a monkey you can, after selecting the monkey, simply press the corresponding key (defaults to backspace). When replaying a recording a sell occurs once your current money + the money gained from this and all adjacent sells surpasses the money required for the next non selling action (which could be 0 for retargeting/monkey special). Ideally you want to avoid selling when using monkey knowledge as the sell could result in less money than expected (due to reduced cost, which isn't factored in)(i. e. your towers are sold before you can actually afford the next tower or upgrade).
To await a round you must press the left shift button.
Directly after the script will prompt you to enter the round you want to await. Entering something invalid aborts the creation of the await round entry. The specified round must be greater than 0 as well as any previously awaited round!
Monkeys in the playthrough file are named <type><number of monkeys of this type placed>
e. g. sniper0
for the first sniper monkey placed, sniper1
for the next one etc.
Types are:
dart
boomerang
bomb
tack
ice
glue
sniper
sub
buccaneer
ace
heli
mortar
dartling
wizard
super
ninja
alchemist
druid
farm
engineer
spike
village
beasthandler
mermonkey
To stop recording press ctrl
+ c
while in the console record_playthrough.py
is running in.
The playthrough file can be edited after recording (e. g. to correct/remove accidental keypresses). The corresponding file is saved under own_playthroughs/<map>#<gamemode>#<resolution>.btd6
(e. g. own_playthroughs/cornfield#hard#2560x1440.btd6
).
Valid entries in a file are:
- placing a monkey (e. g.
place ninja ninja0 at 1212, 641
or for herosplace etienne hero0 at 1212, 641
) - upgrading a monkey (e. g.
upgrade ninja0 path 0
) - retargeting a monkey (clicking the right retarget arrow once) (e. g.
retarget ninja0
) - retargeting a monkey to a position (e. g.
retarget dartling0 to 123, 321
) - activate/deactivate monkey special (e. g. prioritize camo) (e. g.
special ninja0
) - selling a monkey (e. g.
sell ninja0
) - removing an obstacle (e. g.
remove obstacle at 123, 321 for 500
) - awaiting a round (e. g.
round 27
) - specifing the gamespeed (
speed fast
orspeed slow
). The speed defaults tofast
.
Additionally you can specify a discount for an upgrade/placement by appending with <n>% discount
where n an integer between 0 and 100 (including 100 e. g. with the primary mentoring
upgrade for villages) representing the discount in percent. This may be useful when upgrading a village to monkey business
or monkey commerce
and the resulting discount is critical for the playthrough to work.
Note that discounts stack by simply being added (e. g. 2 Villages with monkey commerce
in radius result in a discount of 10%+5%+5% = 20%). E. g. a valid entry would be upgrade ninja0 path 2 with 20% discount
.
There are also several flags that can be used in the filename:
#noMK
- to specify no monkey knowledge was used#noLL
- no lives lost#noLLwMK
- no lives lost with arbitrary monkey knowledge (only#noLL
or#noLLwMK
)
a resulting filename could be: high_finance#hard#2560x1440#noMK#noLLwMK.btd6
for a playthrough of high finance on hard with no monkey knowledge required and no lives lost when using arbitrary monkey knowledge (probably mana lives or free roadspikes)
Playthroughs for contribution should be recorded with monkey knowledge disabled. Please specify whether this condition was met when contributing playthroughs.
Additionally playthroughs should ideally use popular screen resolutions (like 1920x1080, 2560x1440 or 3840x2160) as rescaled playthroughs may not work (due to impossible placements etc.).
If you want to contribute playthroughs you can do it by either forking the repository and creating a pull request with the playthrough files added or you can create an issue with the playthrough file content as a code block.
Due to a lack of hotkeys features like merging beast handlers or targeting beasts are currently unsupported. As a result tier 5 beast handlers can't be used, as they require merging.
The repository contains some additional scripts:
convert_playthrough.py
Usage: py convert_playthrough.py <filename> <resolution(e. g. 1920x1080)>
Converts playthrough filename
to the provided resolution and saves it under own_playthroughs/<filename>
but with replaced resolution.
Can be used to tweak positions in a converted playthrough that doesn't work out of the box.
make_screenshot.py
Usage: py make_screenshot.py
Takes a screenshot of your primary screen and saves it in the screenshots
folder. For taking screenshots required to support new resolutions.
convert_image_to_mask.py
Usage: py convert_image_to_mask.py <filename>
Takes a png image and converts all red (#FF0000) pixels to white, all other to black and saves it under the same filename with _masked
appended. Used internally for cv2.matchTemplate mask.
log_keypresses.py
Usage: py log_keypresses.py
Prints the data of key events including keyname and scancode. Used for changing keybinds.json
. Stop by pressing ctrl
+ c
.
generate_supported_maps_table.py
Usage py generate_supported_maps_table.py
Updates the table of supported playthroughs in README.md
by scaning the playthroughs
folder.
ocr_image.py
Usage py ocr_image.py <filename>
Outputs the detected balance and saves the relevant area of the image as seen by the programm under the same filename with _area
appended.
Currently only screen resolutions of 1920x1080
and 2560x1440
are supported. Supporting a resolution requires the images in the folder images/<resolution>
(as well as tested rescaled or native playthroughs).
Supporting a new collection event only requires adding a .png
image of the symbol on a map to the images/<resolution>/collection_events
folder. Similar to images/<resolution>/collection_events/totem.png
. The collection event name will be the filename without .png
.
Most changes that get introduced in updates can be incorporated by adapting the corresponding config files:
Update version.txt
to contain the new version.
Please be aware that balance changes in major as well as minor updates to BTD6 could cause the provided playthroughs to no longer work.
Regardless newly recorded playthroughs will work.
New Maps can be added by running insert_new_map.py
.
Usage: py insert_new_map.py "<name of the new map>" <before|after> "<name of adjacent map>"
e. g. py insert_new_map.py "Midnight mansion" before "Sunken columns"
This will update maps.json
by inserting the new map and shifting all following maps of the same category by one position.
The prices can be automatically updated by running the costs
mode.
Adding a new tower requires adding it to towers.json
-> monkeys
.
base
refers to the towers base costclass
describes where the tower can be placed (land
,water
orany
(meaning both, like pat futsy))upgrades
refer to the cost of each upgrade (cost on medium difficulty with monkey knowledge disabled)- (optional)
upgrade_confirmation
describes whether the upgrade has a confirmation dialog (currently only used for super monkeys)(no dialog if omitted)
Additionally you need to provide the corresponding hotkey in keybinds.json
.
The addition is only required if you plan to use said tower.
Adding a new tower requires adding it to towers.json
-> heros
.
base
refers to the towers base costclass
describes where the tower can be placed (land
,water
orany
(meaning both, like pat futsy))
Additionally you need to provide the coordinates in the hero selection menu in image_areas.json
for a resolution of 2560x1440.
If the hero shifts the positions of other heros the positions of affected heros will need to be changed as well.
If the hero selection menu gets reorganized for the 16th+ hero all coordinates will need to be updated.
If the GUI of BTD6 changes majorly you might need to recreate the screenshots in images/<resolution>
for your resolution or even redefine the characteristic areas in image_areas.json
for said screenshots. If you define a new resolution in image_areas.json
all attributes present in 2560x1440
must be defined!
- abilities can't be used as they require timing
- the price calculation currently doesn't fully factor in monkey knowledge. (currently only
hero favors
for reduced hero cost)