Showing preview only (1,458K chars total). Download the full file or copy to clipboard to get everything.
Repository: BurnySc2/python-sc2
Branch: develop
Commit: d8c3558a1ddd
Files: 256
Total size: 1.4 MB
Directory structure:
gitextract_5hf8q6mo/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── docker-ci.yml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── README.md
├── data/
│ ├── README.md
│ └── data.json
├── dockerfiles/
│ ├── Dockerfile
│ ├── README.md
│ ├── download_maps.sh
│ ├── test_docker_image.sh
│ └── test_new_python_candidate.sh
├── docs_generate/
│ ├── Makefile
│ ├── bot_ai/
│ │ └── index.rst
│ ├── client/
│ │ └── index.rst
│ ├── conf.py
│ ├── game_data/
│ │ └── index.rst
│ ├── game_info/
│ │ └── index.rst
│ ├── game_state/
│ │ └── index.rst
│ ├── ids/
│ │ └── index.rst
│ ├── index.rst
│ ├── make.bat
│ ├── pixel_map/
│ │ └── index.rst
│ ├── position/
│ │ └── index.rst
│ ├── protocol/
│ │ └── index.rst
│ ├── score/
│ │ └── index.rst
│ ├── text_files/
│ │ ├── docker.rst
│ │ └── introduction.rst
│ ├── unit/
│ │ └── index.rst
│ ├── unit_command/
│ │ └── index.rst
│ └── units/
│ └── index.rst
├── examples/
│ ├── __init__.py
│ ├── arcade_bot.py
│ ├── bot_vs_bot.py
│ ├── competitive/
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── bot.py
│ │ ├── ladderbots.json
│ │ └── run.py
│ ├── distributed_workers.py
│ ├── external_bot.py
│ ├── fastreload.py
│ ├── host_external_norestart.py
│ ├── observer_easy_vs_easy.py
│ ├── play_tvz.py
│ ├── protoss/
│ │ ├── __init__.py
│ │ ├── cannon_rush.py
│ │ ├── find_adept_shades.py
│ │ ├── threebase_voidray.py
│ │ └── warpgate_push.py
│ ├── simulate_fight_scenario.py
│ ├── terran/
│ │ ├── __init__.py
│ │ ├── cyclone_push.py
│ │ ├── mass_reaper.py
│ │ ├── onebase_battlecruiser.py
│ │ ├── proxy_rax.py
│ │ └── ramp_wall.py
│ ├── too_slow_bot.py
│ ├── watch_replay.py
│ ├── worker_rush.py
│ ├── worker_stack_bot.py
│ └── zerg/
│ ├── __init__.py
│ ├── banes_banes_banes.py
│ ├── expand_everywhere.py
│ ├── hydralisk_push.py
│ ├── onebase_broodlord.py
│ ├── worker_split.py
│ └── zerg_rush.py
├── generate_dicts_from_data_json.py
├── generate_id_constants_from_stableid.py
├── pyproject.toml
├── sc2/
│ ├── __init__.py
│ ├── action.py
│ ├── bot_ai.py
│ ├── bot_ai_internal.py
│ ├── cache.py
│ ├── client.py
│ ├── constants.py
│ ├── controller.py
│ ├── data.py
│ ├── data.pyi
│ ├── dicts/
│ │ ├── __init__.py
│ │ ├── generic_redirect_abilities.py
│ │ ├── unit_abilities.py
│ │ ├── unit_research_abilities.py
│ │ ├── unit_tech_alias.py
│ │ ├── unit_train_build_abilities.py
│ │ ├── unit_trained_from.py
│ │ ├── unit_unit_alias.py
│ │ └── upgrade_researched_from.py
│ ├── expiring_dict.py
│ ├── game_data.py
│ ├── game_info.py
│ ├── game_state.py
│ ├── generate_ids.py
│ ├── ids/
│ │ ├── __init__.py
│ │ ├── ability_id.py
│ │ ├── buff_id.py
│ │ ├── effect_id.py
│ │ ├── id_version.py
│ │ ├── unit_typeid.py
│ │ └── upgrade_id.py
│ ├── main.py
│ ├── maps.py
│ ├── observer_ai.py
│ ├── paths.py
│ ├── pixel_map.py
│ ├── player.py
│ ├── portconfig.py
│ ├── position.py
│ ├── power_source.py
│ ├── protocol.py
│ ├── proxy.py
│ ├── py.typed
│ ├── renderer.py
│ ├── sc2process.py
│ ├── score.py
│ ├── unit.py
│ ├── unit_command.py
│ ├── units.py
│ ├── versions.py
│ └── wsl.py
└── test/
├── Dockerfile
├── __init__.py
├── autotest_bot.py
├── battery_overcharge_bot.py
├── benchmark_array_creation.py
├── benchmark_bot_ai_init.py
├── benchmark_distance_two_points.py
├── benchmark_distances_cdist.py
├── benchmark_distances_points_to_point.py
├── benchmark_distances_units.py
├── benchmark_prepare_units.py
├── damagetest_bot.py
├── generate_pickle_files_bot.py
├── pickle_data/
│ ├── 16-BitLE.xz
│ ├── 2000AtmospheresAIE.xz
│ ├── AbiogenesisLE.xz
│ ├── AbyssalReefLE.xz
│ ├── AcidPlantLE.xz
│ ├── AcolyteLE.xz
│ ├── AcropolisLE.xz
│ ├── AncientCisternAIE.xz
│ ├── Artana.xz
│ ├── AscensiontoAiurLE.xz
│ ├── AutomatonLE.xz
│ ├── BackwaterLE.xz
│ ├── Bandwidth.xz
│ ├── BattleontheBoardwalkLE.xz
│ ├── BelShirVestigeLE.xz
│ ├── BerlingradAIE.xz
│ ├── BlackburnAIE.xz
│ ├── BlackpinkLE.xz
│ ├── BlueshiftLE.xz
│ ├── CactusValleyLE.xz
│ ├── CatalystLE.xz
│ ├── CeruleanFallLE.xz
│ ├── CrystalCavern.xz
│ ├── CuriousMindsAIE.xz
│ ├── CyberForestLE.xz
│ ├── DarknessSanctuaryLE.xz
│ ├── DeathAura506.xz
│ ├── DeathAuraLE.xz
│ ├── DefendersLandingLE.xz
│ ├── DigitalFrontier.xz
│ ├── DiscoBloodbathLE.xz
│ ├── DragonScalesAIE.xz
│ ├── DreamcatcherLE.xz
│ ├── EastwatchLE.xz
│ ├── Ephemeron.xz
│ ├── EphemeronLE.xz
│ ├── Equilibrium513AIE.xz
│ ├── EternalEmpire506.xz
│ ├── EternalEmpireLE.xz
│ ├── EverDream506.xz
│ ├── EverDreamLE.xz
│ ├── FractureLE.xz
│ ├── FrostLE.xz
│ ├── GlitteringAshesAIE.xz
│ ├── GoldenAura513AIE.xz
│ ├── GoldenWall506.xz
│ ├── GoldenWallLE.xz
│ ├── GoldenauraAIE.xz
│ ├── Gresvan513AIE.xz
│ ├── GresvanAIE.xz
│ ├── HardLead513AIE.xz
│ ├── HardwireAIE.xz
│ ├── HonorgroundsLE.xz
│ ├── IceandChrome506.xz
│ ├── IceandChromeLE.xz
│ ├── InfestationStationAIE.xz
│ ├── InsideAndOutAIE.xz
│ ├── InterloperLE.xz
│ ├── JagannathaAIE.xz
│ ├── KairosJunctionLE.xz
│ ├── KingsCoveLE.xz
│ ├── LightshadeAIE.xz
│ ├── MechDepotLE.xz
│ ├── MoondanceAIE.xz
│ ├── NeonVioletSquareLE.xz
│ ├── NewRepugnancyLE.xz
│ ├── NewkirkPrecinctTE.xz
│ ├── NightshadeLE.xz
│ ├── Oceanborn513AIE.xz
│ ├── OdysseyLE.xz
│ ├── OldSunshine.xz
│ ├── OxideAIE.xz
│ ├── PaladinoTerminalLE.xz
│ ├── ParaSiteLE.xz
│ ├── PersephoneAIE.xz
│ ├── PillarsofGold506.xz
│ ├── PillarsofGoldLE.xz
│ ├── PortAleksanderLE.xz
│ ├── PrimusQ9.xz
│ ├── ProximaStationLE.xz
│ ├── PylonAIE.xz
│ ├── RedshiftLE.xz
│ ├── Reminiscence.xz
│ ├── RomanticideAIE.xz
│ ├── RoyalBloodAIE.xz
│ ├── Sanglune.xz
│ ├── SequencerLE.xz
│ ├── SimulacrumLE.xz
│ ├── SiteDelta513AIE.xz
│ ├── StargazersAIE.xz
│ ├── StasisLE.xz
│ ├── Submarine506.xz
│ ├── SubmarineLE.xz
│ ├── TheTimelessVoid.xz
│ ├── ThunderbirdLE.xz
│ ├── TorchesAIE.xz
│ ├── Treachery.xz
│ ├── Triton.xz
│ ├── Urzagol.xz
│ ├── WaterfallAIE.xz
│ ├── WintersGateLE.xz
│ ├── WorldofSleepersLE.xz
│ ├── YearZeroLE.xz
│ └── ZenLE.xz
├── queries_test_bot.py
├── real_time_worker_production.py
├── replays/
│ ├── 20220223 - GAME 1 - Astrea vs SKillous - P vs P - Curious Minds LE.SC2Replay
│ ├── 20220224 - GAME 1 - Dream vs Spirit - T vs T - Curious Minds LE.SC2Replay
│ ├── 20220224 - GAME 1 - Serral vs Dark - Z vs Z - 2000 Atmospheres LE.SC2Replay
│ ├── 20220225 - GAME 2 - Maru vs ByuN - T vs T - Hardwire LE.SC2Replay
│ └── 20220227 - GAME 2 - Reynor vs Serral - Z vs Z - Berlingrad LE.SC2Replay
├── run_example_bots_vs_computer.py
├── run_example_bots_vs_each_other.py
├── test_directions.py
├── test_expiring_dict.py
├── test_pickled_data.py
├── test_pickled_ramp.py
├── test_replays.py
├── travis_test_script.py
└── upgradestest_bot.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/ci.yml
================================================
# If you change the name, change the link on the README.md for the badge too
name: Tests
on:
push:
paths:
- sc2/**
- examples/**
- test/**
- docs_generate/**
- .pre-commit-config.yaml
- generate_dicts_from_data_json.py
- generate_id_constants_from_stableid.py
- uv.lock
- pyproject.toml
- README.md
- .github/workflows/ci.yml
pull_request:
branches:
- master
- develop
env:
# Docker image version, see https://hub.docker.com/r/burnysc2/python-sc2-docker/tags
# This version should always lack behind one version behind the docker-ci.yml because it is possible that it doesn't exist
VERSION_NUMBER: "1.0.4"
# TODO Change to '3.14' when a new image has been pushed
LATEST_PYTHON_VERSION: "3.13"
LATEST_SC2_VERSION: "4.10"
jobs:
run_pre_commit_hook:
name: Run pre-commit hook
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ env.LATEST_PYTHON_VERSION }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.LATEST_PYTHON_VERSION }}
- name: Install uv
run: pip install uv
- name: Install dependencies
run: |
uv sync --frozen --no-cache --no-install-project
uv run pre-commit install
- name: Run pre-commit hooks
run: uv run pre-commit run --all-files --hook-stage pre-push
generate_dicts_from_data_json:
name: Generate dicts from data.json
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ env.LATEST_PYTHON_VERSION }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.LATEST_PYTHON_VERSION }}
- name: Install uv
run: pip install uv
- name: Install dependencies
run: |
uv sync --frozen --no-cache --no-install-project
uv run pre-commit install
- name: Run generate dicts
# Check if newly generated file is the same as existing file
# Run pre-commit hook to format files, always return exit code 0 to not end CI run
run: |
mv sc2/dicts sc2/dicts_old
uv run python generate_dicts_from_data_json.py
uv run pre-commit run --all-files --hook-stage pre-push || true
rm -rf sc2/dicts/__pycache__ sc2/dicts_old/__pycache__
- name: Upload generated dicts folder as artifact
uses: actions/upload-artifact@v4
with:
name: Generated_dicts
path: sc2/dicts
- name: Compare generated dict files
# Exit code will be 0 if the results of both commands are equal
run: |
[[ `ls sc2/dicts | md5sum` == `ls sc2/dicts_old | md5sum` ]]
run_pytest_tests:
# Run pytest tests on pickle files (pre-generated SC2 API observations)
name: Run pytest
needs: [run_pre_commit_hook, generate_dicts_from_data_json]
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
# Python 3.6 fails due to: https://www.python.org/dev/peps/pep-0563/
# If all type annotations were removed, this library should run in py3.6 and perhaps even 3.5
# Python 3.7 support has been dropped due to missing cached_property (new since Python 3.8) https://docs.python.org/3/library/functools.html#functools.cached_property
# Python 3.8 support has been dropped because numpy >=1.26.0 requires Python >=3.9 (this numpy version is required to run python 3.12)
# Python 3.9 support has been dropped since numpy >=2.1.0 (this numpy version is required to run python 3.13)
os: [macos-latest, windows-latest, ubuntu-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
id: setup-python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
run: pip install uv
- name: Install dependencies
run: uv sync --frozen --no-cache --no-install-project
- name: Run pytest
run: uv run python -m pytest test
# Run benchmarks
- name: Run benchmark benchmark_array_creation
run: uv run python -m pytest test/benchmark_array_creation.py
- name: Run benchmark benchmark_distance_two_points
run: uv run python -m pytest test/benchmark_distance_two_points.py
- name: Run benchmark benchmark_distances_cdist
run: uv run python -m pytest test/benchmark_distances_cdist.py
- name: Run benchmark benchmark_distances_points_to_point
run: uv run python -m pytest test/benchmark_distances_points_to_point.py
- name: Run benchmark benchmark_distances_units
run: uv run python -m pytest test/benchmark_distances_units.py
- name: Run benchmark benchmark_bot_ai_prepare_units
run: uv run python -m pytest test/benchmark_prepare_units.py
- name: Run benchmark benchmark_bot_ai_init
run: uv run python -m pytest test/benchmark_bot_ai_init.py
run_test_bots:
# Run test bots that download the SC2 linux client and run it
name: Run testbots linux
needs: [run_pytest_tests]
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
# Do not allow this test to cancel. Finish all jobs regardless of error
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
sc2-version: ["4.10"]
env:
IMAGE_NAME: burnysc2/python-sc2:local
steps:
# Copy data from repository
- uses: actions/checkout@v3
- name: Print directories and files
run: sudo apt-get install tree && tree
- name: Load and build docker image
# Build docker image from Dockerfile using specific python and sc2 version
env:
BUILD_ARGS: --build-arg PYTHON_VERSION=${{ matrix.python-version }} --build-arg SC2_VERSION=${{ matrix.sc2-version }}
run: docker build -f test/Dockerfile -t $IMAGE_NAME $BUILD_ARGS --build-arg VERSION_NUMBER=${{ env.VERSION_NUMBER }} .
- name: Run autotest_bot.py
# Run bot and list resulting files (replay file, stable_id.json)
run: |
docker run -i -d --name my_container --env 'PYTHONPATH=/root/python-sc2' $IMAGE_NAME
docker exec -i my_container bash -c "python test/travis_test_script.py test/autotest_bot.py"
docker exec -i my_container bash -c "tree"
docker rm -f my_container
- name: Run upgradestest_bot.py
run: |
docker run -i -d --name my_container --env 'PYTHONPATH=/root/python-sc2' $IMAGE_NAME
docker exec -i my_container bash -c "python test/travis_test_script.py test/upgradestest_bot.py"
docker exec -i my_container bash -c "tree"
docker rm -f my_container
- name: Run damagetest_bot.py
run: |
docker run -i -d --name my_container --env 'PYTHONPATH=/root/python-sc2' $IMAGE_NAME
docker exec -i my_container bash -c "python test/travis_test_script.py test/damagetest_bot.py"
docker exec -i my_container bash -c "tree"
docker rm -f my_container
- name: Run queries_test_bot.py
run: |
docker run -i -d --name my_container --env 'PYTHONPATH=/root/python-sc2' $IMAGE_NAME
docker exec -i my_container bash -c "python test/travis_test_script.py test/queries_test_bot.py"
docker exec -i my_container bash -c "tree"
docker rm -f my_container
run_example_bots:
# Run example bots against computer
name: Run example bots against computer
needs: [run_pytest_tests]
runs-on: ubuntu-latest
timeout-minutes: 60
env:
IMAGE_NAME: burnysc2/python-sc2-docker:local
steps:
# Copy data from repository
- uses: actions/checkout@v3
- name: Print directories and files
run: sudo apt-get install tree && tree
- name: Load and build docker image
# Build docker image from Dockerfile using specific python and sc2 version
env:
BUILD_ARGS: --build-arg PYTHON_VERSION=${{ env.LATEST_PYTHON_VERSION }} --build-arg SC2_VERSION=${{ env.LATEST_SC2_VERSION }}
run: docker build -f test/Dockerfile -t $IMAGE_NAME $BUILD_ARGS --build-arg VERSION_NUMBER=${{ env.VERSION_NUMBER }} .
- name: Run example bots vs computer
run: |
docker run -i -d --name my_container --env 'PYTHONPATH=/root/python-sc2' $IMAGE_NAME
docker exec -i my_container bash -c "python test/run_example_bots_vs_computer.py"
docker exec -i my_container bash -c "tree"
docker rm -f my_container
# TODO Fix in main.py "run_multiple_games" or "a_run_multiple_games" or "a_run_multiple_games_nokill"
# run_bot_vs_bot:
# # Run bot vs bot
# name: Run example bots against each other
# needs: [run_pytest_tests]
# timeout-minutes: 60
# env:
# IMAGE_NAME: burnysc2/python-sc2-docker:local
#
# steps:
# # Copy data from repository
# - uses: actions/checkout@v3
#
# - name: Print directories and files
# run: |
# sudo apt-get install tree
# tree
#
# - name: Load and build docker image
# # Build docker image from Dockerfile using specific python and sc2 version
# env:
# BUILD_ARGS: --build-arg PYTHON_VERSION=${{ env.LATEST_PYTHON_VERSION }} --build-arg SC2_VERSION=${{ env.LATEST_SC2_VERSION }}
# run: |
# docker build -f test/Dockerfile -t $IMAGE_NAME $BUILD_ARGS --build-arg VERSION_NUMBER=${{ env.VERSION_NUMBER }} .
#
# - name: Run example bots vs each other
# run: |
# docker run -i -d --name my_container --env 'PYTHONPATH=/root/python-sc2' $IMAGE_NAME
# docker exec -i my_container bash -c "python test/run_example_bots_vs_each_other.py"
# docker exec -i my_container bash -c "tree"
# docker rm -f my_container
run_coverage:
# Run and upload coverage report
# This coverage test does not cover the whole testing range, check /bat_files/rune_code_coverage.bat
name: Run coverage
needs: [run_test_bots, run_example_bots]
runs-on: ubuntu-latest
timeout-minutes: 30
env:
IMAGE_NAME: burnysc2/python-sc2-docker:local
steps:
- uses: actions/checkout@v3
- name: Load and build docker image
# Build docker image from Dockerfile using specific python and sc2 version
env:
BUILD_ARGS: --build-arg PYTHON_VERSION=${{ env.LATEST_PYTHON_VERSION }} --build-arg SC2_VERSION=${{ env.LATEST_SC2_VERSION }}
run: docker build -f test/Dockerfile -t $IMAGE_NAME $BUILD_ARGS --build-arg VERSION_NUMBER=${{ env.VERSION_NUMBER }} .
- name: Set up container
run: |
mkdir htmlcov
docker run -i -d \
-v $(pwd)/htmlcov:/root/python-sc2/htmlcov \
--name my_container \
--env 'PYTHONPATH=/root/python-sc2/' \
--entrypoint /bin/bash \
$IMAGE_NAME
echo "Install dev requirements because only non dev requirements exist in the docker image at the moment"
docker exec -i my_container bash -c "pip install uv \
&& uv sync --frozen --no-cache --no-install-project"
- name: Run coverage on tests
run: docker exec -i my_container bash -c "uv run pytest --cov=./"
- name: Run coverage on autotest_bot.py
run: docker exec -i my_container bash -c "uv run coverage run -a test/travis_test_script.py test/autotest_bot.py"
- name: Run coverage on upgradestest_bot.py
run: docker exec -i my_container bash -c "uv run coverage run -a test/travis_test_script.py test/upgradestest_bot.py"
- name: Run coverage on damagetest_bot.py
run: docker exec -i my_container bash -c "uv run coverage run -a test/travis_test_script.py test/damagetest_bot.py"
- name: Run coverage on queries_test_bot.py
run: docker exec -i my_container bash -c "uv run coverage run -a test/travis_test_script.py test/queries_test_bot.py"
# Bots might run differently long each time and create flucuations in code coverage - better to mock behavior instead
# - name: Run coverage on example bots
# run: |
# docker exec -i my_container bash -c "uv run coverage run -a test/run_example_bots_vs_computer.py"
- name: Generate xml coverage file
run: |
docker exec -i my_container bash -c "uv run coverage xml"
docker cp my_container:/root/python-sc2/coverage.xml $(pwd)/coverage.xml
- name: Generate html coverage files in htmlcov/ folder
run: |
docker exec -i my_container bash -c "uv run coverage html"
echo "Upload htmlcov folder because it was mounted in container, so it will be available in host machine"
- name: Upload htmlcov/ folder as artifact
uses: actions/upload-artifact@v4
with:
name: Coverage_report
path: htmlcov
run_radon:
name: Run radon complexity analysis
needs: [run_test_bots, run_example_bots]
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ env.LATEST_PYTHON_VERSION }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.LATEST_PYTHON_VERSION }}
- name: Install uv
run: pip install uv
- name: Install dependencies
run: uv sync --frozen --no-cache --no-install-project
- name: Run uv radon
run: uv run radon cc sc2/ -a -nb
release_to_github_pages:
name: GitHub Pages
needs: [run_test_bots, run_example_bots]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ env.LATEST_PYTHON_VERSION }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.LATEST_PYTHON_VERSION }}
- name: Install uv
run: pip install uv
- name: Install dependencies
run: uv sync --frozen --no-cache --no-install-project
- name: Build docs from scratch
run: |
echo "<meta http-equiv=\"refresh\" content=\"0; url=./docs/index.html\" />" > index.html
mkdir -p docs
cd docs_generate
uv run sphinx-build -a -E -b html . ../docs
- name: Debug-list all generated files
run: sudo apt-get install tree && tree
- name: Publish to Github Pages
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
uses: JamesIves/github-pages-deploy-action@releases/v4
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BASE_BRANCH: develop # The branch the action should deploy from.
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: docs # The folder the action should deploy.
release_to_pypi:
name: Pypi package release
needs: [run_test_bots, run_example_bots]
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ env.LATEST_PYTHON_VERSION }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.LATEST_PYTHON_VERSION }}
- name: Install uv
run: pip install uv
- name: Remove test folder to not include it in package
run: rm -rf test
- name: Build package
run: uv build
- name: Publish to pypi
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
continue-on-error: true
run: uv publish --token ${{ secrets.PYPI_PYTHON_SC2_TOKEN }}
================================================
FILE: .github/workflows/docker-ci.yml
================================================
name: Build and push Docker image
# Only run if Dockerfile or docker-ci.yml changed
on:
push:
paths:
- dockerfiles/**
- uv.lock
- pyproject.toml
- .github/workflows/docker-ci.yml
pull_request:
branches:
- master
- develop
env:
VERSION_NUMBER: "1.0.7"
LATEST_PYTHON_VERSION: "3.14"
LATEST_SC2_VERSION: "4.10"
EXPERIMENTAL_PYTHON_VERSION: "3.15"
jobs:
download_sc2_maps:
name: Download and cache sc2 maps
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Cache sc2 maps
uses: actions/cache@v4
id: cache-sc2-maps
with:
path: |
dockerfiles/maps
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
restore-keys: |
${{ runner.os }}-maps-
- name: Download sc2 maps
run: sh dockerfiles/download_maps.sh
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
run_test_docker_image:
name: Run test_docker_image.sh
needs: [download_sc2_maps]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Cache sc2 maps
uses: actions/cache@v4
id: cache-sc2-maps
with:
path: |
dockerfiles/maps
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
restore-keys: |
${{ runner.os }}-maps-
- name: Download sc2 maps
run: sh dockerfiles/download_maps.sh
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
- name: Run shell script
env:
VERSION_NUMBER: ${{ env.VERSION_NUMBER }}
PYTHON_VERSION: ${{ env.LATEST_PYTHON_VERSION }}
SC2_VERSION: ${{ env.LATEST_SC2_VERSION }}
run: sh dockerfiles/test_docker_image.sh
run_test_new_python_version:
name: Run test_new_python_candidate.sh
needs: [download_sc2_maps]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Cache sc2 maps
uses: actions/cache@v4
id: cache-sc2-maps
with:
path: |
dockerfiles/maps
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
restore-keys: |
${{ runner.os }}-maps-
- name: Download sc2 maps
run: sh dockerfiles/download_maps.sh
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
- name: Run shell script
continue-on-error: true
env:
VERSION_NUMBER: ${{ env.VERSION_NUMBER }}
PYTHON_VERSION: ${{ env.EXPERIMENTAL_PYTHON_VERSION }}
SC2_VERSION: ${{ env.LATEST_SC2_VERSION }}
run: sh dockerfiles/test_new_python_candidate.sh
docker_build:
name: Build docker image
needs: [download_sc2_maps]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
sc2-version: ["4.10"]
env:
IMAGE_NAME: burnysc2/python-sc2-docker:py_${{ matrix.python-version }}-sc2_${{ matrix.sc2-version }}
BUILD_ARGS: --build-arg PYTHON_VERSION=${{ matrix.python-version }} --build-arg SC2_VERSION=${{ matrix.sc2-version }}
steps:
- uses: actions/checkout@v3
- name: Cache sc2 maps
uses: actions/cache@v4
id: cache-sc2-maps
with:
path: |
dockerfiles/maps
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
restore-keys: |
${{ runner.os }}-maps-
- name: Download sc2 maps
run: sh dockerfiles/download_maps.sh
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
- name: Build docker image
run: docker build -f dockerfiles/Dockerfile -t $IMAGE_NAME-v$VERSION_NUMBER $BUILD_ARGS .
- name: Run test bots on image
run: |
echo "Start container, override the default entrypoint"
docker run -i -d \
--name test_container \
--env 'PYTHONPATH=/root/python-sc2/' \
--entrypoint /bin/bash \
$IMAGE_NAME-v$VERSION_NUMBER
echo "Install python-sc2"
docker exec -i test_container mkdir -p /root/python-sc2
docker cp pyproject.toml test_container:/root/python-sc2/
docker cp uv.lock test_container:/root/python-sc2/
docker cp sc2 test_container:/root/python-sc2/sc2
docker cp test test_container:/root/python-sc2/test
docker cp examples test_container:/root/python-sc2/examples
docker exec -i test_container bash -c "pip install uv \
&& cd python-sc2 && uv sync --frozen --no-cache --no-install-project"
echo "Run various test bots"
docker exec -i test_container bash -c "cd python-sc2 && uv run python test/travis_test_script.py test/autotest_bot.py"
docker exec -i test_container bash -c "cd python-sc2 && uv run python test/run_example_bots_vs_computer.py"
- name: Login to DockerHub
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Upload docker image
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
run: docker push $IMAGE_NAME-v$VERSION_NUMBER
- name: Upload docker image as latest tag
if: github.ref == 'refs/heads/develop' && github.event_name == 'push' && matrix.python-version == env.LATEST_PYTHON_VERSION && matrix.sc2-version == env.LATEST_SC2_VERSION
run: |
docker tag $IMAGE_NAME-v$VERSION_NUMBER burnysc2/python-sc2-docker:latest
docker push burnysc2/python-sc2-docker:latest
================================================
FILE: .gitignore
================================================
# Misc
.DS_Store
# Python + mypy + pytest
__pycache__/
*.pyc
.mypy_cache/
.pytest_cache/
build/
dist/
*.egg-info/
.cache/
# SC2 things
maps/
mini_games/
.hypothesis/
# Editors
.idea/
.vscode/
# Code coverage
.coverage
/htmlcov
docs/
.pyre
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
# Check yaml files like this one and github actions if they are valid
- id: check-yaml
# Check toml files like pyproject.toml if it is valid
- id: check-toml
# Check if python files are valid
- id: check-ast
- id: check-builtin-literals
- id: check-docstring-first
- id: debug-statements
# Check github action workflow files
- repo: https://github.com/sirosen/check-jsonschema
rev: 0.22.0
hooks:
- id: check-github-workflows
# Convert relative to absolute imports
- repo: https://github.com/MarcoGorelli/absolufy-imports
rev: v0.3.1
hooks:
- id: absolufy-imports
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
# Check for bad code
- id: python-no-eval
- id: python-no-log-warn
# Enforce type annotation instead of comment annotation
- id: python-use-type-annotations
- repo: local
hooks:
# Autoformat code
- id: ruff-format-check
name: Check if files are formatted
stages: [pre-push]
language: system
# Run the following command to fix:
# uv run ruff format .
entry: uv run ruff format . --check --diff
pass_filenames: false
- id: ruff-lint
name: Lint files
stages: [pre-push]
language: system
# Run the following command to fix:
# uv run ruff check . --fix
entry: uv run ruff check .
pass_filenames: false
- id: pyrefly
name: Static types checking with pyrefly
stages: [pre-push]
language: system
entry: uv run pyrefly check
pass_filenames: false
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Hannes Karppila
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](https://github.com/BurnySc2/python-sc2/actions)
[](https://codecov.io/gh/BurnySc2/python-sc2)
# A StarCraft II API Client for Python 3
An easy-to-use library for writing AI Bots for StarCraft II in Python 3. The ultimate goal is simplicity and ease of use, while still preserving all functionality. A really simple worker rush bot should be no more than twenty lines of code, not two hundred. However, this library intends to provide both high and low level abstractions.
**This library (currently) covers only the raw scripted interface.** At this time I don't intend to add support for graphics-based interfaces.
The [documentation can be found here](https://burnysc2.github.io/python-sc2/index.html).
For bot authors, looking directly at the files in the [sc2 folder](/sc2) can also be of benefit: bot_ai.py, unit.py, units.py, client.py, game_info.py and game_state.py. Most functions in those files have docstrings, example usages and type hinting.
I am planning to change this fork more radically than the main repository, for bot performance benefits and to add functions to help new bot authors. This may break older bots in the future, however I try to add deprecation warnings to give a heads up notification. This means that the [video tutorial made by sentdex](https://pythonprogramming.net/starcraft-ii-ai-python-sc2-tutorial/) is outdated and does no longer directly work with this fork.
For a list of ongoing changes and differences to the main repository of Dentosal, [check here](https://github.com/BurnySc2/python-sc2/issues/4).
## Installation
By installing this library you agree to be bound by the terms of the [AI and Machine Learning License](http://blzdistsc2-a.akamaihd.net/AI_AND_MACHINE_LEARNING_LICENSE.html).
For this fork, you'll need Python 3.9 or newer.
Install the pypi package:
```
pip install --upgrade burnysc2
```
or directly from develop branch:
```
pip install --upgrade --force-reinstall https://github.com/BurnySc2/python-sc2/archive/develop.zip
```
Both commands will use the `sc2` library folder, so you will not be able to have Dentosal's and this fork installed at the same time, unless you use virtual environments.
## StarCraft II
You'll need a StarCraft II executable. If you are running Windows or macOS, just install SC2 from [blizzard app](https://starcraft2.com/).
### Linux installation
You can install StarCraft II on Linux with [Wine](https://www.winehq.org/), [Lutris](https://lutris.net/games/battlenet/) or even the [Linux binary](https://github.com/Blizzard/s2client-proto#downloads), but the latter is headless so you cannot actually see the game.
Starcraft II can be directly installed from Battlenet once it is downloaded with Lutris.
By default, it will be installed here:
```
/home/burny/Games/battlenet/drive_c/Program Files (x86)/StarCraft II/
```
Next, set the following environment variables (either globally or within your development environment, e.g. Pycharm: `Run -> Edit Configurations -> Environment Variables`):
```
SC2PF=WineLinux
WINE=/usr/bin/wine
# Or a wine binary from lutris:
# WINE=/home/burny/.local/share/lutris/runners/wine/lutris-4.20-x86_64/bin/wine64
# Default Lutris StarCraftII Installation path:
SC2PATH='/home/burny/Games/battlenet/drive_c/Program Files (x86)/StarCraft II/'
```
### WSL
When running WSL in Windows, python-sc2 detects WSL by default and starts Windows Starcraft 2 instead of Linux Starcraft 2.
If you wish to instead have the game played in Linux, you can disable this behavior by setting `SC2_WSL_DETECT`
environment variable to "0". You can do this inside python with the following code:
```py
import os
os.environ["SC2_WSL_DETECT"] = "0"
```
WSL version 1 should not require any configuration. You may be asked to allow Python through your firewall.
When running WSL version 2 you need to supply the following environment variables so that your bot can connect:
```
SC2CLIENTHOST=<your windows IP>
SC2SERVERHOST=0.0.0.0
```
If you are adding these to your .bashrc, you may need to export your environment variables by adding:
```sh
export SC2CLIENTHOST
export SC2SERVERHOST
```
You can find your Windows IP using `ipconfig /all` from `PowerShell.exe` or `CMD.exe`.
## Maps
You will need maps to run the library.
#### Official maps
Official Blizzard map downloads are available from [Blizzard/s2client-proto](https://github.com/Blizzard/s2client-proto#downloads).
Extract these maps into their respective *subdirectories* in the SC2 maps directory.
e.g. `install-dir/Maps/Ladder2017Season1/`
#### Bot ladder maps
Maps that are run on the [SC2 AI Arena Ladder](https://aiarena.net/) can be downloaded [from the SC2 AI Arena Wiki](https://aiarena.net/wiki/bot-development/getting-started/#wiki-toc-maps).
**Extract these maps into the *root* of the SC2 maps directory** (otherwise ladder replays won't work).
e.g. `install-dir/Maps/AcropolisLE.SC2Map`
### Running
After installing the library, a StarCraft II executable, and some maps, you're ready to get started. Simply run a bot file to fire up an instance of StarCraft II with the bot running. For example:
```sh
python examples/protoss/cannon_rush.py
```
## Example
As promised, worker rush in less than twenty lines:
```python
from sc2 import maps
from sc2.player import Bot, Computer
from sc2.main import run_game
from sc2.data import Race, Difficulty
from sc2.bot_ai import BotAI
class WorkerRushBot(BotAI):
async def on_step(self, iteration: int):
if iteration == 0:
for worker in self.workers:
worker.attack(self.enemy_start_locations[0])
run_game(maps.get("Abyssal Reef LE"), [
Bot(Race.Zerg, WorkerRushBot()),
Computer(Race.Protoss, Difficulty.Medium)
], realtime=True)
```
This is probably the simplest bot that has any realistic chances of winning the game. I have ran it against the medium AI a few times, and once in a while, it wins.
You can find more examples in the [`examples/`](/examples) folder.
## API Configuration Options
The API supports a number of options for configuring how it operates.
### `unit_command_uses_self_do`
Set this to 'True' if your bot is issueing commands using `self.do(Unit(Ability, Target))` instead of `Unit(Ability, Target)`.
```python
class MyBot(BotAI):
def __init__(self):
self.unit_command_uses_self_do = True
```
### `raw_affects_selection`
Setting this to true improves bot performance by a little bit.
```python
class MyBot(BotAI):
def __init__(self):
self.raw_affects_selection = True
```
### `distance_calculation_method`
The distance calculation method:
- 0 for raw python
- 1 for scipy pdist
- 2 for scipy cdist
```python
class MyBot(BotAI):
def __init__(self):
self.distance_calculation_method: int = 2
```
### `game_step`
On game start or in any frame actually, you can set the game step. This controls how often your bot's `step` method is called.
__Do not set this in the \_\_init\_\_ function as the client will not have been initialized yet!__
```python
class MyBot(BotAI):
def __init__(self):
pass # don't set it here!
async def on_start(self):
self.client.game_step: int = 2
```
## Community - Help and support
You have questions but don't want to create an issue? Join the [SC2 AI Arena Discord server](https://discordapp.com/invite/zXHU4wM). Questions about this repository can be asked in text channel #python. There are discussions and questions about SC2 bot programming and this repository every day.
## Bug reports, feature requests and ideas
If you have any issues, ideas or feedback, please create [a new issue](https://github.com/BurnySc2/python-sc2/issues/new). Pull requests are also welcome!
## Contributing & style guidelines
Git commit messages use [imperative-style messages](https://stackoverflow.com/a/3580764/2867076), start with capital letter and do not have trailing commas.
To run pre-commit hooks (which run autoformatting and autosort imports) you can run
```sh
uv run pre-commit install
uv run pre-commit run --all-files --hook-stage pre-push
```
================================================
FILE: data/README.md
================================================
This data comes from dentosals tech tree and is only used to generate the dictionaries in /sc2/dicts/:
https://github.com/BurnySc2/sc2-techtree
If you see abilities missing, requirements wrong or anything else related to the /sc2/dicts/, please open and write an issue here:
https://github.com/BurnySc2/sc2-techtree/issues/new
================================================
FILE: data/data.json
================================================
{"Ability":[{"id":1,"name":"SMART","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":2,"name":"TAUNT_TAUNT","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":4,"name":"STOP_STOP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":5,"name":"STOP_HOLDFIRESPECIAL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":6,"name":"STOP_CHEER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":7,"name":"STOP_DANCE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":16,"name":"MOVE_MOVE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3794},{"id":17,"name":"PATROL_PATROL","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3795},{"id":18,"name":"HOLDPOSITION_HOLD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3793},{"id":19,"name":"SCAN_MOVE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3674},{"id":20,"name":"MOVE_TURN","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":23,"name":"ATTACK_ATTACK","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3674},{"id":24,"name":"ATTACK_ATTACKTOWARDS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":25,"name":"ATTACK_ATTACKBARRAGE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":26,"name":"EFFECT_SPRAY_TERRAN","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3684},{"id":28,"name":"EFFECT_SPRAY_ZERG","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3684},{"id":30,"name":"EFFECT_SPRAY_PROTOSS","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3684},{"id":36,"name":"BEHAVIOR_HOLDFIREON_GHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3688},{"id":38,"name":"BEHAVIOR_HOLDFIREOFF_GHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3689},{"id":40,"name":"MORPHTOINFESTEDTERRAN_INFESTEDTERRANS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":7,"produces_name":"INFESTORTERRAN"}}},{"id":42,"name":"EXPLODE_EXPLODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":45,"name":"FLEETBEACONRESEARCH_RESEARCHINTERCEPTORLAUNCHSPEEDUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":1,"upgrade_name":"CARRIERLAUNCHSPEEDUPGRADE"}}},{"id":46,"name":"RESEARCH_PHOENIXANIONPULSECRYSTALS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":99,"upgrade_name":"PHOENIXRANGEUPGRADE"}}},{"id":47,"name":"FLEETBEACONRESEARCH_TEMPESTRANGEUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":100,"upgrade_name":"TEMPESTRANGEUPGRADE"}}},{"id":48,"name":"FLEETBEACONRESEARCH_RESEARCHVOIDRAYSPEEDUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":288,"upgrade_name":"VOIDRAYSPEEDUPGRADE"}}},{"id":49,"name":"FLEETBEACONRESEARCH_TEMPESTRESEARCHGROUNDATTACKUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":297,"upgrade_name":"TEMPESTGROUNDATTACKUPGRADE"}}},{"id":74,"name":"FUNGALGROWTH_FUNGALGROWTH","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":76,"name":"GUARDIANSHIELD_GUARDIANSHIELD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":78,"name":"EFFECT_REPAIR_MULE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3685},{"id":110,"name":"NEXUSTRAINMOTHERSHIP_MOTHERSHIP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":10}}},{"id":140,"name":"FEEDBACK_FEEDBACK","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":142,"name":"EFFECT_MASSRECALL_STRATEGICRECALL","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3686},{"id":146,"name":"HALLUCINATION_ARCHON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":148,"name":"HALLUCINATION_COLOSSUS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":150,"name":"HALLUCINATION_HIGHTEMPLAR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":152,"name":"HALLUCINATION_IMMORTAL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":154,"name":"HALLUCINATION_PHOENIX","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":156,"name":"HALLUCINATION_PROBE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":158,"name":"HALLUCINATION_STALKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":160,"name":"HALLUCINATION_VOIDRAY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":162,"name":"HALLUCINATION_WARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":164,"name":"HALLUCINATION_ZEALOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":166,"name":"HARVEST_GATHER_MULE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3666},{"id":167,"name":"HARVEST_RETURN_MULE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3667},{"id":171,"name":"CALLDOWNMULE_CALLDOWNMULE","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":173,"name":"GRAVITONBEAM_GRAVITONBEAM","cast_range":4.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":174,"name":"CANCEL_GRAVITONBEAM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":175,"name":"BUILDINPROGRESSNYDUSCANAL_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":181,"name":"SPAWNCHANGELING_SPAWNCHANGELING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":12,"produces_name":"CHANGELING"}}},{"id":195,"name":"RALLY_BUILDING","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3673},{"id":199,"name":"RALLY_MORPHING_UNIT","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3673},{"id":203,"name":"RALLY_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3690},{"id":207,"name":"RALLY_NEXUS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3690},{"id":211,"name":"RALLY_HATCHERY_UNITS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3673},{"id":212,"name":"RALLY_HATCHERY_WORKERS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3690},{"id":216,"name":"RESEARCH_GLIALREGENERATION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":2,"upgrade_name":"GLIALRECONSTITUTION"}}},{"id":217,"name":"RESEARCH_TUNNELINGCLAWS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":3,"upgrade_name":"TUNNELINGCLAWS"}}},{"id":218,"name":"ROACHWARRENRESEARCH_ROACHSUPPLY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":120,"upgrade_name":"ROACHSUPPLY"}}},{"id":245,"name":"SAPSTRUCTURE_SAPSTRUCTURE","cast_range":0.25,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":249,"name":"NEURALPARASITE_NEURALPARASITE","cast_range":8.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":250,"name":"CANCEL_NEURALPARASITE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":251,"name":"EFFECT_INJECTLARVA","cast_range":0.10009765625,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":253,"name":"EFFECT_STIM_MARAUDER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3675},{"id":255,"name":"SUPPLYDROP_SUPPLYDROP","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":263,"name":"RESEARCH_ANABOLICSYNTHESIS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":88,"upgrade_name":"ANABOLICSYNTHESIS"}}},{"id":265,"name":"RESEARCH_CHITINOUSPLATING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":4,"upgrade_name":"CHITINOUSPLATING"}}},{"id":295,"name":"HARVEST_GATHER_SCV","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3666},{"id":296,"name":"HARVEST_RETURN_SCV","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3667},{"id":298,"name":"HARVEST_GATHER_PROBE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3666},{"id":299,"name":"HARVEST_RETURN_PROBE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3667},{"id":301,"name":"ATTACKWARPPRISM_ATTACKWARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":302,"name":"ATTACKWARPPRISM_ATTACKTOWARDS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":303,"name":"ATTACKWARPPRISM_ATTACKBARRAGE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":304,"name":"CANCEL_QUEUE1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":305,"name":"CANCELSLOT_QUEUE1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":306,"name":"CANCEL_QUEUE5","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":307,"name":"CANCELSLOT_QUEUE5","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":308,"name":"CANCEL_QUEUECANCELTOSELECTION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":309,"name":"CANCELSLOT_QUEUECANCELTOSELECTION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":312,"name":"CANCEL_QUEUEADDON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":313,"name":"CANCELSLOT_ADDON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":314,"name":"CANCEL_BUILDINPROGRESS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":315,"name":"HALT_BUILDING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3660},{"id":316,"name":"EFFECT_REPAIR_SCV","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3685},{"id":318,"name":"TERRANBUILD_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":18,"produces_name":"COMMANDCENTER"}}},{"id":319,"name":"TERRANBUILD_SUPPLYDEPOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":19,"produces_name":"SUPPLYDEPOT"}}},{"id":320,"name":"TERRANBUILD_REFINERY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"BuildOnUnit":{"produces":20,"produces_name":"REFINERY"}}},{"id":321,"name":"TERRANBUILD_BARRACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":21,"produces_name":"BARRACKS"}}},{"id":322,"name":"TERRANBUILD_ENGINEERINGBAY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":22,"produces_name":"ENGINEERINGBAY"}}},{"id":323,"name":"TERRANBUILD_MISSILETURRET","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":23,"produces_name":"MISSILETURRET"}}},{"id":324,"name":"TERRANBUILD_BUNKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":24,"produces_name":"BUNKER"}}},{"id":326,"name":"TERRANBUILD_SENSORTOWER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":25,"produces_name":"SENSORTOWER"}}},{"id":327,"name":"TERRANBUILD_GHOSTACADEMY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":26,"produces_name":"GHOSTACADEMY"}}},{"id":328,"name":"TERRANBUILD_FACTORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":27,"produces_name":"FACTORY"}}},{"id":329,"name":"TERRANBUILD_STARPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":28,"produces_name":"STARPORT"}}},{"id":331,"name":"TERRANBUILD_ARMORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":29,"produces_name":"ARMORY"}}},{"id":333,"name":"TERRANBUILD_FUSIONCORE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":30,"produces_name":"FUSIONCORE"}}},{"id":348,"name":"HALT_TERRANBUILD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3660},{"id":380,"name":"EFFECT_STIM_MARINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3675},{"id":382,"name":"BEHAVIOR_CLOAKON_GHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3676},{"id":383,"name":"BEHAVIOR_CLOAKOFF_GHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3677},{"id":386,"name":"MEDIVACHEAL_HEAL","cast_range":4.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":388,"name":"SIEGEMODE_SIEGEMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":32,"produces_name":"SIEGETANKSIEGED"}}},{"id":390,"name":"UNSIEGE_UNSIEGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":33,"produces_name":"SIEGETANK"}}},{"id":392,"name":"BEHAVIOR_CLOAKON_BANSHEE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3676},{"id":393,"name":"BEHAVIOR_CLOAKOFF_BANSHEE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3677},{"id":394,"name":"LOAD_MEDIVAC","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":396,"name":"UNLOADALLAT_MEDIVAC","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3669},{"id":397,"name":"UNLOADUNIT_MEDIVAC","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3796},{"id":399,"name":"SCANNERSWEEP_SCAN","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":401,"name":"YAMATO_YAMATOGUN","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":403,"name":"MORPH_VIKINGASSAULTMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":34,"produces_name":"VIKINGASSAULT"}}},{"id":405,"name":"MORPH_VIKINGFIGHTERMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":35,"produces_name":"VIKINGFIGHTER"}}},{"id":407,"name":"LOAD_BUNKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":408,"name":"UNLOADALL_BUNKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3664},{"id":410,"name":"UNLOADUNIT_BUNKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3796},{"id":412,"name":"COMMANDCENTERTRANSPORT_COMMANDCENTERTRANSPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":413,"name":"UNLOADALL_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3664},{"id":415,"name":"UNLOADUNIT_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3796},{"id":416,"name":"LOADALL_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3663},{"id":417,"name":"LIFT_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3679,"target":{"Morph":{"produces":36,"produces_name":"COMMANDCENTERFLYING"}}},{"id":419,"name":"LAND_COMMANDCENTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3678,"target":{"MorphPlace":{"produces":18,"produces_name":"COMMANDCENTER"}}},{"id":421,"name":"BUILD_TECHLAB_BARRACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3682,"target":{"BuildInstant":{"produces":37}}},{"id":422,"name":"BUILD_REACTOR_BARRACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3683,"target":{"BuildInstant":{"produces":38}}},{"id":451,"name":"CANCEL_BARRACKSADDON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":452,"name":"LIFT_BARRACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3679,"target":{"Morph":{"produces":46,"produces_name":"BARRACKSFLYING"}}},{"id":454,"name":"BUILD_TECHLAB_FACTORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3682,"target":{"BuildInstant":{"produces":39}}},{"id":455,"name":"BUILD_REACTOR_FACTORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3683,"target":{"BuildInstant":{"produces":40}}},{"id":484,"name":"CANCEL_FACTORYADDON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":485,"name":"LIFT_FACTORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3679,"target":{"Morph":{"produces":43,"produces_name":"FACTORYFLYING"}}},{"id":487,"name":"BUILD_TECHLAB_STARPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3682,"target":{"BuildInstant":{"produces":41}}},{"id":488,"name":"BUILD_REACTOR_STARPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3683,"target":{"BuildInstant":{"produces":42}}},{"id":517,"name":"CANCEL_STARPORTADDON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":518,"name":"LIFT_STARPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3679,"target":{"Morph":{"produces":44,"produces_name":"STARPORTFLYING"}}},{"id":520,"name":"LAND_FACTORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3678,"target":{"MorphPlace":{"produces":27,"produces_name":"FACTORY"}}},{"id":522,"name":"LAND_STARPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3678,"target":{"MorphPlace":{"produces":28,"produces_name":"STARPORT"}}},{"id":524,"name":"COMMANDCENTERTRAIN_SCV","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":45,"produces_name":"SCV"}}},{"id":554,"name":"LAND_BARRACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3678,"target":{"MorphPlace":{"produces":21,"produces_name":"BARRACKS"}}},{"id":556,"name":"MORPH_SUPPLYDEPOT_LOWER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":47,"produces_name":"SUPPLYDEPOTLOWERED"}}},{"id":558,"name":"MORPH_SUPPLYDEPOT_RAISE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":19,"produces_name":"SUPPLYDEPOT"}}},{"id":560,"name":"BARRACKSTRAIN_MARINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":48,"produces_name":"MARINE"}}},{"id":561,"name":"BARRACKSTRAIN_REAPER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":49,"produces_name":"REAPER"}}},{"id":562,"name":"BARRACKSTRAIN_GHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":50,"produces_name":"GHOST"}}},{"id":563,"name":"BARRACKSTRAIN_MARAUDER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":51,"produces_name":"MARAUDER"}}},{"id":590,"name":"FACTORYTRAIN_FACTORYTRAIN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":0,"produces_name":"Unknown"}}},{"id":591,"name":"FACTORYTRAIN_SIEGETANK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":33,"produces_name":"SIEGETANK"}}},{"id":594,"name":"FACTORYTRAIN_THOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":52,"produces_name":"THOR"}}},{"id":595,"name":"FACTORYTRAIN_HELLION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":53,"produces_name":"HELLION"}}},{"id":596,"name":"TRAIN_HELLBAT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":484,"produces_name":"HELLIONTANK"}}},{"id":597,"name":"TRAIN_CYCLONE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":692,"produces_name":"CYCLONE"}}},{"id":614,"name":"FACTORYTRAIN_WIDOWMINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":498,"produces_name":"WIDOWMINE"}}},{"id":620,"name":"STARPORTTRAIN_MEDIVAC","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":54,"produces_name":"MEDIVAC"}}},{"id":621,"name":"STARPORTTRAIN_BANSHEE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":55,"produces_name":"BANSHEE"}}},{"id":622,"name":"STARPORTTRAIN_RAVEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":56,"produces_name":"RAVEN"}}},{"id":623,"name":"STARPORTTRAIN_BATTLECRUISER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":57,"produces_name":"BATTLECRUISER"}}},{"id":624,"name":"STARPORTTRAIN_VIKINGFIGHTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":35,"produces_name":"VIKINGFIGHTER"}}},{"id":626,"name":"STARPORTTRAIN_LIBERATOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":689,"produces_name":"LIBERATOR"}}},{"id":650,"name":"RESEARCH_HISECAUTOTRACKING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":5,"upgrade_name":"HISECAUTOTRACKING"}}},{"id":651,"name":"RESEARCH_TERRANSTRUCTUREARMORUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":6,"upgrade_name":"TERRANBUILDINGARMOR"}}},{"id":652,"name":"ENGINEERINGBAYRESEARCH_TERRANINFANTRYWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3698,"target":{"Research":{"upgrade":7,"upgrade_name":"TERRANINFANTRYWEAPONSLEVEL1"}}},{"id":653,"name":"ENGINEERINGBAYRESEARCH_TERRANINFANTRYWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3698,"target":{"Research":{"upgrade":8,"upgrade_name":"TERRANINFANTRYWEAPONSLEVEL2"}}},{"id":654,"name":"ENGINEERINGBAYRESEARCH_TERRANINFANTRYWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3698,"target":{"Research":{"upgrade":9,"upgrade_name":"TERRANINFANTRYWEAPONSLEVEL3"}}},{"id":655,"name":"RESEARCH_NEOSTEELFRAME","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":10,"upgrade_name":"NEOSTEELFRAME"}}},{"id":656,"name":"ENGINEERINGBAYRESEARCH_TERRANINFANTRYARMORLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3697,"target":{"Research":{"upgrade":11,"upgrade_name":"TERRANINFANTRYARMORSLEVEL1"}}},{"id":657,"name":"ENGINEERINGBAYRESEARCH_TERRANINFANTRYARMORLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3697,"target":{"Research":{"upgrade":12,"upgrade_name":"TERRANINFANTRYARMORSLEVEL2"}}},{"id":658,"name":"ENGINEERINGBAYRESEARCH_TERRANINFANTRYARMORLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3697,"target":{"Research":{"upgrade":13,"upgrade_name":"TERRANINFANTRYARMORSLEVEL3"}}},{"id":710,"name":"BUILD_NUKE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":730,"name":"BARRACKSTECHLABRESEARCH_STIMPACK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":15,"upgrade_name":"STIMPACK"}}},{"id":731,"name":"RESEARCH_COMBATSHIELD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":16,"upgrade_name":"SHIELDWALL"}}},{"id":732,"name":"RESEARCH_CONCUSSIVESHELLS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":17,"upgrade_name":"PUNISHERGRENADES"}}},{"id":761,"name":"RESEARCH_INFERNALPREIGNITER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":19,"upgrade_name":"HIGHCAPACITYBARRELS"}}},{"id":763,"name":"FACTORYTECHLABRESEARCH_RESEARCHTRANSFORMATIONSERVOS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":98,"upgrade_name":"TRANSFORMATIONSERVOS"}}},{"id":764,"name":"RESEARCH_DRILLINGCLAWS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":122,"upgrade_name":"DRILLCLAWS"}}},{"id":765,"name":"FACTORYTECHLABRESEARCH_RESEARCHLOCKONRANGEUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":123,"upgrade_name":"CYCLONELOCKONRANGEUPGRADE"}}},{"id":766,"name":"RESEARCH_SMARTSERVOS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":289,"upgrade_name":"SMARTSERVOS"}}},{"id":767,"name":"FACTORYTECHLABRESEARCH_RESEARCHARMORPIERCINGROCKETS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":290,"upgrade_name":"ARMORPIERCINGROCKETS"}}},{"id":768,"name":"RESEARCH_CYCLONERAPIDFIRELAUNCHERS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":291,"upgrade_name":"CYCLONERAPIDFIRELAUNCHERS"}}},{"id":769,"name":"RESEARCH_CYCLONELOCKONDAMAGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":144,"upgrade_name":"CYCLONELOCKONDAMAGEUPGRADE"}}},{"id":770,"name":"FACTORYTECHLABRESEARCH_CYCLONERESEARCHHURRICANETHRUSTERS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":296,"upgrade_name":"HURRICANETHRUSTERS"}}},{"id":790,"name":"RESEARCH_BANSHEECLOAKINGFIELD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":20,"upgrade_name":"BANSHEECLOAK"}}},{"id":793,"name":"RESEARCH_RAVENCORVIDREACTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":22,"upgrade_name":"RAVENCORVIDREACTOR"}}},{"id":796,"name":"STARPORTTECHLABRESEARCH_RESEARCHSEEKERMISSILE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":23,"upgrade_name":"HUNTERSEEKER"}}},{"id":797,"name":"STARPORTTECHLABRESEARCH_RESEARCHDURABLEMATERIALS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":24,"upgrade_name":"DURABLEMATERIALS"}}},{"id":799,"name":"RESEARCH_BANSHEEHYPERFLIGHTROTORS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":136,"upgrade_name":"BANSHEESPEED"}}},{"id":800,"name":"STARPORTTECHLABRESEARCH_RESEARCHLIBERATORAGMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":125,"upgrade_name":"LIBERATORMORPH"}}},{"id":802,"name":"STARPORTTECHLABRESEARCH_RESEARCHRAPIDDEPLOYMENT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":137,"upgrade_name":"MEDIVACRAPIDDEPLOYMENT"}}},{"id":803,"name":"RESEARCH_RAVENRECALIBRATEDEXPLOSIVES","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":138,"upgrade_name":"RAVENRECALIBRATEDEXPLOSIVES"}}},{"id":806,"name":"STARPORTTECHLABRESEARCH_RAVENRESEARCHENHANCEDMUNITIONS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":292,"upgrade_name":"RAVENENHANCEDMUNITIONS"}}},{"id":807,"name":"STARPORTTECHLABRESEARCH_RESEARCHRAVENINTERFERENCEMATRIX","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":300,"upgrade_name":"INTERFERENCEMATRIX"}}},{"id":820,"name":"RESEARCH_PERSONALCLOAKING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":25,"upgrade_name":"PERSONALCLOAKING"}}},{"id":852,"name":"ARMORYRESEARCH_TERRANVEHICLEPLATINGLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":27,"upgrade_name":"TERRANVEHICLEARMORSLEVEL1"}}},{"id":853,"name":"ARMORYRESEARCH_TERRANVEHICLEPLATINGLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":28,"upgrade_name":"TERRANVEHICLEARMORSLEVEL2"}}},{"id":854,"name":"ARMORYRESEARCH_TERRANVEHICLEPLATINGLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":29,"upgrade_name":"TERRANVEHICLEARMORSLEVEL3"}}},{"id":855,"name":"ARMORYRESEARCH_TERRANVEHICLEWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3701,"target":{"Research":{"upgrade":30,"upgrade_name":"TERRANVEHICLEWEAPONSLEVEL1"}}},{"id":856,"name":"ARMORYRESEARCH_TERRANVEHICLEWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3701,"target":{"Research":{"upgrade":31,"upgrade_name":"TERRANVEHICLEWEAPONSLEVEL2"}}},{"id":857,"name":"ARMORYRESEARCH_TERRANVEHICLEWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3701,"target":{"Research":{"upgrade":32,"upgrade_name":"TERRANVEHICLEWEAPONSLEVEL3"}}},{"id":858,"name":"ARMORYRESEARCH_TERRANSHIPPLATINGLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":33,"upgrade_name":"TERRANSHIPARMORSLEVEL1"}}},{"id":859,"name":"ARMORYRESEARCH_TERRANSHIPPLATINGLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":34,"upgrade_name":"TERRANSHIPARMORSLEVEL2"}}},{"id":860,"name":"ARMORYRESEARCH_TERRANSHIPPLATINGLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":35,"upgrade_name":"TERRANSHIPARMORSLEVEL3"}}},{"id":861,"name":"ARMORYRESEARCH_TERRANSHIPWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3699,"target":{"Research":{"upgrade":36,"upgrade_name":"TERRANSHIPWEAPONSLEVEL1"}}},{"id":862,"name":"ARMORYRESEARCH_TERRANSHIPWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3699,"target":{"Research":{"upgrade":37,"upgrade_name":"TERRANSHIPWEAPONSLEVEL2"}}},{"id":863,"name":"ARMORYRESEARCH_TERRANSHIPWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3699,"target":{"Research":{"upgrade":38,"upgrade_name":"TERRANSHIPWEAPONSLEVEL3"}}},{"id":864,"name":"ARMORYRESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3700,"target":{"Research":{"upgrade":116,"upgrade_name":"TERRANVEHICLEANDSHIPARMORSLEVEL1"}}},{"id":865,"name":"ARMORYRESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3700,"target":{"Research":{"upgrade":117,"upgrade_name":"TERRANVEHICLEANDSHIPARMORSLEVEL2"}}},{"id":866,"name":"ARMORYRESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3700,"target":{"Research":{"upgrade":118,"upgrade_name":"TERRANVEHICLEANDSHIPARMORSLEVEL3"}}},{"id":880,"name":"PROTOSSBUILD_NEXUS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":59,"produces_name":"NEXUS"}}},{"id":881,"name":"PROTOSSBUILD_PYLON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":60,"produces_name":"PYLON"}}},{"id":882,"name":"PROTOSSBUILD_ASSIMILATOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"BuildOnUnit":{"produces":61,"produces_name":"ASSIMILATOR"}}},{"id":883,"name":"PROTOSSBUILD_GATEWAY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":62,"produces_name":"GATEWAY"}}},{"id":884,"name":"PROTOSSBUILD_FORGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":63,"produces_name":"FORGE"}}},{"id":885,"name":"PROTOSSBUILD_FLEETBEACON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":64,"produces_name":"FLEETBEACON"}}},{"id":886,"name":"PROTOSSBUILD_TWILIGHTCOUNCIL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":65,"produces_name":"TWILIGHTCOUNCIL"}}},{"id":887,"name":"PROTOSSBUILD_PHOTONCANNON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":66,"produces_name":"PHOTONCANNON"}}},{"id":889,"name":"PROTOSSBUILD_STARGATE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":67,"produces_name":"STARGATE"}}},{"id":890,"name":"PROTOSSBUILD_TEMPLARARCHIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":68,"produces_name":"TEMPLARARCHIVE"}}},{"id":891,"name":"PROTOSSBUILD_DARKSHRINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":69,"produces_name":"DARKSHRINE"}}},{"id":892,"name":"PROTOSSBUILD_ROBOTICSBAY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":70,"produces_name":"ROBOTICSBAY"}}},{"id":893,"name":"PROTOSSBUILD_ROBOTICSFACILITY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":71,"produces_name":"ROBOTICSFACILITY"}}},{"id":894,"name":"PROTOSSBUILD_CYBERNETICSCORE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":72,"produces_name":"CYBERNETICSCORE"}}},{"id":895,"name":"BUILD_SHIELDBATTERY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":1910,"produces_name":"SHIELDBATTERY"}}},{"id":910,"name":"PROTOSSBUILD_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3660},{"id":911,"name":"LOAD_WARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":912,"name":"UNLOADALL_WARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3664},{"id":913,"name":"UNLOADALLAT_WARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3669},{"id":914,"name":"UNLOADUNIT_WARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3796},{"id":916,"name":"GATEWAYTRAIN_ZEALOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":73,"produces_name":"ZEALOT"}}},{"id":917,"name":"GATEWAYTRAIN_STALKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":74,"produces_name":"STALKER"}}},{"id":919,"name":"GATEWAYTRAIN_HIGHTEMPLAR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":75,"produces_name":"HIGHTEMPLAR"}}},{"id":920,"name":"GATEWAYTRAIN_DARKTEMPLAR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":76,"produces_name":"DARKTEMPLAR"}}},{"id":921,"name":"GATEWAYTRAIN_SENTRY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":77,"produces_name":"SENTRY"}}},{"id":922,"name":"TRAIN_ADEPT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":311,"produces_name":"ADEPT"}}},{"id":946,"name":"STARGATETRAIN_PHOENIX","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":78,"produces_name":"PHOENIX"}}},{"id":948,"name":"STARGATETRAIN_CARRIER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":79,"produces_name":"CARRIER"}}},{"id":950,"name":"STARGATETRAIN_VOIDRAY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":80,"produces_name":"VOIDRAY"}}},{"id":954,"name":"STARGATETRAIN_ORACLE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":495,"produces_name":"ORACLE"}}},{"id":955,"name":"STARGATETRAIN_TEMPEST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":496,"produces_name":"TEMPEST"}}},{"id":976,"name":"ROBOTICSFACILITYTRAIN_WARPPRISM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":81,"produces_name":"WARPPRISM"}}},{"id":977,"name":"ROBOTICSFACILITYTRAIN_OBSERVER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":82,"produces_name":"OBSERVER"}}},{"id":978,"name":"ROBOTICSFACILITYTRAIN_COLOSSUS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":4,"produces_name":"COLOSSUS"}}},{"id":979,"name":"ROBOTICSFACILITYTRAIN_IMMORTAL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":83,"produces_name":"IMMORTAL"}}},{"id":994,"name":"TRAIN_DISRUPTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":694,"produces_name":"DISRUPTOR"}}},{"id":1006,"name":"NEXUSTRAIN_PROBE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":84,"produces_name":"PROBE"}}},{"id":1036,"name":"PSISTORM_PSISTORM","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":1038,"name":"CANCEL_HANGARQUEUE5","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":1039,"name":"CANCELSLOT_HANGARQUEUE5","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":1040,"name":"BROODLORDQUEUE2_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":1041,"name":"BROODLORDQUEUE2_CANCELSLOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":1042,"name":"BUILD_INTERCEPTORS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":1062,"name":"FORGERESEARCH_PROTOSSGROUNDWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3695,"target":{"Research":{"upgrade":39,"upgrade_name":"PROTOSSGROUNDWEAPONSLEVEL1"}}},{"id":1063,"name":"FORGERESEARCH_PROTOSSGROUNDWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3695,"target":{"Research":{"upgrade":40,"upgrade_name":"PROTOSSGROUNDWEAPONSLEVEL2"}}},{"id":1064,"name":"FORGERESEARCH_PROTOSSGROUNDWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3695,"target":{"Research":{"upgrade":41,"upgrade_name":"PROTOSSGROUNDWEAPONSLEVEL3"}}},{"id":1065,"name":"FORGERESEARCH_PROTOSSGROUNDARMORLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3694,"target":{"Research":{"upgrade":42,"upgrade_name":"PROTOSSGROUNDARMORSLEVEL1"}}},{"id":1066,"name":"FORGERESEARCH_PROTOSSGROUNDARMORLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3694,"target":{"Research":{"upgrade":43,"upgrade_name":"PROTOSSGROUNDARMORSLEVEL2"}}},{"id":1067,"name":"FORGERESEARCH_PROTOSSGROUNDARMORLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3694,"target":{"Research":{"upgrade":44,"upgrade_name":"PROTOSSGROUNDARMORSLEVEL3"}}},{"id":1068,"name":"FORGERESEARCH_PROTOSSSHIELDSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3696,"target":{"Research":{"upgrade":45,"upgrade_name":"PROTOSSSHIELDSLEVEL1"}}},{"id":1069,"name":"FORGERESEARCH_PROTOSSSHIELDSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3696,"target":{"Research":{"upgrade":46,"upgrade_name":"PROTOSSSHIELDSLEVEL2"}}},{"id":1070,"name":"FORGERESEARCH_PROTOSSSHIELDSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3696,"target":{"Research":{"upgrade":47,"upgrade_name":"PROTOSSSHIELDSLEVEL3"}}},{"id":1093,"name":"RESEARCH_GRAVITICBOOSTER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":48,"upgrade_name":"OBSERVERGRAVITICBOOSTER"}}},{"id":1094,"name":"RESEARCH_GRAVITICDRIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":49,"upgrade_name":"GRAVITICDRIVE"}}},{"id":1097,"name":"RESEARCH_EXTENDEDTHERMALLANCE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":50,"upgrade_name":"EXTENDEDTHERMALLANCE"}}},{"id":1099,"name":"ROBOTICSBAYRESEARCH_RESEARCHIMMORTALREVIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":121,"upgrade_name":"IMMORTALREVIVE"}}},{"id":1126,"name":"RESEARCH_PSISTORM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":52,"upgrade_name":"PSISTORMTECH"}}},{"id":1152,"name":"ZERGBUILD_HATCHERY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":86,"produces_name":"HATCHERY"}}},{"id":1153,"name":"ZERGBUILD_CREEPTUMOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":87,"produces_name":"CREEPTUMOR"}}},{"id":1154,"name":"ZERGBUILD_EXTRACTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"BuildOnUnit":{"produces":88,"produces_name":"EXTRACTOR"}}},{"id":1155,"name":"ZERGBUILD_SPAWNINGPOOL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":89,"produces_name":"SPAWNINGPOOL"}}},{"id":1156,"name":"ZERGBUILD_EVOLUTIONCHAMBER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":90,"produces_name":"EVOLUTIONCHAMBER"}}},{"id":1157,"name":"ZERGBUILD_HYDRALISKDEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":91,"produces_name":"HYDRALISKDEN"}}},{"id":1158,"name":"ZERGBUILD_SPIRE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":92,"produces_name":"SPIRE"}}},{"id":1159,"name":"ZERGBUILD_ULTRALISKCAVERN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":93,"produces_name":"ULTRALISKCAVERN"}}},{"id":1160,"name":"ZERGBUILD_INFESTATIONPIT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":94,"produces_name":"INFESTATIONPIT"}}},{"id":1161,"name":"ZERGBUILD_NYDUSNETWORK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":95,"produces_name":"NYDUSNETWORK"}}},{"id":1162,"name":"ZERGBUILD_BANELINGNEST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":96,"produces_name":"BANELINGNEST"}}},{"id":1163,"name":"BUILD_LURKERDEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":504,"produces_name":"LURKERDENMP"}}},{"id":1165,"name":"ZERGBUILD_ROACHWARREN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":97,"produces_name":"ROACHWARREN"}}},{"id":1166,"name":"ZERGBUILD_SPINECRAWLER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":98,"produces_name":"SPINECRAWLER"}}},{"id":1167,"name":"ZERGBUILD_SPORECRAWLER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":99,"produces_name":"SPORECRAWLER"}}},{"id":1182,"name":"ZERGBUILD_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3660},{"id":1183,"name":"HARVEST_GATHER_DRONE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3666},{"id":1184,"name":"HARVEST_RETURN_DRONE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3667},{"id":1186,"name":"RESEARCH_ZERGMELEEWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3705,"target":{"Research":{"upgrade":53,"upgrade_name":"ZERGMELEEWEAPONSLEVEL1"}}},{"id":1187,"name":"RESEARCH_ZERGMELEEWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3705,"target":{"Research":{"upgrade":54,"upgrade_name":"ZERGMELEEWEAPONSLEVEL2"}}},{"id":1188,"name":"RESEARCH_ZERGMELEEWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3705,"target":{"Research":{"upgrade":55,"upgrade_name":"ZERGMELEEWEAPONSLEVEL3"}}},{"id":1189,"name":"RESEARCH_ZERGGROUNDARMORLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3704,"target":{"Research":{"upgrade":56,"upgrade_name":"ZERGGROUNDARMORSLEVEL1"}}},{"id":1190,"name":"RESEARCH_ZERGGROUNDARMORLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3704,"target":{"Research":{"upgrade":57,"upgrade_name":"ZERGGROUNDARMORSLEVEL2"}}},{"id":1191,"name":"RESEARCH_ZERGGROUNDARMORLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3704,"target":{"Research":{"upgrade":58,"upgrade_name":"ZERGGROUNDARMORSLEVEL3"}}},{"id":1192,"name":"RESEARCH_ZERGMISSILEWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3706,"target":{"Research":{"upgrade":59,"upgrade_name":"ZERGMISSILEWEAPONSLEVEL1"}}},{"id":1193,"name":"RESEARCH_ZERGMISSILEWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3706,"target":{"Research":{"upgrade":60,"upgrade_name":"ZERGMISSILEWEAPONSLEVEL2"}}},{"id":1194,"name":"RESEARCH_ZERGMISSILEWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3706,"target":{"Research":{"upgrade":61,"upgrade_name":"ZERGMISSILEWEAPONSLEVEL3"}}},{"id":1195,"name":"EVOLUTIONCHAMBERRESEARCH_EVOLVEPROPULSIVEPERISTALSIS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":304,"upgrade_name":"SECRETEDCOATING"}}},{"id":1216,"name":"UPGRADETOLAIR_LAIR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":100,"produces_name":"LAIR"}}},{"id":1217,"name":"CANCEL_MORPHLAIR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1218,"name":"UPGRADETOHIVE_HIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":101,"produces_name":"HIVE"}}},{"id":1219,"name":"CANCEL_MORPHHIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1220,"name":"UPGRADETOGREATERSPIRE_GREATERSPIRE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":102,"produces_name":"GREATERSPIRE"}}},{"id":1221,"name":"CANCEL_MORPHGREATERSPIRE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1223,"name":"RESEARCH_PNEUMATIZEDCARAPACE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":62,"upgrade_name":"OVERLORDSPEED"}}},{"id":1224,"name":"LAIRRESEARCH_EVOLVEVENTRALSACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":63,"upgrade_name":"OVERLORDTRANSPORT"}}},{"id":1225,"name":"RESEARCH_BURROW","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":64,"upgrade_name":"BURROW"}}},{"id":1252,"name":"RESEARCH_ZERGLINGADRENALGLANDS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":65,"upgrade_name":"ZERGLINGATTACKSPEED"}}},{"id":1253,"name":"RESEARCH_ZERGLINGMETABOLICBOOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":66,"upgrade_name":"ZERGLINGMOVEMENTSPEED"}}},{"id":1282,"name":"RESEARCH_GROOVEDSPINES","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":134,"upgrade_name":"EVOLVEGROOVEDSPINES"}}},{"id":1283,"name":"RESEARCH_MUSCULARAUGMENTS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":135,"upgrade_name":"EVOLVEMUSCULARAUGMENTS"}}},{"id":1284,"name":"HYDRALISKDENRESEARCH_RESEARCHFRENZY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":298,"upgrade_name":"FRENZY"}}},{"id":1312,"name":"RESEARCH_ZERGFLYERATTACKLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3703,"target":{"Research":{"upgrade":68,"upgrade_name":"ZERGFLYERWEAPONSLEVEL1"}}},{"id":1313,"name":"RESEARCH_ZERGFLYERATTACKLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3703,"target":{"Research":{"upgrade":69,"upgrade_name":"ZERGFLYERWEAPONSLEVEL2"}}},{"id":1314,"name":"RESEARCH_ZERGFLYERATTACKLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3703,"target":{"Research":{"upgrade":70,"upgrade_name":"ZERGFLYERWEAPONSLEVEL3"}}},{"id":1315,"name":"RESEARCH_ZERGFLYERARMORLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3702,"target":{"Research":{"upgrade":71,"upgrade_name":"ZERGFLYERARMORSLEVEL1"}}},{"id":1316,"name":"RESEARCH_ZERGFLYERARMORLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3702,"target":{"Research":{"upgrade":72,"upgrade_name":"ZERGFLYERARMORSLEVEL2"}}},{"id":1317,"name":"RESEARCH_ZERGFLYERARMORLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3702,"target":{"Research":{"upgrade":73,"upgrade_name":"ZERGFLYERARMORSLEVEL3"}}},{"id":1342,"name":"LARVATRAIN_DRONE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":104,"produces_name":"DRONE"}}},{"id":1343,"name":"LARVATRAIN_ZERGLING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":105,"produces_name":"ZERGLING"}}},{"id":1344,"name":"LARVATRAIN_OVERLORD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":106,"produces_name":"OVERLORD"}}},{"id":1345,"name":"LARVATRAIN_HYDRALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":107,"produces_name":"HYDRALISK"}}},{"id":1346,"name":"LARVATRAIN_MUTALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":108,"produces_name":"MUTALISK"}}},{"id":1348,"name":"LARVATRAIN_ULTRALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":109,"produces_name":"ULTRALISK"}}},{"id":1351,"name":"LARVATRAIN_ROACH","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":110,"produces_name":"ROACH"}}},{"id":1352,"name":"LARVATRAIN_INFESTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":111,"produces_name":"INFESTOR"}}},{"id":1353,"name":"LARVATRAIN_CORRUPTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":112,"produces_name":"CORRUPTOR"}}},{"id":1354,"name":"LARVATRAIN_VIPER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":499,"produces_name":"VIPER"}}},{"id":1356,"name":"TRAIN_SWARMHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Train":{"produces":494,"produces_name":"SWARMHOSTMP"}}},{"id":1372,"name":"MORPHTOBROODLORD_BROODLORD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":114,"produces_name":"BROODLORD"}}},{"id":1373,"name":"CANCEL_MORPHBROODLORD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1374,"name":"BURROWDOWN_BANELING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":115,"produces_name":"BANELINGBURROWED"}}},{"id":1375,"name":"BURROWBANELINGDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1376,"name":"BURROWUP_BANELING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":9,"produces_name":"BANELING"}}},{"id":1378,"name":"BURROWDOWN_DRONE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":116,"produces_name":"DRONEBURROWED"}}},{"id":1379,"name":"BURROWDRONEDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1380,"name":"BURROWUP_DRONE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":104,"produces_name":"DRONE"}}},{"id":1382,"name":"BURROWDOWN_HYDRALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":117,"produces_name":"HYDRALISKBURROWED"}}},{"id":1383,"name":"BURROWHYDRALISKDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1384,"name":"BURROWUP_HYDRALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":107,"produces_name":"HYDRALISK"}}},{"id":1386,"name":"BURROWDOWN_ROACH","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":118,"produces_name":"ROACHBURROWED"}}},{"id":1387,"name":"BURROWROACHDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1388,"name":"BURROWUP_ROACH","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":110,"produces_name":"ROACH"}}},{"id":1390,"name":"BURROWDOWN_ZERGLING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":119,"produces_name":"ZERGLINGBURROWED"}}},{"id":1391,"name":"BURROWZERGLINGDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1392,"name":"BURROWUP_ZERGLING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":105,"produces_name":"ZERGLING"}}},{"id":1394,"name":"BURROWDOWN_INFESTORTERRAN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":120,"produces_name":"INFESTORTERRANBURROWED"}}},{"id":1396,"name":"BURROWUP_INFESTORTERRAN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":7,"produces_name":"INFESTORTERRAN"}}},{"id":1406,"name":"LOAD_OVERLORD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":1408,"name":"UNLOADALLAT_OVERLORD","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3669},{"id":1409,"name":"UNLOADUNIT_OVERLORD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3796},{"id":1411,"name":"MERGEABLE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1412,"name":"WARPABLE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1413,"name":"WARPGATETRAIN_ZEALOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"TrainPlace":{"produces":73,"produces_name":"ZEALOT"}}},{"id":1414,"name":"WARPGATETRAIN_STALKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"TrainPlace":{"produces":74,"produces_name":"STALKER"}}},{"id":1416,"name":"WARPGATETRAIN_HIGHTEMPLAR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"TrainPlace":{"produces":75,"produces_name":"HIGHTEMPLAR"}}},{"id":1417,"name":"WARPGATETRAIN_DARKTEMPLAR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"TrainPlace":{"produces":76,"produces_name":"DARKTEMPLAR"}}},{"id":1418,"name":"WARPGATETRAIN_SENTRY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"TrainPlace":{"produces":77,"produces_name":"SENTRY"}}},{"id":1419,"name":"TRAINWARP_ADEPT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"TrainPlace":{"produces":311,"produces_name":"ADEPT"}}},{"id":1433,"name":"BURROWDOWN_QUEEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":125,"produces_name":"QUEENBURROWED"}}},{"id":1434,"name":"BURROWQUEENDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1435,"name":"BURROWUP_QUEEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":126,"produces_name":"QUEEN"}}},{"id":1437,"name":"LOAD_NYDUSNETWORK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":1438,"name":"UNLOADALL_NYDASNETWORK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3664},{"id":1440,"name":"UNLOADUNIT_NYDASNETWORK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3796},{"id":1442,"name":"EFFECT_BLINK_STALKER","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3687},{"id":1444,"name":"BURROWDOWN_INFESTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":127,"produces_name":"INFESTORBURROWED"}}},{"id":1445,"name":"BURROWINFESTORDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1446,"name":"BURROWUP_INFESTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":111,"produces_name":"INFESTOR"}}},{"id":1448,"name":"MORPH_OVERSEER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":129,"produces_name":"OVERSEER"}}},{"id":1449,"name":"CANCEL_MORPHOVERSEER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1450,"name":"UPGRADETOPLANETARYFORTRESS_PLANETARYFORTRESS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":130,"produces_name":"PLANETARYFORTRESS"}}},{"id":1451,"name":"CANCEL_MORPHPLANETARYFORTRESS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1455,"name":"RESEARCH_NEURALPARASITE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":101,"upgrade_name":"NEURALPARASITE"}}},{"id":1456,"name":"INFESTATIONPITRESEARCH_RESEARCHLOCUSTLIFETIMEINCREASE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":102,"upgrade_name":"LOCUSTLIFETIMEINCREASE"}}},{"id":1457,"name":"INFESTATIONPITRESEARCH_EVOLVEAMORPHOUSARMORCLOUD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":299,"upgrade_name":"MICROBIALSHROUD"}}},{"id":1482,"name":"RESEARCH_CENTRIFUGALHOOKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":75,"upgrade_name":"CENTRIFICALHOOKS"}}},{"id":1512,"name":"BURROWDOWN_ULTRALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":131,"produces_name":"ULTRALISKBURROWED"}}},{"id":1514,"name":"BURROWUP_ULTRALISK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":109,"produces_name":"ULTRALISK"}}},{"id":1516,"name":"UPGRADETOORBITAL_ORBITALCOMMAND","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":132,"produces_name":"ORBITALCOMMAND"}}},{"id":1517,"name":"CANCEL_MORPHORBITAL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1518,"name":"MORPH_WARPGATE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":133,"produces_name":"WARPGATE"}}},{"id":1519,"name":"UPGRADETOWARPGATE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1520,"name":"MORPH_GATEWAY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":62,"produces_name":"GATEWAY"}}},{"id":1521,"name":"MORPHBACKTOGATEWAY_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1522,"name":"LIFT_ORBITALCOMMAND","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3679,"target":{"Morph":{"produces":134,"produces_name":"ORBITALCOMMANDFLYING"}}},{"id":1524,"name":"LAND_ORBITALCOMMAND","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3678,"target":{"MorphPlace":{"produces":132,"produces_name":"ORBITALCOMMAND"}}},{"id":1526,"name":"FORCEFIELD_FORCEFIELD","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":1527,"name":"FORCEFIELD_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1528,"name":"MORPH_WARPPRISMPHASINGMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":136,"produces_name":"WARPPRISMPHASING"}}},{"id":1529,"name":"PHASINGMODE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1530,"name":"MORPH_WARPPRISMTRANSPORTMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":81,"produces_name":"WARPPRISM"}}},{"id":1531,"name":"TRANSPORTMODE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1532,"name":"RESEARCH_BATTLECRUISERWEAPONREFIT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":76,"upgrade_name":"BATTLECRUISERENABLESPECIALIZATIONS"}}},{"id":1533,"name":"FUSIONCORERESEARCH_RESEARCHBALLISTICRANGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":140,"upgrade_name":"LIBERATORAGRANGEUPGRADE"}}},{"id":1534,"name":"FUSIONCORERESEARCH_RESEARCHRAPIDREIGNITIONSYSTEM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":139,"upgrade_name":"MEDIVACINCREASESPEEDBOOST"}}},{"id":1535,"name":"FUSIONCORERESEARCH_RESEARCHMEDIVACENERGYUPGRADE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":21,"upgrade_name":"MEDIVACCADUCEUSREACTOR"}}},{"id":1562,"name":"CYBERNETICSCORERESEARCH_PROTOSSAIRWEAPONSLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3693,"target":{"Research":{"upgrade":78,"upgrade_name":"PROTOSSAIRWEAPONSLEVEL1"}}},{"id":1563,"name":"CYBERNETICSCORERESEARCH_PROTOSSAIRWEAPONSLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3693,"target":{"Research":{"upgrade":79,"upgrade_name":"PROTOSSAIRWEAPONSLEVEL2"}}},{"id":1564,"name":"CYBERNETICSCORERESEARCH_PROTOSSAIRWEAPONSLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3693,"target":{"Research":{"upgrade":80,"upgrade_name":"PROTOSSAIRWEAPONSLEVEL3"}}},{"id":1565,"name":"CYBERNETICSCORERESEARCH_PROTOSSAIRARMORLEVEL1","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3692,"target":{"Research":{"upgrade":81,"upgrade_name":"PROTOSSAIRARMORSLEVEL1"}}},{"id":1566,"name":"CYBERNETICSCORERESEARCH_PROTOSSAIRARMORLEVEL2","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3692,"target":{"Research":{"upgrade":82,"upgrade_name":"PROTOSSAIRARMORSLEVEL2"}}},{"id":1567,"name":"CYBERNETICSCORERESEARCH_PROTOSSAIRARMORLEVEL3","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3692,"target":{"Research":{"upgrade":83,"upgrade_name":"PROTOSSAIRARMORSLEVEL3"}}},{"id":1568,"name":"RESEARCH_WARPGATE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":84,"upgrade_name":"WARPGATERESEARCH"}}},{"id":1571,"name":"CYBERNETICSCORERESEARCH_RESEARCHHALLUCINATION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":85,"upgrade_name":"HALTECH"}}},{"id":1592,"name":"RESEARCH_CHARGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":86,"upgrade_name":"CHARGE"}}},{"id":1593,"name":"RESEARCH_BLINK","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":87,"upgrade_name":"BLINKTECH"}}},{"id":1594,"name":"RESEARCH_ADEPTRESONATINGGLAIVES","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":130,"upgrade_name":"ADEPTPIERCINGATTACK"}}},{"id":1595,"name":"TWILIGHTCOUNCILRESEARCH_RESEARCHPSIONICSURGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":301,"upgrade_name":"SUNDERINGIMPACT"}}},{"id":1596,"name":"TWILIGHTCOUNCILRESEARCH_RESEARCHAMPLIFIEDSHIELDING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":302,"upgrade_name":"AMPLIFIEDSHIELDING"}}},{"id":1597,"name":"TWILIGHTCOUNCILRESEARCH_RESEARCHPSIONICAMPLIFIERS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":303,"upgrade_name":"PSIONICAMPLIFIERS"}}},{"id":1622,"name":"TACNUKESTRIKE_NUKECALLDOWN","cast_range":12.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":1623,"name":"CANCEL_NUKE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1628,"name":"EMP_EMP","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":1632,"name":"TRAINQUEEN_QUEEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":126}}},{"id":1662,"name":"BURROWCREEPTUMORDOWN_BURROWDOWN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":137,"produces_name":"CREEPTUMORBURROWED"}}},{"id":1664,"name":"TRANSFUSION_TRANSFUSION","cast_range":7.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1666,"name":"TECHLABMORPH_TECHLABMORPH","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":5,"produces_name":"TECHLAB"}}},{"id":1668,"name":"BARRACKSTECHLABMORPH_TECHLABBARRACKS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":5,"produces_name":"TECHLAB"}}},{"id":1670,"name":"FACTORYTECHLABMORPH_TECHLABFACTORY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":5,"produces_name":"TECHLAB"}}},{"id":1672,"name":"STARPORTTECHLABMORPH_TECHLABSTARPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":5,"produces_name":"TECHLAB"}}},{"id":1674,"name":"REACTORMORPH_REACTORMORPH","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":6,"produces_name":"REACTOR"}}},{"id":1676,"name":"BARRACKSREACTORMORPH_REACTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":6,"produces_name":"REACTOR"}}},{"id":1678,"name":"FACTORYREACTORMORPH_REACTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":6,"produces_name":"REACTOR"}}},{"id":1680,"name":"STARPORTREACTORMORPH_REACTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":6,"produces_name":"REACTOR"}}},{"id":1682,"name":"ATTACK_REDIRECT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3674},{"id":1683,"name":"EFFECT_STIM_MARINE_REDIRECT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3675},{"id":1684,"name":"EFFECT_STIM_MARAUDER_REDIRECT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3675},{"id":1691,"name":"STOP_REDIRECT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":1692,"name":"BEHAVIOR_GENERATECREEPON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":1693,"name":"BEHAVIOR_GENERATECREEPOFF","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":1694,"name":"BUILD_CREEPTUMOR_QUEEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3691,"target":{"Build":{"produces":138,"produces_name":"CREEPTUMORQUEEN"}}},{"id":1724,"name":"QUEENBUILD_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3660},{"id":1725,"name":"SPINECRAWLERUPROOT_SPINECRAWLERUPROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3681,"target":{"Morph":{"produces":139,"produces_name":"SPINECRAWLERUPROOTED"}}},{"id":1726,"name":"SPINECRAWLERUPROOT_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1727,"name":"SPORECRAWLERUPROOT_SPORECRAWLERUPROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3681,"target":{"Morph":{"produces":140,"produces_name":"SPORECRAWLERUPROOTED"}}},{"id":1728,"name":"SPORECRAWLERUPROOT_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1729,"name":"SPINECRAWLERROOT_SPINECRAWLERROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3680,"target":{"MorphPlace":{"produces":98,"produces_name":"SPINECRAWLER"}}},{"id":1730,"name":"CANCEL_SPINECRAWLERROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1731,"name":"SPORECRAWLERROOT_SPORECRAWLERROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3680,"target":{"MorphPlace":{"produces":99,"produces_name":"SPORECRAWLER"}}},{"id":1732,"name":"CANCEL_SPORECRAWLERROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1733,"name":"BUILD_CREEPTUMOR_TUMOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3691,"target":{"Build":{"produces":87,"produces_name":"CREEPTUMOR"}}},{"id":1763,"name":"CANCEL_CREEPTUMOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1764,"name":"BUILDAUTOTURRET_AUTOTURRET","cast_range":2.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":31,"produces_name":"AUTOTURRET"}}},{"id":1766,"name":"MORPH_ARCHON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":141,"produces_name":"ARCHON"}}},{"id":1767,"name":"ARCHON_WARP_TARGET","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1768,"name":"BUILD_NYDUSWORM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":142,"produces_name":"NYDUSCANAL"}}},{"id":1769,"name":"BUILDNYDUSCANAL_SUMMONNYDUSCANALATTACKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":491,"produces_name":"NYDUSCANALATTACKER"}}},{"id":1798,"name":"BUILDNYDUSCANAL_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3660},{"id":1799,"name":"BROODLORDHANGAR_BROODLORDHANGAR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":1819,"name":"EFFECT_CHARGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1820,"name":"TOWERCAPTURE_TOWERCAPTURE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1821,"name":"HERDINTERACT_HERD","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1825,"name":"CONTAMINATE_CONTAMINATE","cast_range":3.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1827,"name":"SHATTER_SHATTER","cast_range":0.10009765625,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1831,"name":"CANCEL_QUEUEPASIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":1832,"name":"CANCELSLOT_QUEUEPASSIVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":1833,"name":"CANCEL_QUEUEPASSIVECANCELTOSELECTION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3671},{"id":1834,"name":"CANCELSLOT_QUEUEPASSIVECANCELTOSELECTION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3672},{"id":1837,"name":"MORPHTOGHOSTNOVA_MOVE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":145,"produces_name":"GHOSTNOVA"}}},{"id":1839,"name":"DIGESTERCREEPSPRAY_DIGESTERCREEPSPRAY","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":1841,"name":"MORPHTOCOLLAPSIBLETERRANTOWERDEBRIS_MORPHTOCOLLAPSIBLETERRANTOWERDEBRIS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":1842,"name":"MORPHTOCOLLAPSIBLETERRANTOWERDEBRIS_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1843,"name":"MORPHTOCOLLAPSIBLETERRANTOWERDEBRISRAMPLEFT_MORPHTOCOLLAPSIBLETERRANTOWERDEBRISRAMPLEFT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":1844,"name":"MORPHTOCOLLAPSIBLETERRANTOWERDEBRISRAMPLEFT_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1845,"name":"MORPHTOCOLLAPSIBLETERRANTOWERDEBRISRAMPRIGHT_MORPHTOCOLLAPSIBLETERRANTOWERDEBRISRAMPRIGHT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":1846,"name":"MORPHTOCOLLAPSIBLETERRANTOWERDEBRISRAMPRIGHT_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1847,"name":"MORPH_MOTHERSHIP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":10,"produces_name":"MOTHERSHIP"}}},{"id":1848,"name":"CANCEL_MORPHMOTHERSHIP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1928,"name":"XELNAGAHEALINGSHRINE_XELNAGAHEALINGSHRINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":1930,"name":"NEXUSINVULNERABILITY_NEXUSINVULNERABILITY","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":1974,"name":"EFFECT_MASSRECALL_MOTHERSHIPCORE","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3686},{"id":1978,"name":"MORPH_HELLION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":53,"produces_name":"HELLION"}}},{"id":1996,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRIS_MORPHTOCOLLAPSIBLEROCKTOWERDEBRIS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":1997,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRIS_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":1998,"name":"MORPH_HELLBAT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":484,"produces_name":"HELLIONTANK"}}},{"id":2014,"name":"BURROWDOWN_SWARMHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":493,"produces_name":"SWARMHOSTBURROWEDMP"}}},{"id":2015,"name":"MORPHTOSWARMHOSTBURROWEDMP_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2016,"name":"BURROWUP_SWARMHOST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":494,"produces_name":"SWARMHOSTMP"}}},{"id":2048,"name":"ATTACKPROTOSSBUILDING_ATTACKBUILDING","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3674},{"id":2049,"name":"ATTACKPROTOSSBUILDING_ATTACKTOWARDS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2050,"name":"ATTACKPROTOSSBUILDING_ATTACKBARRAGE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2057,"name":"STOP_BUILDING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":2058,"name":"STOPPROTOSSBUILDING_HOLDFIRE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2059,"name":"STOPPROTOSSBUILDING_CHEER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2060,"name":"STOPPROTOSSBUILDING_DANCE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2063,"name":"BLINDINGCLOUD_BLINDINGCLOUD","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2067,"name":"EFFECT_ABDUCT","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2073,"name":"VIPERCONSUMESTRUCTURE_VIPERCONSUME","cast_range":7.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2079,"name":"TESTZERG_TESTZERG","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2080,"name":"TESTZERG_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2081,"name":"BEHAVIOR_BUILDINGATTACKON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2082,"name":"BEHAVIOR_BUILDINGATTACKOFF","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2083,"name":"PICKUPSCRAPSMALL_PICKUPSCRAPSMALL","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2085,"name":"PICKUPSCRAPMEDIUM_PICKUPSCRAPMEDIUM","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2087,"name":"PICKUPSCRAPLARGE_PICKUPSCRAPLARGE","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2089,"name":"PICKUPPALLETGAS_PICKUPPALLETGAS","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2091,"name":"PICKUPPALLETMINERALS_PICKUPPALLETMINERALS","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2093,"name":"MASSIVEKNOCKOVER_MASSIVEKNOCKOVER","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2095,"name":"BURROWDOWN_WIDOWMINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":500,"produces_name":"WIDOWMINEBURROWED"}}},{"id":2096,"name":"WIDOWMINEBURROW_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2097,"name":"BURROWUP_WIDOWMINE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":498,"produces_name":"WIDOWMINE"}}},{"id":2099,"name":"WIDOWMINEATTACK_WIDOWMINEATTACK","cast_range":5.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2101,"name":"TORNADOMISSILE_TORNADOMISSILE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2108,"name":"BURROWDOWN_LURKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":503,"produces_name":"LURKERMPBURROWED"}}},{"id":2109,"name":"BURROWLURKERMPDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2110,"name":"BURROWUP_LURKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":502,"produces_name":"LURKERMP"}}},{"id":2114,"name":"HALLUCINATION_ORACLE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2116,"name":"EFFECT_MEDIVACIGNITEAFTERBURNERS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2146,"name":"ORACLEREVELATION_ORACLEREVELATION","cast_range":12.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2152,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPRIGHT_MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPRIGHT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":2153,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPRIGHT_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2154,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPLEFT_MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPLEFT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":2155,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPLEFT_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2158,"name":"ULTRALISKWEAPONCOOLDOWN_ULTRALISKWEAPONCOOLDOWN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2162,"name":"EFFECT_PHOTONOVERCHARGE","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2172,"name":"XELNAGA_CAVERNS_DOORNEOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2174,"name":"XELNAGA_CAVERNS_DOORNOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2178,"name":"XELNAGA_CAVERNS_DOORNWOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2184,"name":"XELNAGA_CAVERNS_DOORSEOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2186,"name":"XELNAGA_CAVERNS_DOORSOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2190,"name":"XELNAGA_CAVERNS_DOORSWOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2194,"name":"XELNAGA_CAVERNS_DOORWOPENED_XELNAGA_CAVERNS_DOORDEFAULTOPEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2244,"name":"EFFECT_TIMEWARP","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2262,"name":"TARSONIS_DOORN_TARSONIS_DOORN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2264,"name":"TARSONIS_DOORNLOWERED_TARSONIS_DOORNLOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2266,"name":"TARSONIS_DOORNE_TARSONIS_DOORNE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2268,"name":"TARSONIS_DOORNELOWERED_TARSONIS_DOORNELOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2270,"name":"TARSONIS_DOORE_TARSONIS_DOORE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2272,"name":"TARSONIS_DOORELOWERED_TARSONIS_DOORELOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2274,"name":"TARSONIS_DOORNW_TARSONIS_DOORNW","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2276,"name":"TARSONIS_DOORNWLOWERED_TARSONIS_DOORNWLOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2278,"name":"COMPOUNDMANSION_DOORN_COMPOUNDMANSION_DOORN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2280,"name":"COMPOUNDMANSION_DOORNLOWERED_COMPOUNDMANSION_DOORNLOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2282,"name":"COMPOUNDMANSION_DOORNE_COMPOUNDMANSION_DOORNE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2284,"name":"COMPOUNDMANSION_DOORNELOWERED_COMPOUNDMANSION_DOORNELOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2286,"name":"COMPOUNDMANSION_DOORE_COMPOUNDMANSION_DOORE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2288,"name":"COMPOUNDMANSION_DOORELOWERED_COMPOUNDMANSION_DOORELOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2290,"name":"COMPOUNDMANSION_DOORNW_COMPOUNDMANSION_DOORNW","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2292,"name":"COMPOUNDMANSION_DOORNWLOWERED_COMPOUNDMANSION_DOORNWLOWERED","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2324,"name":"CAUSTICSPRAY_CAUSTICSPRAY","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2330,"name":"MORPHTORAVAGER_RAVAGER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":688,"produces_name":"RAVAGER"}}},{"id":2331,"name":"CANCEL_MORPHRAVAGER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2332,"name":"MORPH_LURKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":502,"produces_name":"LURKERMP"}}},{"id":2333,"name":"CANCEL_MORPHLURKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2338,"name":"EFFECT_CORROSIVEBILE","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2340,"name":"BURROWDOWN_RAVAGER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":690,"produces_name":"RAVAGERBURROWED"}}},{"id":2341,"name":"BURROWRAVAGERDOWN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2342,"name":"BURROWUP_RAVAGER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":688,"produces_name":"RAVAGER"}}},{"id":2344,"name":"PURIFICATIONNOVA_PURIFICATIONNOVA","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2346,"name":"EFFECT_PURIFICATIONNOVA","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2350,"name":"LOCKON_LOCKON","cast_range":7.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2354,"name":"CANCEL_LOCKON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2358,"name":"EFFECT_TACTICALJUMP","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2362,"name":"MORPH_THORHIGHIMPACTMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":691,"produces_name":"THORAP"}}},{"id":2363,"name":"THORAPMODE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2364,"name":"MORPH_THOREXPLOSIVEMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":52,"produces_name":"THOR"}}},{"id":2365,"name":"CANCEL_MORPHTHOREXPLOSIVEMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2370,"name":"LOAD_NYDUSWORM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3668},{"id":2371,"name":"UNLOADALL_NYDUSWORM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3664},{"id":2375,"name":"BEHAVIOR_PULSARBEAMON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2376,"name":"BEHAVIOR_PULSARBEAMOFF","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2383,"name":"LOCUSTMPFLYINGMORPHTOGROUND_LOCUSTMPFLYINGSWOOP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":489,"produces_name":"LOCUSTMP"}}},{"id":2385,"name":"LOCUSTMPMORPHTOAIR_LOCUSTMPFLYINGSWOOP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":693,"produces_name":"LOCUSTMPFLYING"}}},{"id":2387,"name":"EFFECT_LOCUSTSWOOP","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2389,"name":"HALLUCINATION_DISRUPTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2391,"name":"HALLUCINATION_ADEPT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2393,"name":"EFFECT_VOIDRAYPRISMATICALIGNMENT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2395,"name":"SEEKERDUMMYCHANNEL_SEEKERDUMMYCHANNEL","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2469,"name":"VOIDMPIMMORTALREVIVEREBUILD_IMMORTAL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2473,"name":"ARBITERMPSTASISFIELD_ARBITERMPSTASISFIELD","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":2475,"name":"ARBITERMPRECALL_ARBITERMPRECALL","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2477,"name":"CORSAIRMPDISRUPTIONWEB_CORSAIRMPDISRUPTIONWEB","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2479,"name":"MORPHTOGUARDIANMP_MORPHTOGUARDIANMP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":727,"produces_name":"GUARDIANMP"}}},{"id":2480,"name":"MORPHTOGUARDIANMP_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2481,"name":"MORPHTODEVOURERMP_MORPHTODEVOURERMP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":729,"produces_name":"DEVOURERMP"}}},{"id":2482,"name":"MORPHTODEVOURERMP_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2483,"name":"DEFILERMPCONSUME_DEFILERMPCONSUME","cast_range":0.5,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2485,"name":"DEFILERMPDARKSWARM_DEFILERMPDARKSWARM","cast_range":8.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2487,"name":"DEFILERMPPLAGUE_DEFILERMPPLAGUE","cast_range":8.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2489,"name":"DEFILERMPBURROW_BURROWDOWN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3661,"target":{"Morph":{"produces":730,"produces_name":"DEFILERMPBURROWED"}}},{"id":2490,"name":"DEFILERMPBURROW_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2491,"name":"DEFILERMPUNBURROW_BURROWUP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"remaps_to_ability_id":3662,"target":{"Morph":{"produces":731,"produces_name":"DEFILERMP"}}},{"id":2493,"name":"QUEENMPENSNARE_QUEENMPENSNARE","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2495,"name":"QUEENMPSPAWNBROODLINGS_QUEENMPSPAWNBROODLINGS","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2497,"name":"QUEENMPINFESTCOMMANDCENTER_QUEENMPINFESTCOMMANDCENTER","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2505,"name":"BUILD_STASISTRAP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":732,"produces_name":"ORACLESTASISTRAP"}}},{"id":2535,"name":"CANCEL_STASISTRAP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2536,"name":"ORACLESTASISTRAPACTIVATE_ACTIVATESTASISWARD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":2542,"name":"PARASITICBOMB_PARASITICBOMB","cast_range":8.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2544,"name":"ADEPTPHASESHIFT_ADEPTPHASESHIFT","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":2548,"name":"PURIFICATIONNOVAMORPHBACK_PURIFICATIONNOVA","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"Unknown"}}},{"id":2550,"name":"BEHAVIOR_HOLDFIREON_LURKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3688},{"id":2552,"name":"BEHAVIOR_HOLDFIREOFF_LURKER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3689},{"id":2554,"name":"LIBERATORMORPHTOAG_LIBERATORAGMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":734,"produces_name":"LIBERATORAG"}}},{"id":2556,"name":"LIBERATORMORPHTOAA_LIBERATORAAMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":689,"produces_name":"LIBERATOR"}}},{"id":2558,"name":"MORPH_LIBERATORAGMODE","cast_range":5.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"MorphPlace":{"produces":734,"produces_name":"LIBERATORAG"}}},{"id":2560,"name":"MORPH_LIBERATORAAMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":689,"produces_name":"LIBERATOR"}}},{"id":2588,"name":"KD8CHARGE_KD8CHARGE","cast_range":5.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":2594,"name":"CANCEL_ADEPTPHASESHIFT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2596,"name":"CANCEL_ADEPTSHADEPHASESHIFT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2598,"name":"SLAYNELEMENTALGRAB_SLAYNELEMENTALGRAB","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2600,"name":"MORPHTOCOLLAPSIBLEPURIFIERTOWERDEBRIS_MORPHTOCOLLAPSIBLEPURIFIERTOWERDEBRIS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":2601,"name":"MORPHTOCOLLAPSIBLEPURIFIERTOWERDEBRIS_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2700,"name":"EFFECT_SHADOWSTRIDE","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3687},{"id":2704,"name":"EFFECT_SPAWNLOCUSTS","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":693}}},{"id":2706,"name":"LOCUSTMPFLYINGSWOOPATTACK_LOCUSTMPFLYINGSWOOP","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":2708,"name":"MORPH_OVERLORDTRANSPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":893,"produces_name":"OVERLORDTRANSPORT"}}},{"id":2709,"name":"CANCEL_MORPHOVERLORDTRANSPORT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2714,"name":"EFFECT_GHOSTSNIPE","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":2715,"name":"CHANNELSNIPE_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":2716,"name":"PURIFYMORPHPYLON_MOTHERSHIPCOREWEAPON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":894,"produces_name":"PYLONOVERCHARGED"}}},{"id":2718,"name":"PURIFYMORPHPYLONBACK_MOTHERSHIPCOREWEAPON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"Unknown"}}},{"id":2720,"name":"RESEARCH_SHADOWSTRIKE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":141,"upgrade_name":"DARKTEMPLARBLINKUPGRADE"}}},{"id":3659,"name":"CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3660,"name":"HALT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3661,"name":"BURROWDOWN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"Unknown"}}},{"id":3662,"name":"BURROWUP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"Unknown"}}},{"id":3663,"name":"LOADALL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3664,"name":"UNLOADALL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3665,"name":"STOP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3666,"name":"HARVEST_GATHER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3667,"name":"HARVEST_RETURN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3668,"name":"LOAD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3669,"name":"UNLOADALLAT","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3671,"name":"CANCEL_LAST","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3672,"name":"CANCEL_SLOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3673,"name":"RALLY_UNITS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3674,"name":"ATTACK","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3675,"name":"EFFECT_STIM","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3676,"name":"BEHAVIOR_CLOAKON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3677,"name":"BEHAVIOR_CLOAKOFF","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3678,"name":"LAND","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"MorphPlace":{"produces":0,"produces_name":"Unknown"}}},{"id":3679,"name":"LIFT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"Unknown"}}},{"id":3680,"name":"MORPH_ROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"MorphPlace":{"produces":0,"produces_name":"Unknown"}}},{"id":3681,"name":"MORPH_UPROOT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"Unknown"}}},{"id":3682,"name":"BUILD_TECHLAB","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"BuildInstant":{"produces":5,"produces_name":"TECHLAB"}}},{"id":3683,"name":"BUILD_REACTOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"BuildInstant":{"produces":6,"produces_name":"REACTOR"}}},{"id":3684,"name":"EFFECT_SPRAY","cast_range":1.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":3685,"name":"EFFECT_REPAIR","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3686,"name":"EFFECT_MASSRECALL","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":3687,"name":"EFFECT_BLINK","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":3688,"name":"BEHAVIOR_HOLDFIREON","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3689,"name":"BEHAVIOR_HOLDFIREOFF","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3690,"name":"RALLY_WORKERS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3691,"name":"BUILD_CREEPTUMOR","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Build":{"produces":87,"produces_name":"CREEPTUMOR"}}},{"id":3707,"name":"CANCEL_VOIDRAYPRISMATICALIGNMENT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":3709,"name":"RESEARCH_ADAPTIVETALONS","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":293,"upgrade_name":"DIGGINGCLAWS"}}},{"id":3710,"name":"LURKERDENRESEARCH_RESEARCHLURKERRANGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Research":{"upgrade":127,"upgrade_name":"LURKERRANGE"}}},{"id":3739,"name":"MORPH_OBSERVERMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":82,"produces_name":"OBSERVER"}}},{"id":3741,"name":"MORPH_SURVEILLANCEMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":1911,"produces_name":"OBSERVERSIEGEMODE"}}},{"id":3743,"name":"MORPH_OVERSIGHTMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":1912,"produces_name":"OVERSEERSIEGEMODE"}}},{"id":3745,"name":"MORPH_OVERSEERMODE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":129,"produces_name":"OVERSEER"}}},{"id":3747,"name":"EFFECT_INTERFERENCEMATRIX","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3751,"name":"EFFECT_REPAIR_REPAIRDRONE","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit","remaps_to_ability_id":3685},{"id":3753,"name":"EFFECT_ANTIARMORMISSILE","cast_range":10.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3755,"name":"EFFECT_CHRONOBOOSTENERGYCOST","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3757,"name":"EFFECT_MASSRECALL_NEXUS","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point","remaps_to_ability_id":3686},{"id":3763,"name":"INFESTORENSNARE_INFESTORENSNARE","cast_range":8.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3771,"name":"ATTACK_BATTLECRUISER","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3674},{"id":3772,"name":"BATTLECRUISERATTACK_ATTACKTOWARDS","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":3773,"name":"BATTLECRUISERATTACK_ATTACKBARRAGE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":3776,"name":"MOVE_BATTLECRUISER","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3794},{"id":3777,"name":"PATROL_BATTLECRUISER","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit","remaps_to_ability_id":3795},{"id":3778,"name":"HOLDPOSITION_BATTLECRUISER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3793},{"id":3779,"name":"BATTLECRUISERMOVE_ACQUIREMOVE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3780,"name":"BATTLECRUISERMOVE_TURN","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3783,"name":"STOP_BATTLECRUISER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3665},{"id":3784,"name":"BATTLECRUISERSTOP_HOLDFIRE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3785,"name":"BATTLECRUISERSTOP_CHEER","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3786,"name":"BATTLECRUISERSTOP_DANCE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3789,"name":"VIPERPARASITICBOMBRELAY_PARASITICBOMB","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":3791,"name":"PARASITICBOMBRELAYDODGE_PARASITICBOMB","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":3793,"name":"HOLDPOSITION","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3794,"name":"MOVE","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3795,"name":"PATROL","cast_range":0.0,"energy_cost":0,"allow_minimap":true,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"PointOrUnit"},{"id":3796,"name":"UNLOADUNIT","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":3966,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPLEFTGREEN_MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPLEFTGREEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":3967,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPLEFTGREEN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":3969,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPRIGHTGREEN_MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPRIGHTGREEN","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":3970,"name":"MORPHTOCOLLAPSIBLEROCKTOWERDEBRISRAMPRIGHTGREEN_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":4109,"name":"HYDRALISKFRENZY_HYDRALISKFRENZY","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":4111,"name":"AMORPHOUSARMORCLOUD_AMORPHOUSARMORCLOUD","cast_range":9.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Point"},{"id":4113,"name":"SHIELDBATTERYRECHARGEEX5_SHIELDBATTERYRECHARGE","cast_range":6.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":true,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":4114,"name":"SHIELDBATTERYRECHARGEEX5_STOP","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":4121,"name":"MORPHTOBANELING_BANELING","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":{"Morph":{"produces":0,"produces_name":"NOTAUNIT"}}},{"id":4122,"name":"MORPHTOBANELING_CANCEL","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None","remaps_to_ability_id":3659},{"id":4124,"name":"MOTHERSHIPCLOAK_ORACLECLOAKFIELD","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":4126,"name":"ENERGYRECHARGE_ENERGYRECHARGE","cast_range":500.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"},{"id":4128,"name":"SALVAGEEFFECT_SALVAGE","cast_range":0.0,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"None"},{"id":4132,"name":"WORKERSTOPIDLEABILITYVESPENE_GATHER","cast_range":0.300048828125,"energy_cost":0,"allow_minimap":false,"allow_autocast":false,"effect":[],"buff":[],"cooldown":0,"target":"Unit"}],"Unit":[{"id":4,"name":"Colossus","race":"Protoss","supply":6.0,"cargo_size":8,"max_health":250.0,"armor":1.0,"sight":10.0,"speed":2.25,"speed_creep_mul":1.0,"attributes":["Armored","Mechanical","Massive"],"size":0,"radius":1.0,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":300,"gas":200,"time":1200.0,"tech_alias":[],"unit_alias":0,"max_shield":100.0,"is_flying":false,"weapons":[{"target_type":"Ground","damage_per_hit":10.0,"damage_splash":0,"attacks":2,"range":7.0,"cooldown":1.5,"bonuses":[{"against":"Light","damage":5.0}]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":23},{"ability":1}]},{"id":5,"name":"TechLab","race":"Terran","supply":0.0,"max_health":400.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"abilities":[{"ability":730,"requirements":[{"addon_to":21}]},{"ability":731,"requirements":[{"addon_to":21}]},{"ability":732,"requirements":[{"addon_to":21}]},{"ability":761,"requirements":[{"addon_to":27}]},{"ability":764,"requirements":[{"addon_to":27}]},{"ability":793,"requirements":[{"addon_to":28}]},{"ability":790,"requirements":[{"addon_to":28}]}],"size":0,"radius":1.125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":true,"is_worker":false,"is_townhall":false,"minerals":50,"gas":25,"time":2.0,"tech_alias":[],"unit_alias":0,"is_flying":false},{"id":6,"name":"Reactor","race":"Terran","supply":0.0,"max_health":400.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"abilities":[],"size":0,"radius":1.125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":true,"is_worker":false,"is_townhall":false,"minerals":50,"gas":50,"time":2.0,"tech_alias":[],"unit_alias":0,"is_flying":false},{"id":7,"name":"InfestorTerran","race":"Zerg","supply":0.0,"max_health":75.0,"armor":0.0,"sight":9.0,"speed":0.9375,"speed_creep_mul":1.0,"attributes":["Light","Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":78.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"weapons":[{"target_type":"Air","damage_per_hit":24.0,"damage_splash":0,"attacks":1,"range":6.0,"cooldown":1.330078125,"bonuses":[]},{"target_type":"Ground","damage_per_hit":12.0,"damage_splash":0,"attacks":1,"range":5.0,"cooldown":0.86083984375,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":23},{"ability":1},{"requirements":[{"upgrade":64}],"ability":1394}]},{"id":8,"name":"BanelingCocoon","race":"Zerg","supply":0.5,"max_health":50.0,"armor":2.0,"sight":5.0,"speed":2.5,"speed_creep_mul":1.0,"weapons":[],"attributes":["Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":50,"gas":25,"time":0.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":195},{"ability":1}]},{"id":9,"name":"Baneling","race":"Zerg","supply":0.5,"cargo_size":2,"max_health":30.0,"armor":0.0,"sight":8.0,"speed":2.5,"speed_creep_mul":1.0,"weapons":[],"attributes":["Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":50,"gas":25,"time":320.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":23},{"ability":42},{"ability":2081},{"ability":1},{"requirements":[{"upgrade":64}],"ability":1374}]},{"id":10,"name":"Mothership","race":"Protoss","supply":8.0,"max_health":350.0,"armor":2.0,"sight":14.0,"speed":2.015625,"speed_creep_mul":1.0,"attributes":["Armored","Mechanical","Psionic","Massive","Heroic"],"size":0,"radius":1.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":400,"gas":400,"time":2000.0,"tech_alias":[],"unit_alias":0,"max_shield":350.0,"is_flying":true,"weapons":[{"target_type":"Any","damage_per_hit":6.0,"damage_splash":0,"attacks":4,"range":7.0,"cooldown":2.2099609375,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":23},{"ability":142},{"ability":2244},{"ability":4124},{"ability":1}]},{"id":11,"name":"PointDefenseDrone","race":"Terran","supply":0.0,"max_health":50.0,"armor":0.0,"sight":7.0,"speed_creep_mul":1.0,"max_energy":200.0,"start_energy":200,"weapons":[],"attributes":["Light","Mechanical","Structure"],"abilities":[],"size":0,"radius":0.625,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":100,"gas":0,"time":0.0,"tech_alias":[],"unit_alias":0,"is_flying":true},{"id":12,"name":"Changeling","race":"Zerg","supply":0.0,"max_health":5.0,"armor":0.0,"sight":8.0,"speed":2.25,"speed_creep_mul":1.0,"weapons":[],"attributes":["Light","Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":0.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":19},{"ability":1}]},{"id":13,"name":"ChangelingZealot","normal_mode":12,"race":"Zerg","supply":0.0,"max_health":100.0,"armor":1.0,"sight":9.0,"speed":2.25,"speed_creep_mul":1.0,"attributes":["Light","Biological"],"size":0,"radius":0.5,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":8.0,"tech_alias":[],"unit_alias":12,"max_shield":50.0,"is_flying":false,"weapons":[{"target_type":"Ground","damage_per_hit":8.0,"damage_splash":0,"attacks":2,"range":0.10009765625,"cooldown":1.199951171875,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":19},{"ability":1}]},{"id":14,"name":"ChangelingMarineShield","normal_mode":12,"race":"Zerg","supply":0.0,"max_health":55.0,"armor":0.0,"sight":9.0,"speed":2.25,"speed_creep_mul":1.0,"attributes":["Light","Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":8.0,"tech_alias":[],"unit_alias":12,"is_flying":false,"weapons":[{"target_type":"Any","damage_per_hit":6.0,"damage_splash":0,"attacks":1,"range":5.0,"cooldown":0.86083984375,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":19},{"ability":1}]},{"id":15,"name":"ChangelingMarine","normal_mode":12,"race":"Zerg","supply":0.0,"max_health":45.0,"armor":0.0,"sight":9.0,"speed":2.25,"speed_creep_mul":1.0,"attributes":["Light","Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":8.0,"tech_alias":[],"unit_alias":12,"is_flying":false,"weapons":[{"target_type":"Any","damage_per_hit":6.0,"damage_splash":0,"attacks":1,"range":5.0,"cooldown":0.86083984375,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":19},{"ability":1}]},{"id":16,"name":"ChangelingZerglingWings","normal_mode":12,"race":"Zerg","supply":0.0,"max_health":35.0,"armor":0.0,"sight":8.0,"speed":2.953125,"speed_creep_mul":1.0,"attributes":["Light","Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":8.0,"tech_alias":[],"unit_alias":12,"is_flying":false,"weapons":[{"target_type":"Ground","damage_per_hit":5.0,"damage_splash":0,"attacks":1,"range":0.10009765625,"cooldown":0.696044921875,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":19},{"ability":1}]},{"id":17,"name":"ChangelingZergling","normal_mode":12,"race":"Zerg","supply":0.0,"max_health":35.0,"armor":0.0,"sight":8.0,"speed":2.953125,"speed_creep_mul":1.0,"attributes":["Light","Biological"],"size":0,"radius":0.375,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":0,"gas":0,"time":8.0,"tech_alias":[],"unit_alias":12,"is_flying":false,"weapons":[{"target_type":"Ground","damage_per_hit":5.0,"damage_splash":0,"attacks":1,"range":0.10009765625,"cooldown":0.696044921875,"bonuses":[]}],"abilities":[{"ability":4},{"ability":16},{"ability":17},{"ability":18},{"ability":19},{"ability":1}]},{"id":18,"name":"CommandCenter","race":"Terran","supply":-15.0,"cargo_capacity":5,"max_health":1500.0,"armor":1.0,"sight":11.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":2.75,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":true,"minerals":400,"gas":0,"time":1600.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":203},{"ability":416},{"ability":417},{"ability":524},{"ability":1},{"requirements":[{"building":22}],"ability":1450},{"requirements":[{"building":21}],"ability":1516}]},{"id":19,"name":"SupplyDepot","race":"Terran","supply":-8.0,"max_health":400.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.25,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":100,"gas":0,"time":480.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":556}]},{"id":20,"name":"Refinery","race":"Terran","supply":0.0,"max_health":500.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"abilities":[],"size":0,"radius":1.6875,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":true,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":75,"gas":0,"time":480.0,"tech_alias":[],"unit_alias":0,"is_flying":false},{"id":21,"name":"Barracks","race":"Terran","supply":0.0,"max_health":1000.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":true,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":0,"time":1040.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":195},{"ability":421},{"ability":422},{"ability":452},{"ability":560},{"ability":561},{"ability":1},{"requirements":[{"building":26,"addon":5}],"ability":562},{"requirements":[{"addon":5}],"ability":563}]},{"id":22,"name":"EngineeringBay","race":"Terran","supply":0.0,"max_health":850.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":125,"gas":0,"time":560.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":650},{"ability":651},{"ability":652},{"ability":656},{"ability":653,"requirements":[{"upgrade":7},{"building":29}]},{"ability":654,"requirements":[{"upgrade":8},{"building":29}]},{"ability":657,"requirements":[{"upgrade":11},{"building":29}]},{"ability":658,"requirements":[{"upgrade":12},{"building":29}]}]},{"id":23,"name":"MissileTurret","race":"Terran","supply":0.0,"max_health":250.0,"armor":0.0,"sight":11.0,"detection_range":11.0,"speed_creep_mul":1.0,"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":100,"gas":0,"time":400.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"weapons":[{"target_type":"Air","damage_per_hit":12.0,"damage_splash":0,"attacks":2,"range":7.0,"cooldown":0.86083984375,"bonuses":[]}],"abilities":[{"ability":4},{"ability":23},{"ability":1}]},{"id":24,"name":"Bunker","race":"Terran","supply":0.0,"cargo_capacity":4,"max_health":400.0,"armor":1.0,"sight":10.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":100,"gas":0,"time":640.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":195},{"ability":407},{"ability":4128},{"ability":1}]},{"id":25,"name":"SensorTower","race":"Terran","supply":0.0,"max_health":200.0,"armor":0.0,"sight":12.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":0.75,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":100,"gas":50,"time":400.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":4128}]},{"id":26,"name":"GhostAcademy","race":"Terran","supply":0.0,"max_health":1250.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":50,"time":640.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":820},{"requirements":[{"building":27}],"ability":710}]},{"id":27,"name":"Factory","race":"Terran","supply":0.0,"max_health":1250.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":true,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":100,"time":960.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":195},{"ability":454},{"ability":455},{"ability":485},{"ability":595},{"ability":614},{"ability":1},{"requirements":[{"addon":5}],"ability":591},{"requirements":[{"addon":5},{"building":29}],"ability":594},{"requirements":[{"building":29}],"ability":596},{"requirements":[{"addon":5}],"ability":597}]},{"id":28,"name":"Starport","race":"Terran","supply":0.0,"max_health":1300.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":true,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":100,"time":800.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":195},{"ability":487},{"ability":488},{"ability":518},{"ability":620},{"ability":624},{"ability":626},{"ability":1},{"requirements":[{"addon":5}],"ability":621},{"requirements":[{"addon":5}],"ability":622},{"requirements":[{"addon":5},{"building":30}],"ability":623}]},{"id":29,"name":"Armory","race":"Terran","supply":0.0,"max_health":750.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":50,"time":1040.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":855},{"ability":861},{"ability":864},{"ability":856,"requirements":[{"upgrade":30}]},{"ability":857,"requirements":[{"upgrade":31}]},{"ability":862,"requirements":[{"upgrade":36}]},{"ability":863,"requirements":[{"upgrade":37}]},{"ability":865,"requirements":[{"upgrade":116}]},{"ability":866,"requirements":[{"upgrade":117}]}]},{"id":30,"name":"FusionCore","race":"Terran","supply":0.0,"max_health":750.0,"armor":1.0,"sight":9.0,"speed_creep_mul":1.0,"weapons":[],"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.8125,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":150,"time":1040.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"abilities":[{"ability":1532},{"ability":1533},{"ability":1535}]},{"id":31,"name":"AutoTurret","race":"Terran","supply":0.0,"max_health":100.0,"armor":0.0,"sight":7.0,"speed_creep_mul":1.0,"attributes":["Armored","Mechanical","Structure"],"size":0,"radius":1.0,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":true,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":100,"gas":0,"time":16.0,"tech_alias":[],"unit_alias":0,"is_flying":false,"weapons":[{"target_type":"Any","damage_per_hit":18.0,"damage_splash":0,"attacks":1,"range":6.0,"cooldown":0.800048828125,"bonuses":[]}],"abilities":[{"ability":4},{"ability":23},{"ability":1}]},{"id":32,"name":"SiegeTankSieged","normal_mode":33,"race":"Terran","supply":3.0,"max_health":175.0,"armor":1.0,"sight":11.0,"speed_creep_mul":1.0,"attributes":["Armored","Mechanical"],"size":0,"radius":0.875,"accepts_addon":false,"needs_power":false,"needs_creep":false,"needs_geyser":false,"is_structure":false,"is_addon":false,"is_worker":false,"is_townhall":false,"minerals":150,"gas":125,"time":68.66796875,"tech_alias":[33],"unit_alias":33,"is_flying":false,"weapons":[{"target_type":"Ground","damage_per_hit":40.0,"damage_splash":0,"attacks":1,"range":13.0,"cooldown":3.0,"bonuses":[{"against":"Armored","damage":30.0}]}],"abilities":[{"ability":4},{"ability":23},{"ability":390},{"ability":1}]},{"id":33,"name":"SiegeTank","race":"Terran","supply":3.0,"cargo_size":4,"max_health":175.0,"a
gitextract_5hf8q6mo/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── docker-ci.yml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── README.md
├── data/
│ ├── README.md
│ └── data.json
├── dockerfiles/
│ ├── Dockerfile
│ ├── README.md
│ ├── download_maps.sh
│ ├── test_docker_image.sh
│ └── test_new_python_candidate.sh
├── docs_generate/
│ ├── Makefile
│ ├── bot_ai/
│ │ └── index.rst
│ ├── client/
│ │ └── index.rst
│ ├── conf.py
│ ├── game_data/
│ │ └── index.rst
│ ├── game_info/
│ │ └── index.rst
│ ├── game_state/
│ │ └── index.rst
│ ├── ids/
│ │ └── index.rst
│ ├── index.rst
│ ├── make.bat
│ ├── pixel_map/
│ │ └── index.rst
│ ├── position/
│ │ └── index.rst
│ ├── protocol/
│ │ └── index.rst
│ ├── score/
│ │ └── index.rst
│ ├── text_files/
│ │ ├── docker.rst
│ │ └── introduction.rst
│ ├── unit/
│ │ └── index.rst
│ ├── unit_command/
│ │ └── index.rst
│ └── units/
│ └── index.rst
├── examples/
│ ├── __init__.py
│ ├── arcade_bot.py
│ ├── bot_vs_bot.py
│ ├── competitive/
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── bot.py
│ │ ├── ladderbots.json
│ │ └── run.py
│ ├── distributed_workers.py
│ ├── external_bot.py
│ ├── fastreload.py
│ ├── host_external_norestart.py
│ ├── observer_easy_vs_easy.py
│ ├── play_tvz.py
│ ├── protoss/
│ │ ├── __init__.py
│ │ ├── cannon_rush.py
│ │ ├── find_adept_shades.py
│ │ ├── threebase_voidray.py
│ │ └── warpgate_push.py
│ ├── simulate_fight_scenario.py
│ ├── terran/
│ │ ├── __init__.py
│ │ ├── cyclone_push.py
│ │ ├── mass_reaper.py
│ │ ├── onebase_battlecruiser.py
│ │ ├── proxy_rax.py
│ │ └── ramp_wall.py
│ ├── too_slow_bot.py
│ ├── watch_replay.py
│ ├── worker_rush.py
│ ├── worker_stack_bot.py
│ └── zerg/
│ ├── __init__.py
│ ├── banes_banes_banes.py
│ ├── expand_everywhere.py
│ ├── hydralisk_push.py
│ ├── onebase_broodlord.py
│ ├── worker_split.py
│ └── zerg_rush.py
├── generate_dicts_from_data_json.py
├── generate_id_constants_from_stableid.py
├── pyproject.toml
├── sc2/
│ ├── __init__.py
│ ├── action.py
│ ├── bot_ai.py
│ ├── bot_ai_internal.py
│ ├── cache.py
│ ├── client.py
│ ├── constants.py
│ ├── controller.py
│ ├── data.py
│ ├── data.pyi
│ ├── dicts/
│ │ ├── __init__.py
│ │ ├── generic_redirect_abilities.py
│ │ ├── unit_abilities.py
│ │ ├── unit_research_abilities.py
│ │ ├── unit_tech_alias.py
│ │ ├── unit_train_build_abilities.py
│ │ ├── unit_trained_from.py
│ │ ├── unit_unit_alias.py
│ │ └── upgrade_researched_from.py
│ ├── expiring_dict.py
│ ├── game_data.py
│ ├── game_info.py
│ ├── game_state.py
│ ├── generate_ids.py
│ ├── ids/
│ │ ├── __init__.py
│ │ ├── ability_id.py
│ │ ├── buff_id.py
│ │ ├── effect_id.py
│ │ ├── id_version.py
│ │ ├── unit_typeid.py
│ │ └── upgrade_id.py
│ ├── main.py
│ ├── maps.py
│ ├── observer_ai.py
│ ├── paths.py
│ ├── pixel_map.py
│ ├── player.py
│ ├── portconfig.py
│ ├── position.py
│ ├── power_source.py
│ ├── protocol.py
│ ├── proxy.py
│ ├── py.typed
│ ├── renderer.py
│ ├── sc2process.py
│ ├── score.py
│ ├── unit.py
│ ├── unit_command.py
│ ├── units.py
│ ├── versions.py
│ └── wsl.py
└── test/
├── Dockerfile
├── __init__.py
├── autotest_bot.py
├── battery_overcharge_bot.py
├── benchmark_array_creation.py
├── benchmark_bot_ai_init.py
├── benchmark_distance_two_points.py
├── benchmark_distances_cdist.py
├── benchmark_distances_points_to_point.py
├── benchmark_distances_units.py
├── benchmark_prepare_units.py
├── damagetest_bot.py
├── generate_pickle_files_bot.py
├── pickle_data/
│ ├── 16-BitLE.xz
│ ├── 2000AtmospheresAIE.xz
│ ├── AbiogenesisLE.xz
│ ├── AbyssalReefLE.xz
│ ├── AcidPlantLE.xz
│ ├── AcolyteLE.xz
│ ├── AcropolisLE.xz
│ ├── AncientCisternAIE.xz
│ ├── Artana.xz
│ ├── AscensiontoAiurLE.xz
│ ├── AutomatonLE.xz
│ ├── BackwaterLE.xz
│ ├── Bandwidth.xz
│ ├── BattleontheBoardwalkLE.xz
│ ├── BelShirVestigeLE.xz
│ ├── BerlingradAIE.xz
│ ├── BlackburnAIE.xz
│ ├── BlackpinkLE.xz
│ ├── BlueshiftLE.xz
│ ├── CactusValleyLE.xz
│ ├── CatalystLE.xz
│ ├── CeruleanFallLE.xz
│ ├── CrystalCavern.xz
│ ├── CuriousMindsAIE.xz
│ ├── CyberForestLE.xz
│ ├── DarknessSanctuaryLE.xz
│ ├── DeathAura506.xz
│ ├── DeathAuraLE.xz
│ ├── DefendersLandingLE.xz
│ ├── DigitalFrontier.xz
│ ├── DiscoBloodbathLE.xz
│ ├── DragonScalesAIE.xz
│ ├── DreamcatcherLE.xz
│ ├── EastwatchLE.xz
│ ├── Ephemeron.xz
│ ├── EphemeronLE.xz
│ ├── Equilibrium513AIE.xz
│ ├── EternalEmpire506.xz
│ ├── EternalEmpireLE.xz
│ ├── EverDream506.xz
│ ├── EverDreamLE.xz
│ ├── FractureLE.xz
│ ├── FrostLE.xz
│ ├── GlitteringAshesAIE.xz
│ ├── GoldenAura513AIE.xz
│ ├── GoldenWall506.xz
│ ├── GoldenWallLE.xz
│ ├── GoldenauraAIE.xz
│ ├── Gresvan513AIE.xz
│ ├── GresvanAIE.xz
│ ├── HardLead513AIE.xz
│ ├── HardwireAIE.xz
│ ├── HonorgroundsLE.xz
│ ├── IceandChrome506.xz
│ ├── IceandChromeLE.xz
│ ├── InfestationStationAIE.xz
│ ├── InsideAndOutAIE.xz
│ ├── InterloperLE.xz
│ ├── JagannathaAIE.xz
│ ├── KairosJunctionLE.xz
│ ├── KingsCoveLE.xz
│ ├── LightshadeAIE.xz
│ ├── MechDepotLE.xz
│ ├── MoondanceAIE.xz
│ ├── NeonVioletSquareLE.xz
│ ├── NewRepugnancyLE.xz
│ ├── NewkirkPrecinctTE.xz
│ ├── NightshadeLE.xz
│ ├── Oceanborn513AIE.xz
│ ├── OdysseyLE.xz
│ ├── OldSunshine.xz
│ ├── OxideAIE.xz
│ ├── PaladinoTerminalLE.xz
│ ├── ParaSiteLE.xz
│ ├── PersephoneAIE.xz
│ ├── PillarsofGold506.xz
│ ├── PillarsofGoldLE.xz
│ ├── PortAleksanderLE.xz
│ ├── PrimusQ9.xz
│ ├── ProximaStationLE.xz
│ ├── PylonAIE.xz
│ ├── RedshiftLE.xz
│ ├── Reminiscence.xz
│ ├── RomanticideAIE.xz
│ ├── RoyalBloodAIE.xz
│ ├── Sanglune.xz
│ ├── SequencerLE.xz
│ ├── SimulacrumLE.xz
│ ├── SiteDelta513AIE.xz
│ ├── StargazersAIE.xz
│ ├── StasisLE.xz
│ ├── Submarine506.xz
│ ├── SubmarineLE.xz
│ ├── TheTimelessVoid.xz
│ ├── ThunderbirdLE.xz
│ ├── TorchesAIE.xz
│ ├── Treachery.xz
│ ├── Triton.xz
│ ├── Urzagol.xz
│ ├── WaterfallAIE.xz
│ ├── WintersGateLE.xz
│ ├── WorldofSleepersLE.xz
│ ├── YearZeroLE.xz
│ └── ZenLE.xz
├── queries_test_bot.py
├── real_time_worker_production.py
├── replays/
│ ├── 20220223 - GAME 1 - Astrea vs SKillous - P vs P - Curious Minds LE.SC2Replay
│ ├── 20220224 - GAME 1 - Dream vs Spirit - T vs T - Curious Minds LE.SC2Replay
│ ├── 20220224 - GAME 1 - Serral vs Dark - Z vs Z - 2000 Atmospheres LE.SC2Replay
│ ├── 20220225 - GAME 2 - Maru vs ByuN - T vs T - Hardwire LE.SC2Replay
│ └── 20220227 - GAME 2 - Reynor vs Serral - Z vs Z - Berlingrad LE.SC2Replay
├── run_example_bots_vs_computer.py
├── run_example_bots_vs_each_other.py
├── test_directions.py
├── test_expiring_dict.py
├── test_pickled_data.py
├── test_pickled_ramp.py
├── test_replays.py
├── travis_test_script.py
└── upgradestest_bot.py
SYMBOL INDEX (1283 symbols across 89 files)
FILE: examples/arcade_bot.py
class MarineSplitChallenge (line 40) | class MarineSplitChallenge(BotAI):
method on_start (line 41) | async def on_start(self):
method on_step (line 45) | async def on_step(self, iteration: int):
method position_around_unit (line 97) | def position_around_unit(
function main (line 121) | def main():
FILE: examples/bot_vs_bot.py
function main_old (line 17) | def main_old():
function main (line 31) | def main():
FILE: examples/competitive/__init__.py
function run_ladder_game (line 16) | def run_ladder_game(bot):
function join_ladder_game (line 58) | async def join_ladder_game(host, port, players, realtime, portconfig, sa...
FILE: examples/competitive/bot.py
class CompetitiveBot (line 5) | class CompetitiveBot(BotAI):
method on_start (line 6) | async def on_start(self):
method on_step (line 10) | async def on_step(self, iteration: int):
method on_end (line 14) | async def on_end(self, game_result: Result):
FILE: examples/distributed_workers.py
class TerranBot (line 9) | class TerranBot(BotAI):
method on_step (line 10) | async def on_step(self, iteration: int):
method build_workers (line 16) | async def build_workers(self):
method expand (line 21) | async def expand(self):
method build_supply (line 25) | async def build_supply(self):
FILE: examples/external_bot.py
function main (line 9) | def main():
FILE: examples/fastreload.py
function main (line 10) | def main():
FILE: examples/host_external_norestart.py
function main (line 9) | def main():
FILE: examples/observer_easy_vs_easy.py
function main (line 8) | def main():
FILE: examples/play_tvz.py
function main (line 12) | def main():
FILE: examples/protoss/cannon_rush.py
class CannonRushBot (line 11) | class CannonRushBot(BotAI):
method on_step (line 12) | async def on_step(self, iteration: int):
function main (line 62) | def main():
FILE: examples/protoss/find_adept_shades.py
class FindAdeptShadesBot (line 13) | class FindAdeptShadesBot(BotAI):
method __init__ (line 14) | def __init__(self):
method on_start (line 18) | async def on_start(self):
method on_step (line 24) | async def on_step(self, iteration: int):
function main (line 59) | def main():
FILE: examples/protoss/threebase_voidray.py
class ThreebaseVoidrayBot (line 11) | class ThreebaseVoidrayBot(BotAI):
method on_step (line 12) | async def on_step(self, iteration: int):
function main (line 122) | def main():
FILE: examples/protoss/warpgate_push.py
class WarpGateBot (line 15) | class WarpGateBot(BotAI):
method __init__ (line 16) | def __init__(self):
method warp_new_units (line 20) | async def warp_new_units(self, proxy: Unit):
method on_step (line 33) | async def on_step(self, iteration: int):
function main (line 138) | def main():
FILE: examples/simulate_fight_scenario.py
class FightBot (line 15) | class FightBot(BotAI):
method __init__ (line 16) | def __init__(self):
method on_start (line 21) | async def on_start(self):
method on_step (line 26) | async def on_step(self, iteration: int):
method reset_arena (line 44) | async def reset_arena(self):
method manage_enemy_units (line 63) | async def manage_enemy_units(self):
method manage_own_units (line 67) | async def manage_own_units(self):
function main (line 80) | def main():
FILE: examples/terran/cyclone_push.py
class CyclonePush (line 12) | class CyclonePush(BotAI):
method select_target (line 13) | def select_target(self) -> Point2:
method on_step (line 31) | async def on_step(self, iteration: int):
function main (line 121) | def main():
FILE: examples/terran/mass_reaper.py
class MassReaperBot (line 26) | class MassReaperBot(BotAI):
method __init__ (line 27) | def __init__(self):
method on_step (line 31) | async def on_step(self, iteration: int):
method neighbors4 (line 266) | def neighbors4(position: Point2, distance: float = 1) -> set[Point2]:
method neighbors8 (line 272) | def neighbors8(self, position: Point2, distance: float = 1) -> set[Poi...
method my_distribute_workers (line 283) | async def my_distribute_workers(self, performance_heavy=True, only_sat...
function main (line 423) | def main():
FILE: examples/terran/onebase_battlecruiser.py
class BCRushBot (line 15) | class BCRushBot(BotAI):
method select_target (line 16) | def select_target(self) -> tuple[Point2, bool]:
method on_step (line 31) | async def on_step(self, iteration: int):
function main (line 184) | def main():
FILE: examples/terran/proxy_rax.py
class ProxyRaxBot (line 12) | class ProxyRaxBot(BotAI):
method on_start (line 13) | async def on_start(self):
method on_step (line 16) | async def on_step(self, iteration: int):
function main (line 63) | def main():
FILE: examples/terran/ramp_wall.py
class RampWallBot (line 18) | class RampWallBot(BotAI):
method __init__ (line 19) | def __init__(self):
method on_step (line 22) | async def on_step(self, iteration: int):
method on_building_construction_started (line 111) | async def on_building_construction_started(self, unit: Unit):
method on_building_construction_complete (line 114) | async def on_building_construction_complete(self, unit: Unit):
method draw_ramp_points (line 117) | def draw_ramp_points(self):
method draw_expansions (line 136) | def draw_expansions(self):
method draw_pathing_grid (line 143) | def draw_pathing_grid(self):
method draw_placement_grid (line 162) | def draw_placement_grid(self):
method draw_vision_blockers (line 181) | def draw_vision_blockers(self):
method draw_visibility_pixelmap (line 191) | def draw_visibility_pixelmap(self):
method draw_example (line 205) | def draw_example(self):
method draw_facing_units (line 247) | def draw_facing_units(self):
function main (line 263) | def main():
FILE: examples/too_slow_bot.py
class SlowBot (line 11) | class SlowBot(ProxyRaxBot):
method on_step (line 12) | async def on_step(self, iteration: int):
function main (line 17) | def main():
FILE: examples/watch_replay.py
class ObserverBot (line 10) | class ObserverBot(ObserverAI):
method on_start (line 16) | async def on_start(self):
method on_step (line 19) | async def on_step(self, iteration: int):
FILE: examples/worker_rush.py
class WorkerRushBot (line 8) | class WorkerRushBot(BotAI):
method on_step (line 9) | async def on_step(self, iteration: int):
function main (line 15) | def main():
FILE: examples/worker_stack_bot.py
class WorkerStackBot (line 30) | class WorkerStackBot(BotAI):
method __init__ (line 31) | def __init__(self):
method on_start (line 40) | async def on_start(self):
method assign_workers (line 44) | async def assign_workers(self):
method on_step (line 66) | async def on_step(self, iteration: int):
function main (line 105) | def main():
FILE: examples/zerg/banes_banes_banes.py
class BanesBanesBanes (line 15) | class BanesBanesBanes(BotAI):
method select_target (line 21) | def select_target(self) -> Point2:
method on_step (line 26) | async def on_step(self, iteration: int):
function main (line 129) | def main():
FILE: examples/zerg/expand_everywhere.py
class ExpandEverywhere (line 14) | class ExpandEverywhere(BotAI):
method on_start (line 15) | async def on_start(self):
method on_step (line 19) | async def on_step(self, iteration: int):
method on_building_construction_complete (line 63) | async def on_building_construction_complete(self, unit: Unit):
function main (line 70) | def main():
FILE: examples/zerg/hydralisk_push.py
class Hydralisk (line 16) | class Hydralisk(BotAI):
method select_target (line 17) | def select_target(self) -> Point2:
method on_step (line 22) | async def on_step(self, iteration: int):
function main (line 127) | def main():
FILE: examples/zerg/onebase_broodlord.py
class BroodlordBot (line 16) | class BroodlordBot(BotAI):
method select_target (line 17) | def select_target(self) -> Point2:
method on_step (line 22) | async def on_step(self, iteration: int):
function main (line 129) | def main():
FILE: examples/zerg/worker_split.py
class WorkerSplitBot (line 20) | class WorkerSplitBot(BotAI):
method on_before_start (line 21) | async def on_before_start(self):
method on_start (line 30) | async def on_start(self):
method on_step (line 33) | async def on_step(self, iteration: int):
function main (line 42) | def main():
FILE: examples/zerg/zerg_rush.py
class ZergRushBot (line 18) | class ZergRushBot(BotAI):
method __init__ (line 19) | def __init__(self):
method on_start (line 22) | async def on_start(self):
method on_step (line 25) | async def on_step(self, iteration: int):
method draw_creep_pixelmap (line 127) | def draw_creep_pixelmap(self):
method on_end (line 139) | async def on_end(self, game_result: Result):
function main (line 144) | def main():
FILE: generate_dicts_from_data_json.py
function get_map_file_path (line 29) | def get_map_file_path() -> Path:
class OrderedDict2 (line 35) | class OrderedDict2(OrderedDict):
method __repr__ (line 36) | def __repr__(self):
class OrderedSet2 (line 46) | class OrderedSet2(set):
method __repr__ (line 47) | def __repr__(self):
function dump_dict_to_file (line 53) | def dump_dict_to_file(
function generate_init_file (line 65) | def generate_init_file(dict_file_paths: list[Path], file_path: Path, fil...
function get_unit_train_build_abilities (line 77) | def get_unit_train_build_abilities(data):
function get_upgrade_abilities (line 244) | def get_upgrade_abilities(data):
function get_unit_created_from (line 337) | def get_unit_created_from(unit_train_abilities: dict):
function get_upgrade_researched_from (line 349) | def get_upgrade_researched_from(unit_research_abilities: dict):
function get_unit_abilities (line 361) | def get_unit_abilities(data: dict):
function generate_unit_alias_dict (line 384) | def generate_unit_alias_dict(data: dict):
function generate_redirect_abilities_dict (line 429) | def generate_redirect_abilities_dict(data: dict):
function main (line 454) | def main():
FILE: sc2/__init__.py
function is_submodule (line 4) | def is_submodule(path):
FILE: sc2/action.py
function combine_actions (line 15) | def combine_actions(action_iter: list[UnitCommand]):
FILE: sc2/bot_ai.py
class BotAI (line 39) | class BotAI(BotAIInternal):
method time (line 45) | def time(self) -> float:
method time_formatted (line 50) | def time_formatted(self) -> str:
method step_time (line 56) | def step_time(self) -> tuple[float, float, float, float]:
method alert (line 73) | def alert(self, alert_code: Alert) -> bool:
method start_location (line 115) | def start_location(self) -> Point2:
method enemy_start_locations (line 123) | def enemy_start_locations(self) -> list[Point2]:
method main_base_ramp (line 128) | def main_base_ramp(self) -> Ramp:
method expansion_locations_list (line 151) | def expansion_locations_list(self) -> list[Point2]:
method expansion_locations_dict (line 159) | def expansion_locations_dict(self) -> dict[Point2, Units]:
method units_created (line 182) | def units_created(self) -> Counter[UnitTypeId]:
method get_available_abilities (line 201) | async def get_available_abilities(
method expand_now (line 218) | async def expand_now(
method get_next_expansion (line 249) | async def get_next_expansion(self) -> Point2 | None:
method distribute_workers (line 274) | async def distribute_workers(self, resource_ratio: float = 2) -> None:
method owned_expansions (line 381) | def owned_expansions(self) -> dict[Point2, Unit]:
method calculate_supply_cost (line 394) | def calculate_supply_cost(self, unit_type: UnitTypeId) -> float:
method can_feed (line 422) | def can_feed(self, unit_type: UnitTypeId) -> bool:
method calculate_unit_value (line 437) | def calculate_unit_value(self, unit_type: UnitTypeId) -> Cost:
method calculate_cost (line 452) | def calculate_cost(self, item_id: UnitTypeId | UpgradeId | AbilityId) ...
method can_afford (line 508) | def can_afford(self, item_id: UnitTypeId | UpgradeId | AbilityId, chec...
method can_cast (line 535) | async def can_cast(
method select_build_worker (line 602) | def select_build_worker(self, pos: Unit | Point2, force: bool = False)...
method can_place_single (line 631) | async def can_place_single(self, building: AbilityId | UnitTypeId, pos...
method can_place (line 642) | async def can_place(self, building: AbilityData | AbilityId | UnitType...
method find_placement (line 682) | async def find_placement(
method already_pending_upgrade (line 754) | def already_pending_upgrade(self, upgrade_type: UpgradeId) -> float:
method structure_type_build_progress (line 782) | def structure_type_build_progress(self, structure_type: UnitTypeId | i...
method tech_requirement_progress (line 835) | def tech_requirement_progress(self, structure_type: UnitTypeId) -> float:
method already_pending (line 873) | def already_pending(self, unit_type: UpgradeId | UnitTypeId) -> float:
method worker_en_route_to_build (line 904) | def worker_en_route_to_build(self, unit_type: UnitTypeId) -> float:
method structures_without_construction_SCVs (line 916) | def structures_without_construction_SCVs(self) -> Units:
method build (line 937) | async def build(
method train (line 981) | def train(
method research (line 1128) | def research(self, upgrade_type: UpgradeId) -> bool:
method chat_send (line 1210) | async def chat_send(self, message: str, team_only: bool = False) -> None:
method in_map_bounds (line 1222) | def in_map_bounds(self, pos: Point2 | tuple[float, float] | list[float...
method get_terrain_height (line 1236) | def get_terrain_height(self, pos: Point2 | Unit) -> int:
method get_terrain_z_height (line 1245) | def get_terrain_z_height(self, pos: Point2 | Unit) -> float:
method in_placement_grid (line 1253) | def in_placement_grid(self, pos: Point2 | Unit) -> bool:
method in_pathing_grid (line 1263) | def in_pathing_grid(self, pos: Point2 | Unit) -> bool:
method is_visible (line 1271) | def is_visible(self, pos: Point2 | Unit) -> bool:
method has_creep (line 1280) | def has_creep(self, pos: Point2 | Unit) -> bool:
method on_unit_destroyed (line 1288) | async def on_unit_destroyed(self, unit_tag: int) -> None:
method on_unit_created (line 1299) | async def on_unit_created(self, unit: Unit) -> None:
method on_unit_type_changed (line 1304) | async def on_unit_type_changed(self, unit: Unit, previous_type: UnitTy...
method on_building_construction_started (line 1318) | async def on_building_construction_started(self, unit: Unit) -> None:
method on_building_construction_complete (line 1326) | async def on_building_construction_complete(self, unit: Unit) -> None:
method on_upgrade_complete (line 1334) | async def on_upgrade_complete(self, upgrade: UpgradeId) -> None:
method on_unit_took_damage (line 1341) | async def on_unit_took_damage(self, unit: Unit, amount_damage_taken: f...
method on_enemy_unit_entered_vision (line 1358) | async def on_enemy_unit_entered_vision(self, unit: Unit) -> None:
method on_enemy_unit_left_vision (line 1365) | async def on_enemy_unit_left_vision(self, unit_tag: int) -> None:
method on_before_start (line 1379) | async def on_before_start(self) -> None:
method on_start (line 1387) | async def on_start(self) -> None:
method on_step (line 1393) | async def on_step(self, iteration: int):
method on_end (line 1403) | async def on_end(self, game_result: Result) -> None:
FILE: sc2/bot_ai_internal.py
class BotAIInternal (line 50) | class BotAIInternal(ABC):
method __init__ (line 53) | def __init__(self: BotAI) -> None:
method _initialize_variables (line 57) | def _initialize_variables(self: BotAI) -> None:
method _game_info (line 133) | def _game_info(self) -> GameInfo:
method _game_data (line 144) | def _game_data(self) -> GameData:
method _client (line 155) | def _client(self) -> Client:
method expansion_locations (line 166) | def expansion_locations(self: BotAI) -> dict[Point2, Units]:
method _cluster_center (line 178) | def _cluster_center(self, group: list[Unit]) -> Point2:
method _find_expansion_location (line 204) | def _find_expansion_location(
method _has_opposite_side_geyser_layout (line 245) | def _has_opposite_side_geyser_layout(self, minerals: list[Unit], gas_g...
method _find_expansion_locations (line 320) | def _find_expansion_locations(self) -> None:
method _correct_zerg_supply (line 407) | def _correct_zerg_supply(self) -> None:
method _abilities_count_and_build_progress (line 427) | def _abilities_count_and_build_progress(self) -> tuple[Counter[Ability...
method _worker_orders (line 462) | def _worker_orders(self) -> Counter[AbilityId]:
method do (line 480) | def do(
method synchronous_do (line 550) | async def synchronous_do(self: BotAI, action: UnitCommand):
method _do_actions (line 573) | async def _do_actions(self, actions: list[UnitCommand], prevent_double...
method prevent_double_actions (line 587) | def prevent_double_actions(action: UnitCommand) -> bool:
method _prepare_start (line 616) | def _prepare_start(
method _prepare_first_step (line 650) | def _prepare_first_step(self) -> None:
method _prepare_step (line 660) | def _prepare_step(self: BotAI, state: GameState, proto_game_info: sc_p...
method _prepare_units (line 701) | def _prepare_units(self: BotAI) -> None:
method _after_step (line 805) | async def _after_step(self) -> int:
method _advance_steps (line 827) | async def _advance_steps(self: BotAI, steps: int) -> None:
method issue_events (line 840) | async def issue_events(self: BotAI) -> None:
method _issue_unit_added_events (line 855) | async def _issue_unit_added_events(self: BotAI) -> None:
method _issue_upgrade_events (line 872) | async def _issue_upgrade_events(self: BotAI) -> None:
method _issue_building_events (line 879) | async def _issue_building_events(self: BotAI) -> None:
method _issue_vision_events (line 911) | async def _issue_vision_events(self: BotAI) -> None:
method _issue_unit_dead_events (line 929) | async def _issue_unit_dead_events(self: BotAI) -> None:
method _units_count (line 937) | def _units_count(self) -> int:
method _pdist (line 942) | def _pdist(self) -> np.ndarray:
method _cdist (line 950) | def _cdist(self) -> np.ndarray:
method _calculate_distances_method1 (line 957) | def _calculate_distances_method1(self) -> np.ndarray:
method _calculate_distances_method2 (line 974) | def _calculate_distances_method2(self) -> np.ndarray:
method _calculate_distances_method3 (line 991) | def _calculate_distances_method3(self) -> np.ndarray:
method square_to_condensed (line 1008) | def square_to_condensed(self, i, j) -> int:
method convert_tuple_to_numpy_array (line 1018) | def convert_tuple_to_numpy_array(pos: tuple[float, float]) -> np.ndarray:
method distance_math_hypot (line 1026) | def distance_math_hypot(
method distance_math_hypot_squared (line 1034) | def distance_math_hypot_squared(
method _distance_squared_unit_to_unit_method0 (line 1041) | def _distance_squared_unit_to_unit_method0(self, unit1: Unit, unit2: U...
method _distance_squared_unit_to_unit_method1 (line 1047) | def _distance_squared_unit_to_unit_method1(self, unit1: Unit, unit2: U...
method _distance_squared_unit_to_unit_method2 (line 1060) | def _distance_squared_unit_to_unit_method2(self, unit1: Unit, unit2: U...
method _distance_pos_to_pos (line 1067) | def _distance_pos_to_pos(
method _distance_units_to_pos (line 1075) | def _distance_units_to_pos(
method _distance_unit_to_points (line 1084) | def _distance_unit_to_points(
method _distances_override_functions (line 1094) | def _distances_override_functions(self, method: int = 0) -> None:
FILE: sc2/cache.py
class CacheDict (line 12) | class CacheDict(dict[Hashable, Any]):
method retrieve_and_set (line 13) | def retrieve_and_set(self, key: Hashable, func: Callable[[], T]) -> T:
class property_cache_once_per_frame (line 21) | class property_cache_once_per_frame(property): # noqa: N801
method __init__ (line 32) | def __init__(self, func: Callable[[BotAI], T], name: str | None = None...
method __set__ (line 38) | def __set__(self, obj: BotAI, value: T) -> None:
method __get__ (line 44) | def __get__(self, obj: BotAI, _type=None) -> T:
FILE: sc2/client.py
class Client (line 30) | class Client(Protocol):
method __init__ (line 31) | def __init__(self, ws: ClientWebSocketResponse, save_replay_path: str ...
method in_game (line 55) | def in_game(self) -> bool:
method join_game (line 58) | async def join_game(
method leave (line 116) | async def leave(self) -> None:
method save_replay (line 134) | async def save_replay(self, path: str) -> None:
method observation (line 141) | async def observation(self, game_loop: int | None = None):
method step (line 165) | async def step(self, step_size: int | None = None):
method get_game_data (line 170) | async def get_game_data(self) -> GameData:
method dump_data (line 176) | async def dump_data(
method get_game_info (line 203) | async def get_game_info(self) -> GameInfo:
method actions (line 207) | async def actions(self, actions: list[UnitCommand], return_successes: ...
method query_pathing (line 229) | async def query_pathing(self, start: Unit | Point2 | Point3, end: Poin...
method query_pathings (line 247) | async def query_pathings(self, zipped_list: list[tuple[Unit | Point2 |...
method _query_building_placement_fast (line 269) | async def _query_building_placement_fast(
method query_building_placement (line 292) | async def query_building_placement(
method query_available_abilities (line 318) | async def query_available_abilities(
method query_available_abilities_with_tag (line 342) | async def query_available_abilities_with_tag(
method chat_send (line 355) | async def chat_send(self, message: str, team_only: bool) -> None:
method toggle_autocast (line 368) | async def toggle_autocast(self, units: list[Unit] | Units, ability: Ab...
method debug_create_unit (line 394) | async def debug_create_unit(
method debug_kill_unit (line 420) | async def debug_kill_unit(self, unit_tags: Unit | Units | list[int] | ...
method move_camera (line 435) | async def move_camera(self, position: Unit | Units | Point2 | Point3) ...
method obs_move_camera (line 456) | async def obs_move_camera(self, position: Unit | Units | Point2 | Poin...
method move_camera_spatial (line 475) | async def move_camera_spatial(self, position: Point2 | Point3) -> None:
method debug_text_simple (line 487) | def debug_text_simple(self, text: str) -> None:
method debug_text_screen (line 491) | def debug_text_screen(
method debug_text_2d (line 512) | def debug_text_2d(
method debug_text_world (line 521) | def debug_text_world(
method debug_text_3d (line 542) | def debug_text_3d(
method debug_line_out (line 551) | def debug_line_out(
method debug_box_out (line 572) | def debug_box_out(
method debug_box2_out (line 593) | def debug_box2_out(
method debug_sphere_out (line 613) | def debug_sphere_out(
method _send_debug (line 631) | async def _send_debug(self) -> None:
method debug_leave (line 692) | async def debug_leave(self) -> None:
method debug_set_unit_value (line 695) | async def debug_set_unit_value(
method debug_hang (line 730) | async def debug_hang(self, delay_in_seconds: float) -> None:
method debug_show_map (line 746) | async def debug_show_map(self) -> None:
method debug_control_enemy (line 752) | async def debug_control_enemy(self) -> None:
method debug_food (line 758) | async def debug_food(self) -> None:
method debug_free (line 764) | async def debug_free(self) -> None:
method debug_all_resources (line 770) | async def debug_all_resources(self) -> None:
method debug_god (line 776) | async def debug_god(self) -> None:
method debug_minerals (line 782) | async def debug_minerals(self) -> None:
method debug_gas (line 788) | async def debug_gas(self) -> None:
method debug_cooldown (line 794) | async def debug_cooldown(self) -> None:
method debug_tech_tree (line 800) | async def debug_tech_tree(self) -> None:
method debug_upgrade (line 806) | async def debug_upgrade(self) -> None:
method debug_fast_build (line 812) | async def debug_fast_build(self) -> None:
method quick_save (line 818) | async def quick_save(self) -> None:
method quick_load (line 823) | async def quick_load(self) -> None:
class DrawItem (line 832) | class DrawItem:
method to_debug_color (line 834) | def to_debug_color(color: tuple[float, float, float] | list[float] | P...
class DrawItemScreenText (line 854) | class DrawItemScreenText(DrawItem):
method __init__ (line 855) | def __init__(
method to_proto (line 867) | def to_proto(self):
method __hash__ (line 877) | def __hash__(self) -> int:
class DrawItemWorldText (line 881) | class DrawItemWorldText(DrawItem):
method __init__ (line 882) | def __init__(
method to_proto (line 894) | def to_proto(self):
method __hash__ (line 904) | def __hash__(self) -> int:
class DrawItemLine (line 908) | class DrawItemLine(DrawItem):
method __init__ (line 909) | def __init__(
method to_proto (line 919) | def to_proto(self):
method __hash__ (line 925) | def __hash__(self) -> int:
class DrawItemBox (line 929) | class DrawItemBox(DrawItem):
method __init__ (line 930) | def __init__(
method to_proto (line 940) | def to_proto(self):
method __hash__ (line 947) | def __hash__(self) -> int:
class DrawItemSphere (line 951) | class DrawItemSphere(DrawItem):
method __init__ (line 952) | def __init__(
method to_proto (line 962) | def to_proto(self):
method __hash__ (line 967) | def __hash__(self) -> int:
FILE: sc2/constants.py
function return_NOTAUNIT (line 362) | def return_NOTAUNIT() -> UnitTypeId:
FILE: sc2/controller.py
class Controller (line 18) | class Controller(Protocol):
method __init__ (line 19) | def __init__(self, ws: ClientWebSocketResponse, process: SC2Process) -...
method running (line 24) | def running(self) -> bool:
method create_game (line 27) | async def create_game(self, game_map, players, realtime: bool, random_...
method request_available_maps (line 56) | async def request_available_maps(self):
method request_save_map (line 61) | async def request_save_map(self, download_path: str):
method request_replay_info (line 67) | async def request_replay_info(self, replay_path: str):
method start_replay (line 73) | async def start_replay(self, replay_path: str, realtime: bool, observe...
FILE: sc2/data.pyi
class CreateGameError (line 18) | class CreateGameError(Enum):
class PlayerType (line 28) | class PlayerType(Enum):
class Difficulty (line 33) | class Difficulty(Enum):
class AIBuild (line 45) | class AIBuild(Enum):
class Status (line 53) | class Status(Enum):
class Result (line 62) | class Result(Enum):
class Alert (line 68) | class Alert(Enum):
class ChatChannel (line 92) | class ChatChannel(Enum):
class Race (line 96) | class Race(Enum):
class DisplayType (line 114) | class DisplayType(Enum):
class Alliance (line 120) | class Alliance(Enum):
class CloakState (line 126) | class CloakState(Enum):
class Attribute (line 133) | class Attribute(Enum):
class TargetType (line 146) | class TargetType(Enum):
class Target (line 152) | class Target(Enum):
class ActionResult (line 160) | class ActionResult(Enum):
FILE: sc2/expiring_dict.py
class ExpiringDict (line 12) | class ExpiringDict(OrderedDict[Hashable, Any]):
method __init__ (line 33) | def __init__(self, bot: BotAI, max_age_frames: int = 1) -> None:
method frame (line 43) | def frame(self) -> int:
method __contains__ (line 46) | def __contains__(self, key: Hashable) -> bool:
method __getitem__ (line 57) | def __getitem__(self, key: Hashable, with_age: bool = False) -> Any:
method __setitem__ (line 69) | def __setitem__(self, key: Hashable, value: Any) -> None:
method __repr__ (line 74) | def __repr__(self) -> str:
method __str__ (line 84) | def __str__(self) -> str:
method __iter__ (line 87) | def __iter__(self) -> Iterable[Hashable]:
method __len__ (line 93) | def __len__(self) -> int:
method pop (line 102) | def pop(self, key: Hashable, default: Any = None, with_age: bool = Fal...
method get (line 119) | def get(self, key: Hashable, default: Any = None, with_age: bool = Fal...
method update (line 135) | def update(self, other_dict: dict[Hashable, Any]) -> None:
method items (line 140) | def items(self) -> Iterable[tuple[Hashable, Any]]:
method keys (line 147) | def keys(self) -> Iterable[Hashable]:
method values (line 154) | def values(self) -> Iterable[Any]:
FILE: sc2/game_data.py
class GameData (line 22) | class GameData:
method __init__ (line 23) | def __init__(self, data: sc2api_pb2.ResponseData) -> None:
method calculate_ability_cost (line 36) | def calculate_ability_cost(self, ability: AbilityData | AbilityId | Un...
class AbilityData (line 75) | class AbilityData:
method id_exists (line 79) | def id_exists(cls, ability_id: int) -> bool:
method __init__ (line 86) | def __init__(self, game_data: GameData, proto: data_pb2.AbilityData) -...
method __repr__ (line 93) | def __repr__(self) -> str:
method id (line 97) | def id(self) -> AbilityId:
method exact_id (line 104) | def exact_id(self) -> AbilityId:
method link_name (line 109) | def link_name(self) -> str:
method button_name (line 114) | def button_name(self) -> str:
method friendly_name (line 119) | def friendly_name(self) -> str:
method is_free_morph (line 124) | def is_free_morph(self) -> bool:
method cost (line 128) | def cost(self) -> Cost:
class UnitTypeData (line 132) | class UnitTypeData:
method __init__ (line 133) | def __init__(self, game_data: GameData, proto: data_pb2.UnitTypeData) ...
method __repr__ (line 147) | def __repr__(self) -> str:
method id (line 151) | def id(self) -> UnitTypeId:
method name (line 155) | def name(self) -> str:
method creation_ability (line 159) | def creation_ability(self) -> AbilityData | None:
method footprint_radius (line 167) | def footprint_radius(self) -> float | None:
method attributes (line 174) | def attributes(self) -> list[Attribute]:
method has_attribute (line 177) | def has_attribute(self, attr: Attribute) -> bool:
method has_minerals (line 182) | def has_minerals(self) -> bool:
method has_vespene (line 186) | def has_vespene(self) -> bool:
method cargo_size (line 190) | def cargo_size(self) -> int:
method tech_requirement (line 195) | def tech_requirement(self) -> UnitTypeId | None:
method tech_alias (line 204) | def tech_alias(self) -> list[UnitTypeId] | None:
method unit_alias (line 215) | def unit_alias(self) -> UnitTypeId | None:
method race (line 225) | def race(self) -> Race:
method cost (line 229) | def cost(self) -> Cost:
method cost_zerg_corrected (line 233) | def cost_zerg_corrected(self) -> Cost:
method morph_cost (line 240) | def morph_cost(self) -> Cost | None:
class UpgradeData (line 275) | class UpgradeData:
method __init__ (line 276) | def __init__(self, game_data: GameData, proto: data_pb2.UpgradeData) -...
method __repr__ (line 284) | def __repr__(self) -> str:
method name (line 288) | def name(self) -> str:
method research_ability (line 292) | def research_ability(self) -> AbilityData | None:
method cost (line 300) | def cost(self) -> Cost:
class Cost (line 305) | class Cost:
method __repr__ (line 315) | def __repr__(self) -> str:
method __eq__ (line 318) | def __eq__(self, other: Cost) -> bool:
method __ne__ (line 321) | def __ne__(self, other: Cost) -> bool:
method __bool__ (line 324) | def __bool__(self) -> bool:
method __add__ (line 327) | def __add__(self, other: Cost) -> Cost:
method __sub__ (line 335) | def __sub__(self, other: Cost) -> Cost:
method __mul__ (line 339) | def __mul__(self, other: int) -> Cost:
method __rmul__ (line 342) | def __rmul__(self, other: int) -> Cost:
FILE: sc2/game_info.py
class Ramp (line 18) | class Ramp:
method x_offset (line 23) | def x_offset(self) -> float:
method y_offset (line 28) | def y_offset(self) -> float:
method _height_map (line 33) | def _height_map(self) -> PixelMap:
method size (line 37) | def size(self) -> int:
method height_at (line 40) | def height_at(self, p: Point2) -> int:
method upper (line 44) | def upper(self) -> frozenset[Point2]:
method upper2_for_ramp_wall (line 58) | def upper2_for_ramp_wall(self) -> frozenset[Point2]:
method top_center (line 64) | def top_center(self) -> Point2:
method lower (line 70) | def lower(self) -> frozenset[Point2]:
method bottom_center (line 83) | def bottom_center(self) -> Point2:
method barracks_in_middle (line 89) | def barracks_in_middle(self) -> Point2 | None:
method depot_in_middle (line 105) | def depot_in_middle(self) -> Point2 | None:
method corner_depots (line 125) | def corner_depots(self) -> set[Point2]:
method barracks_can_fit_addon (line 144) | def barracks_can_fit_addon(self) -> bool:
method barracks_correct_placement (line 154) | def barracks_correct_placement(self) -> Point2 | None:
method protoss_wall_pylon (line 166) | def protoss_wall_pylon(self) -> Point2 | None:
method protoss_wall_buildings (line 182) | def protoss_wall_buildings(self) -> frozenset[Point2]:
method protoss_wall_warpin (line 206) | def protoss_wall_warpin(self) -> Point2 | None:
class GameInfo (line 224) | class GameInfo:
method __init__ (line 225) | def __init__(self, proto: sc2api_pb2.ResponseGameInfo) -> None:
method _find_ramps_and_vision_blockers (line 254) | def _find_ramps_and_vision_blockers(self) -> tuple[list[Ramp], frozens...
method _find_groups (line 280) | def _find_groups(self, points: Iterable[Point2], minimum_points_per_gr...
FILE: sc2/game_state.py
class Blip (line 28) | class Blip:
method __init__ (line 29) | def __init__(self, proto: raw_pb2.Unit) -> None:
method is_blip (line 36) | def is_blip(self) -> bool:
method is_snapshot (line 41) | def is_snapshot(self) -> bool:
method is_visible (line 45) | def is_visible(self) -> bool:
method alliance (line 49) | def alliance(self) -> int:
method is_mine (line 53) | def is_mine(self) -> bool:
method is_enemy (line 57) | def is_enemy(self) -> bool:
method position (line 61) | def position(self) -> Point2:
method position3d (line 66) | def position3d(self) -> Point3:
class Common (line 71) | class Common:
method __init__ (line 86) | def __init__(self, proto: sc2api_pb2.PlayerCommon) -> None:
method __getattr__ (line 89) | def __getattr__(self, attr) -> int:
class EffectData (line 94) | class EffectData:
method __init__ (line 95) | def __init__(self, proto: raw_pb2.Effect | raw_pb2.Unit, fake: bool = ...
method id (line 104) | def id(self) -> EffectId | str:
method positions (line 111) | def positions(self) -> set[Point2]:
method alliance (line 117) | def alliance(self) -> Alliance:
method is_mine (line 121) | def is_mine(self) -> bool:
method is_enemy (line 126) | def is_enemy(self) -> bool:
method owner (line 131) | def owner(self) -> int:
method radius (line 135) | def radius(self) -> float:
method __repr__ (line 140) | def __repr__(self) -> str:
class ChatMessage (line 145) | class ChatMessage:
class AbilityLookupTemplateClass (line 151) | class AbilityLookupTemplateClass:
method exact_id (line 155) | def exact_id(self) -> AbilityId:
method generic_id (line 159) | def generic_id(self) -> AbilityId:
class ActionRawUnitCommand (line 167) | class ActionRawUnitCommand(AbilityLookupTemplateClass):
class ActionRawToggleAutocast (line 176) | class ActionRawToggleAutocast(AbilityLookupTemplateClass):
class ActionRawCameraMove (line 182) | class ActionRawCameraMove:
class ActionError (line 187) | class ActionError(AbilityLookupTemplateClass):
class GameState (line 193) | class GameState:
method __init__ (line 194) | def __init__(
method dead_units (line 238) | def dead_units(self) -> set[int]:
method chat (line 246) | def chat(self) -> list[ChatMessage]:
method alerts (line 255) | def alerts(self) -> list[int]:
method actions (line 264) | def actions(self) -> list[ActionRawUnitCommand | ActionRawToggleAutoca...
method actions_unit_commands (line 318) | def actions_unit_commands(self) -> list[ActionRawUnitCommand]:
method actions_toggle_autocast (line 327) | def actions_toggle_autocast(self) -> list[ActionRawToggleAutocast]:
method action_errors (line 336) | def action_errors(self) -> list[ActionError]:
FILE: sc2/generate_ids.py
class IdGenerator (line 20) | class IdGenerator:
method __init__ (line 21) | def __init__(
method make_key (line 60) | def make_key(key: str) -> str:
method parse_data (line 66) | def parse_data(self, data) -> dict[str, Any]:
method parse_simple (line 123) | def parse_simple(self, d, data):
method generate_python_code (line 142) | def generate_python_code(self, enums) -> None:
method update_ids_from_stableid_json (line 196) | def update_ids_from_stableid_json(self) -> None:
method reimport_ids (line 209) | def reimport_ids() -> None:
FILE: sc2/ids/ability_id.py
class AbilityId (line 8) | class AbilityId(enum.Enum):
method __repr__ (line 1391) | def __repr__(self) -> str:
method _missing_ (line 1395) | def _missing_(cls, value: int) -> AbilityId:
FILE: sc2/ids/buff_id.py
class BuffId (line 8) | class BuffId(enum.Enum):
method __repr__ (line 313) | def __repr__(self) -> str:
method _missing_ (line 317) | def _missing_(cls, value: int) -> BuffId:
FILE: sc2/ids/effect_id.py
class EffectId (line 8) | class EffectId(enum.Enum):
method __repr__ (line 23) | def __repr__(self) -> str:
FILE: sc2/ids/unit_typeid.py
class UnitTypeId (line 8) | class UnitTypeId(enum.Enum):
method __repr__ (line 2015) | def __repr__(self) -> str:
FILE: sc2/ids/upgrade_id.py
class UpgradeId (line 8) | class UpgradeId(enum.Enum):
method __repr__ (line 316) | def __repr__(self) -> str:
FILE: sc2/main.py
class GameMatch (line 39) | class GameMatch:
method __post_init__ (line 56) | def __post_init__(self) -> None:
method needed_sc2_count (line 76) | def needed_sc2_count(self) -> int:
method host_game_kwargs (line 80) | def host_game_kwargs(self) -> dict[str, Any]:
method __repr__ (line 89) | def __repr__(self) -> str:
function _play_game_human (line 97) | async def _play_game_human(client, player_id, realtime, game_time_limit):
function _play_game_ai (line 111) | async def _play_game_ai(
function _play_game (line 212) | async def _play_game(
function _play_replay (line 240) | async def _play_replay(client: Client, ai, realtime: bool = False, playe...
function _setup_host_game (line 328) | async def _setup_host_game(
function _host_game (line 342) | async def _host_game(
function _host_game_aiter (line 383) | async def _host_game_aiter(
function _host_game_iter (line 418) | def _host_game_iter(*args, **kwargs):
function _join_game (line 425) | async def _join_game(
function _setup_replay (line 453) | async def _setup_replay(server, replay_path, realtime, observed_id):
function _host_replay (line 458) | async def _host_replay(
function get_replay_version (line 467) | def get_replay_version(replay_path: str | Path) -> tuple[str, str]:
function run_game (line 480) | def run_game(
function run_replay (line 549) | def run_replay(ai: ObserverAI, replay_path: Path | str, realtime: bool =...
function play_from_websocket (line 562) | async def play_from_websocket(
function run_match (line 601) | async def run_match(controllers: list[Controller], match: GameMatch, clo...
function process_results (line 647) | def process_results(players: list[AbstractPlayer], async_results: list[R...
function maintain_SCII_count (line 668) | async def maintain_SCII_count(count: int, controllers: list[Controller],...
function run_multiple_games (line 743) | def run_multiple_games(matches: list[GameMatch]):
function a_run_multiple_games (line 750) | async def a_run_multiple_games(matches: list[GameMatch]) -> list[dict[Ab...
function a_run_multiple_games_nokill (line 783) | async def a_run_multiple_games_nokill(matches: list[GameMatch]) -> list[...
FILE: sc2/maps.py
function get (line 10) | def get(name: str) -> Map:
class Map (line 23) | class Map:
method __init__ (line 24) | def __init__(self, path: Path) -> None:
method name (line 37) | def name(self) -> str:
method data (line 41) | def data(self) -> bytes:
method __repr__ (line 45) | def __repr__(self) -> str:
method is_map_file (line 49) | def is_map_file(cls, file: Path) -> bool:
method matches_target_map_name (line 53) | def matches_target_map_name(cls, file: Path, name: str) -> bool:
FILE: sc2/observer_ai.py
class ObserverAI (line 17) | class ObserverAI(BotAIInternal):
method time (line 21) | def time(self) -> float:
method time_formatted (line 26) | def time_formatted(self) -> str:
method alert (line 31) | def alert(self, alert_code: Alert) -> bool:
method start_location (line 73) | def start_location(self) -> Point2:
method enemy_start_locations (line 81) | def enemy_start_locations(self) -> list[Point2]:
method get_available_abilities (line 85) | async def get_available_abilities(
method on_unit_destroyed (line 102) | async def on_unit_destroyed(self, unit_tag: int) -> None:
method on_unit_created (line 111) | async def on_unit_created(self, unit: Unit) -> None:
method on_building_construction_started (line 116) | async def on_building_construction_started(self, unit: Unit) -> None:
method on_building_construction_complete (line 124) | async def on_building_construction_complete(self, unit: Unit) -> None:
method on_upgrade_complete (line 132) | async def on_upgrade_complete(self, upgrade: UpgradeId) -> None:
method on_start (line 139) | async def on_start(self) -> None:
method on_step (line 145) | async def on_step(self, iteration: int):
method on_end (line 155) | async def on_end(self, game_result: Result) -> None:
FILE: sc2/paths.py
function platform_detect (line 51) | def platform_detect():
function get_home (line 61) | def get_home():
function get_user_sc2_install (line 68) | def get_user_sc2_install():
function get_env (line 85) | def get_env() -> None:
function get_runner_args (line 90) | def get_runner_args(cwd):
function latest_executeble (line 106) | def latest_executeble(versions_dir, base_build=None):
class _MetaPaths (line 127) | class _MetaPaths(type):
method __setup (line 130) | def __setup(cls):
method __getattr__ (line 151) | def __getattr__(cls, attr):
class Paths (line 156) | class Paths(metaclass=_MetaPaths):
FILE: sc2/pixel_map.py
class PixelMap (line 12) | class PixelMap:
method __init__ (line 13) | def __init__(self, proto: ImageData, in_bits: bool = False) -> None:
method width (line 31) | def width(self) -> int:
method height (line 35) | def height(self) -> int:
method bits_per_pixel (line 39) | def bits_per_pixel(self) -> int:
method bytes_per_pixel (line 43) | def bytes_per_pixel(self) -> int:
method __getitem__ (line 46) | def __getitem__(self, pos: _PointLike) -> int:
method __setitem__ (line 53) | def __setitem__(self, pos: _PointLike, value: int) -> None:
method is_set (line 64) | def is_set(self, p: tuple[int, int]) -> bool:
method is_empty (line 67) | def is_empty(self, p: tuple[int, int]) -> bool:
method copy (line 70) | def copy(self) -> PixelMap:
method flood_fill (line 73) | def flood_fill(self, start_point: Point2, pred: Callable[[int], bool])...
method flood_fill_all (line 92) | def flood_fill_all(self, pred: Callable[[int], bool]) -> set[frozenset...
method print (line 105) | def print(self, wide: bool = False) -> None:
method save_image (line 111) | def save_image(self, filename: str | Path) -> None:
method plot (line 120) | def plot(self) -> None:
FILE: sc2/player.py
class AbstractPlayer (line 11) | class AbstractPlayer(ABC):
method __init__ (line 12) | def __init__(
method needs_sc2 (line 48) | def needs_sc2(self) -> bool:
class Human (line 52) | class Human(AbstractPlayer):
method __init__ (line 53) | def __init__(self, race: Race, name: str | None = None, fullscreen: bo...
method __str__ (line 56) | def __str__(self) -> str:
class Bot (line 62) | class Bot(AbstractPlayer):
method __init__ (line 63) | def __init__(self, race: Race, ai: BotAI, name: str | None = None, ful...
method __str__ (line 72) | def __str__(self) -> str:
class Computer (line 78) | class Computer(AbstractPlayer):
method __init__ (line 79) | def __init__(
method __str__ (line 84) | def __str__(self) -> str:
class Observer (line 90) | class Observer(AbstractPlayer):
method __init__ (line 91) | def __init__(self) -> None:
method __str__ (line 94) | def __str__(self) -> str:
class Player (line 98) | class Player(AbstractPlayer):
method __init__ (line 99) | def __init__(
method from_proto (line 115) | def from_proto(cls, proto: sc2api_pb2.PlayerInfo) -> Player:
class BotProcess (line 128) | class BotProcess(AbstractPlayer):
method __init__ (line 147) | def __init__(
method __repr__ (line 171) | def __repr__(self) -> str:
method cmd_line (line 176) | def cmd_line(
FILE: sc2/portconfig.py
class Portconfig (line 9) | class Portconfig:
method __init__ (line 28) | def __init__(
method clean (line 44) | def clean(self) -> None:
method __str__ (line 48) | def __str__(self) -> str:
method as_json (line 52) | def as_json(self) -> str:
method contiguous_ports (line 56) | def contiguous_ports(cls, guests: int = 1, attempts: int = 40) -> Port...
method from_json (line 72) | def from_json(cls, json_data: bytearray | bytes | str) -> Portconfig:
FILE: sc2/position.py
class HasPosition2D (line 19) | class HasPosition2D(Protocol):
method position (line 21) | def position(self) -> Point2: ...
function _sign (line 31) | def _sign(num: SupportsFloat | SupportsIndex) -> float:
class Pointlike (line 35) | class Pointlike(tuple[float, ...]):
method position (line 39) | def position(self: T) -> T:
method distance_to (line 42) | def distance_to(self, target: _PosLike) -> float:
method distance_to_point2 (line 50) | def distance_to_point2(self, p: _PointLike) -> float:
method _distance_squared (line 57) | def _distance_squared(self, p2: _PointLike) -> float:
method sort_by_distance (line 64) | def sort_by_distance(self, ps: Iterable[_TPosLike]) -> list[_TPosLike]:
method closest (line 72) | def closest(self, ps: Iterable[_TPosLike]) -> _TPosLike:
method distance_to_closest (line 80) | def distance_to_closest(self, ps: Iterable[_TPosLike]) -> float:
method furthest (line 93) | def furthest(self, ps: Iterable[_TPosLike]) -> _TPosLike:
method distance_to_furthest (line 101) | def distance_to_furthest(self, ps: Iterable[_PosLike]) -> float:
method offset (line 115) | def offset(self: T, p: _PointLike) -> T:
method unit_axes_towards (line 122) | def unit_axes_towards(self: T, p: _PointLike) -> T:
method towards (line 129) | def towards(self: T, p: _PosLike, distance: float = 1, limit: bool = F...
method __eq__ (line 150) | def __eq__(self, other: Any) -> bool:
method __hash__ (line 156) | def __hash__(self) -> int:
class Point2 (line 160) | class Point2(Pointlike):
method from_proto (line 164) | def from_proto(
method as_Point2D (line 173) | def as_Point2D(self) -> common_pb.Point2D:
method as_PointI (line 177) | def as_PointI(self) -> common_pb.PointI:
method rounded (line 182) | def rounded(self) -> Point2:
method length (line 186) | def length(self) -> float:
method normalized (line 191) | def normalized(self: Point2 | Point3) -> Point2:
method x (line 199) | def x(self) -> float:
method y (line 203) | def y(self) -> float:
method to2 (line 207) | def to2(self) -> Point2:
method to3 (line 211) | def to3(self) -> Point3:
method round (line 214) | def round(self, decimals: int) -> Point2:
method offset (line 218) | def offset(self: T, p: _PointLike) -> T:
method random_on_distance (line 221) | def random_on_distance(self, distance: float | tuple[float, float] | l...
method towards_with_random_angle (line 232) | def towards_with_random_angle(
method circle_intersection (line 243) | def circle_intersection(self, p: Point2, r: float) -> set[Point2]:
method neighbors4 (line 271) | def neighbors4(self: T) -> set[T]:
method neighbors8 (line 280) | def neighbors8(self: T) -> set[T]:
method negative_offset (line 288) | def negative_offset(self: T, other: Point2) -> T:
method __add__ (line 291) | def __add__(self, other: Point2) -> Point2:
method __sub__ (line 294) | def __sub__(self, other: Point2) -> Point2:
method __neg__ (line 297) | def __neg__(self: T) -> T:
method __abs__ (line 300) | def __abs__(self) -> float:
method __bool__ (line 303) | def __bool__(self) -> bool:
method __mul__ (line 306) | def __mul__(self, other: _PointLike | float) -> Point2:
method __rmul__ (line 311) | def __rmul__(self, other: _PointLike | float) -> Point2:
method __truediv__ (line 314) | def __truediv__(self, other: float | Point2) -> Point2:
method is_same_as (line 319) | def is_same_as(self, other: Point2, dist: float = 0.001) -> bool:
method direction_vector (line 322) | def direction_vector(self, other: Point2) -> Point2:
method manhattan_distance (line 326) | def manhattan_distance(self, other: Point2) -> float:
method center (line 333) | def center(points: list[Point2]) -> Point2:
class Point3 (line 343) | class Point3(Point2):
method from_proto (line 345) | def from_proto(cls, data: common_pb.Point | Point3) -> Point3:
method as_Point (line 352) | def as_Point(self) -> common_pb.Point:
method rounded (line 356) | def rounded(self) -> Point3:
method z (line 360) | def z(self) -> float:
method to3 (line 364) | def to3(self) -> Point3:
method __add__ (line 367) | def __add__(self, other: Point2 | Point3) -> Point3:
class Size (line 373) | class Size(Point2):
method from_proto (line 375) | def from_proto(
method width (line 384) | def width(self) -> float:
method height (line 388) | def height(self) -> float:
class Rect (line 392) | class Rect(Point2):
method from_proto (line 394) | def from_proto(cls, data: common_pb.RectangleI) -> Rect:
method x (line 402) | def x(self) -> float:
method y (line 406) | def y(self) -> float:
method width (line 410) | def width(self) -> float:
method height (line 414) | def height(self) -> float:
method right (line 418) | def right(self) -> float:
method top (line 423) | def top(self) -> float:
method size (line 428) | def size(self) -> Size:
method center (line 432) | def center(self) -> Point2:
method offset (line 435) | def offset(self, p: _PointLike) -> Rect:
FILE: sc2/power_source.py
class PowerSource (line 10) | class PowerSource:
method __post_init__ (line 15) | def __post_init__(self) -> None:
method from_proto (line 19) | def from_proto(cls, proto: raw_pb2.PowerSource) -> PowerSource:
method covers (line 22) | def covers(self, position: Point2) -> bool:
method __repr__ (line 25) | def __repr__(self) -> str:
class PsionicMatrix (line 30) | class PsionicMatrix:
method from_proto (line 34) | def from_proto(cls, proto: list[raw_pb2.PowerSource]) -> PsionicMatrix:
method covers (line 37) | def covers(self, position: Point2) -> bool:
FILE: sc2/protocol.py
class ProtocolError (line 17) | class ProtocolError(Exception):
method is_game_over_error (line 19) | def is_game_over_error(self) -> bool:
class ConnectionAlreadyClosedError (line 23) | class ConnectionAlreadyClosedError(ProtocolError):
class Protocol (line 27) | class Protocol:
method __init__ (line 28) | def __init__(self, ws: ClientWebSocketResponse) -> None:
method __request (line 38) | async def __request(self, request: sc_pb.Request) -> sc_pb.Response:
method _execute (line 70) | async def _execute(self, create_game: sc_pb.RequestCreateGame) -> sc_p...
method _execute (line 72) | async def _execute(self, join_game: sc_pb.RequestJoinGame) -> sc_pb.Re...
method _execute (line 74) | async def _execute(self, restart_game: sc_pb.RequestRestartGame) -> sc...
method _execute (line 76) | async def _execute(self, start_replay: sc_pb.RequestStartReplay) -> sc...
method _execute (line 78) | async def _execute(self, leave_game: sc_pb.RequestLeaveGame) -> sc_pb....
method _execute (line 80) | async def _execute(self, quick_save: sc_pb.RequestQuickSave) -> sc_pb....
method _execute (line 82) | async def _execute(self, quick_load: sc_pb.RequestQuickLoad) -> sc_pb....
method _execute (line 84) | async def _execute(self, quit: sc_pb.RequestQuit) -> sc_pb.Response: ...
method _execute (line 86) | async def _execute(self, game_info: sc_pb.RequestGameInfo) -> sc_pb.Re...
method _execute (line 88) | async def _execute(self, action: sc_pb.RequestAction) -> sc_pb.Respons...
method _execute (line 90) | async def _execute(self, observation: sc_pb.RequestObservation) -> sc_...
method _execute (line 92) | async def _execute(self, obs_action: sc_pb.RequestObserverAction) -> s...
method _execute (line 94) | async def _execute(self, step: sc_pb.RequestStep) -> sc_pb.Response: ...
method _execute (line 96) | async def _execute(self, data: sc_pb.RequestData) -> sc_pb.Response: ...
method _execute (line 98) | async def _execute(self, query: RequestQuery) -> sc_pb.Response: ...
method _execute (line 100) | async def _execute(self, save_replay: sc_pb.RequestSaveReplay) -> sc_p...
method _execute (line 102) | async def _execute(self, map_command: sc_pb.RequestMapCommand) -> sc_p...
method _execute (line 104) | async def _execute(self, replay_info: sc_pb.RequestReplayInfo) -> sc_p...
method _execute (line 106) | async def _execute(self, available_maps: sc_pb.RequestAvailableMaps) -...
method _execute (line 108) | async def _execute(self, save_map: sc_pb.RequestSaveMap) -> sc_pb.Resp...
method _execute (line 110) | async def _execute(self, ping: sc_pb.RequestPing) -> sc_pb.Response: ...
method _execute (line 112) | async def _execute(self, debug: sc_pb.RequestDebug) -> sc_pb.Response:...
method _execute (line 113) | async def _execute(self, **kwargs) -> sc_pb.Response:
method ping (line 129) | async def ping(self):
method quit (line 133) | async def quit(self) -> None:
FILE: sc2/proxy.py
class Proxy (line 23) | class Proxy:
method __init__ (line 29) | def __init__(
method parse_request (line 50) | async def parse_request(self, msg) -> None:
method get_response (line 68) | async def get_response(self):
method parse_response (line 88) | async def parse_response(self, response_bytes):
method get_result (line 115) | async def get_result(self) -> None:
method proxy_handler (line 127) | async def proxy_handler(self, request) -> WebSocketResponse:
method play_with_proxy (line 168) | async def play_with_proxy(self, startport):
FILE: sc2/renderer.py
class Renderer (line 18) | class Renderer:
method __init__ (line 19) | def __init__(self, client: Client, map_size: tuple[float, float], mini...
method render (line 34) | async def render(self, observation: ResponseObservation) -> None:
method _update_window (line 130) | async def _update_window(self) -> None:
method _on_mouse_press (line 146) | def _on_mouse_press(self, x, y, button, _modifiers) -> None:
method _on_mouse_release (line 153) | def _on_mouse_release(self, x, y, button, _modifiers) -> None:
method _on_mouse_drag (line 160) | def _on_mouse_drag(self, x, y, _dx, _dy, buttons, _modifiers) -> None:
FILE: sc2/sc2process.py
class KillSwitch (line 26) | class KillSwitch:
method add (line 30) | def add(cls, value) -> None:
method kill_all (line 35) | def kill_all(cls) -> None:
class SC2Process (line 41) | class SC2Process:
method __init__ (line 57) | def __init__(
method __aenter__ (line 98) | async def __aenter__(self) -> Controller:
method __aexit__ (line 118) | async def __aexit__(self, *args) -> None:
method ws_url (line 124) | def ws_url(self) -> str:
method versions (line 128) | def versions(self):
method find_data_hash (line 133) | def find_data_hash(self, target_sc2_version: str) -> str | None:
method find_base_dir (line 141) | def find_base_dir(self, target_sc2_version: str) -> str | None:
method _launch (line 148) | def _launch(self):
method _connect (line 214) | async def _connect(self) -> ClientWebSocketResponse:
method _close_connection (line 242) | async def _close_connection(self) -> None:
method _clean (line 251) | def _clean(self, verbose: bool = True) -> None:
FILE: sc2/score.py
class ScoreDetails (line 6) | class ScoreDetails:
method __init__ (line 11) | def __init__(self, proto: score_pb2.Score) -> None:
method summary (line 16) | def summary(self) -> list[list[float]]:
method score_type (line 112) | def score_type(self):
method score (line 116) | def score(self):
method idle_production_time (line 120) | def idle_production_time(self):
method idle_worker_time (line 124) | def idle_worker_time(self):
method total_value_units (line 128) | def total_value_units(self):
method total_value_structures (line 132) | def total_value_structures(self):
method killed_value_units (line 136) | def killed_value_units(self):
method killed_value_structures (line 140) | def killed_value_structures(self):
method collected_minerals (line 144) | def collected_minerals(self):
method collected_vespene (line 148) | def collected_vespene(self):
method collection_rate_minerals (line 152) | def collection_rate_minerals(self):
method collection_rate_vespene (line 156) | def collection_rate_vespene(self):
method spent_minerals (line 160) | def spent_minerals(self):
method spent_vespene (line 164) | def spent_vespene(self):
method food_used_none (line 168) | def food_used_none(self):
method food_used_army (line 172) | def food_used_army(self):
method food_used_economy (line 176) | def food_used_economy(self):
method food_used_technology (line 180) | def food_used_technology(self):
method food_used_upgrade (line 184) | def food_used_upgrade(self):
method killed_minerals_none (line 188) | def killed_minerals_none(self):
method killed_minerals_army (line 192) | def killed_minerals_army(self):
method killed_minerals_economy (line 196) | def killed_minerals_economy(self):
method killed_minerals_technology (line 200) | def killed_minerals_technology(self):
method killed_minerals_upgrade (line 204) | def killed_minerals_upgrade(self):
method killed_vespene_none (line 208) | def killed_vespene_none(self):
method killed_vespene_army (line 212) | def killed_vespene_army(self):
method killed_vespene_economy (line 216) | def killed_vespene_economy(self):
method killed_vespene_technology (line 220) | def killed_vespene_technology(self):
method killed_vespene_upgrade (line 224) | def killed_vespene_upgrade(self):
method lost_minerals_none (line 228) | def lost_minerals_none(self):
method lost_minerals_army (line 232) | def lost_minerals_army(self):
method lost_minerals_economy (line 236) | def lost_minerals_economy(self):
method lost_minerals_technology (line 240) | def lost_minerals_technology(self):
method lost_minerals_upgrade (line 244) | def lost_minerals_upgrade(self):
method lost_vespene_none (line 248) | def lost_vespene_none(self):
method lost_vespene_army (line 252) | def lost_vespene_army(self):
method lost_vespene_economy (line 256) | def lost_vespene_economy(self):
method lost_vespene_technology (line 260) | def lost_vespene_technology(self):
method lost_vespene_upgrade (line 264) | def lost_vespene_upgrade(self):
method friendly_fire_minerals_none (line 268) | def friendly_fire_minerals_none(self):
method friendly_fire_minerals_army (line 272) | def friendly_fire_minerals_army(self):
method friendly_fire_minerals_economy (line 276) | def friendly_fire_minerals_economy(self):
method friendly_fire_minerals_technology (line 280) | def friendly_fire_minerals_technology(self):
method friendly_fire_minerals_upgrade (line 284) | def friendly_fire_minerals_upgrade(self):
method friendly_fire_vespene_none (line 288) | def friendly_fire_vespene_none(self):
method friendly_fire_vespene_army (line 292) | def friendly_fire_vespene_army(self):
method friendly_fire_vespene_economy (line 296) | def friendly_fire_vespene_economy(self):
method friendly_fire_vespene_technology (line 300) | def friendly_fire_vespene_technology(self):
method friendly_fire_vespene_upgrade (line 304) | def friendly_fire_vespene_upgrade(self):
method used_minerals_none (line 308) | def used_minerals_none(self):
method used_minerals_army (line 312) | def used_minerals_army(self):
method used_minerals_economy (line 316) | def used_minerals_economy(self):
method used_minerals_technology (line 320) | def used_minerals_technology(self):
method used_minerals_upgrade (line 324) | def used_minerals_upgrade(self):
method used_vespene_none (line 328) | def used_vespene_none(self):
method used_vespene_army (line 332) | def used_vespene_army(self):
method used_vespene_economy (line 336) | def used_vespene_economy(self):
method used_vespene_technology (line 340) | def used_vespene_technology(self):
method used_vespene_upgrade (line 344) | def used_vespene_upgrade(self):
method total_used_minerals_none (line 348) | def total_used_minerals_none(self):
method total_used_minerals_army (line 352) | def total_used_minerals_army(self):
method total_used_minerals_economy (line 356) | def total_used_minerals_economy(self):
method total_used_minerals_technology (line 360) | def total_used_minerals_technology(self):
method total_used_minerals_upgrade (line 364) | def total_used_minerals_upgrade(self):
method total_used_vespene_none (line 368) | def total_used_vespene_none(self):
method total_used_vespene_army (line 372) | def total_used_vespene_army(self):
method total_used_vespene_economy (line 376) | def total_used_vespene_economy(self):
method total_used_vespene_technology (line 380) | def total_used_vespene_technology(self):
method total_used_vespene_upgrade (line 384) | def total_used_vespene_upgrade(self):
method total_damage_dealt_life (line 388) | def total_damage_dealt_life(self):
method total_damage_dealt_shields (line 392) | def total_damage_dealt_shields(self):
method total_damage_dealt_energy (line 396) | def total_damage_dealt_energy(self):
method total_damage_taken_life (line 400) | def total_damage_taken_life(self):
method total_damage_taken_shields (line 404) | def total_damage_taken_shields(self):
method total_damage_taken_energy (line 408) | def total_damage_taken_energy(self):
method total_healed_life (line 412) | def total_healed_life(self):
method total_healed_shields (line 416) | def total_healed_shields(self):
method total_healed_energy (line 420) | def total_healed_energy(self):
method current_apm (line 424) | def current_apm(self):
method current_effective_apm (line 428) | def current_effective_apm(self):
FILE: sc2/unit.py
class RallyTarget (line 69) | class RallyTarget:
method from_proto (line 74) | def from_proto(cls, proto: raw_pb2.RallyTarget) -> RallyTarget:
class UnitOrder (line 82) | class UnitOrder:
method from_proto (line 88) | def from_proto(cls, proto: raw_pb2.UnitOrder, bot_object: BotAI) -> Un...
method __repr__ (line 100) | def __repr__(self) -> str:
class Unit (line 104) | class Unit(HasPosition2D):
method __init__ (line 107) | def __init__(
method __repr__ (line 127) | def __repr__(self) -> str:
method type_id (line 132) | def type_id(self) -> UnitTypeId:
method _type_data (line 138) | def _type_data(self) -> UnitTypeData:
method _creation_ability (line 143) | def _creation_ability(self) -> AbilityData | None:
method name (line 148) | def name(self) -> str:
method race (line 153) | def race(self) -> Race:
method tag (line 158) | def tag(self) -> int:
method is_structure (line 163) | def is_structure(self) -> bool:
method is_light (line 168) | def is_light(self) -> bool:
method is_armored (line 173) | def is_armored(self) -> bool:
method is_biological (line 178) | def is_biological(self) -> bool:
method is_mechanical (line 183) | def is_mechanical(self) -> bool:
method is_massive (line 188) | def is_massive(self) -> bool:
method is_psionic (line 193) | def is_psionic(self) -> bool:
method tech_alias (line 198) | def tech_alias(self) -> list[UnitTypeId] | None:
method unit_alias (line 205) | def unit_alias(self) -> UnitTypeId | None:
method _weapons (line 212) | def _weapons(self):
method can_attack (line 217) | def can_attack(self) -> bool:
method can_attack_both (line 223) | def can_attack_both(self) -> bool:
method can_attack_ground (line 228) | def can_attack_ground(self) -> bool:
method ground_dps (line 237) | def ground_dps(self) -> float:
method ground_range (line 246) | def ground_range(self) -> float:
method can_attack_air (line 259) | def can_attack_air(self) -> bool:
method air_dps (line 268) | def air_dps(self) -> float:
method air_range (line 277) | def air_range(self) -> float:
method bonus_damage (line 288) | def bonus_damage(self) -> tuple[float, str] | None:
method armor (line 300) | def armor(self) -> float:
method sight_range (line 305) | def sight_range(self) -> float:
method movement_speed (line 310) | def movement_speed(self) -> float:
method real_speed (line 317) | def real_speed(self) -> float:
method calculate_speed (line 321) | def calculate_speed(self, upgrades: set[UpgradeId] | None = None) -> f...
method distance_per_step (line 370) | def distance_per_step(self) -> float:
method distance_to_weapon_ready (line 376) | def distance_to_weapon_ready(self) -> float:
method is_mineral_field (line 381) | def is_mineral_field(self) -> bool:
method is_vespene_geyser (line 386) | def is_vespene_geyser(self) -> bool:
method health (line 391) | def health(self) -> float:
method health_max (line 396) | def health_max(self) -> float:
method health_percentage (line 401) | def health_percentage(self) -> float:
method shield (line 408) | def shield(self) -> float:
method shield_max (line 413) | def shield_max(self) -> float:
method shield_percentage (line 418) | def shield_percentage(self) -> float:
method shield_health_percentage (line 425) | def shield_health_percentage(self) -> float:
method energy (line 434) | def energy(self) -> float:
method energy_max (line 439) | def energy_max(self) -> float:
method energy_percentage (line 444) | def energy_percentage(self) -> float:
method age_in_frames (line 451) | def age_in_frames(self) -> int:
method age (line 456) | def age(self) -> float:
method is_memory (line 461) | def is_memory(self) -> bool:
method is_snapshot (line 466) | def is_snapshot(self) -> bool:
method is_visible (line 478) | def is_visible(self) -> bool:
method is_placeholder (line 488) | def is_placeholder(self) -> bool:
method alliance (line 506) | def alliance(self) -> int:
method is_mine (line 511) | def is_mine(self) -> bool:
method is_enemy (line 516) | def is_enemy(self) -> bool:
method owner_id (line 521) | def owner_id(self) -> int:
method position_tuple (line 526) | def position_tuple(self) -> tuple[float, float]:
method position (line 531) | def position(self) -> Point2:
method position3d (line 536) | def position3d(self) -> Point3:
method distance_to (line 540) | def distance_to(self, p: Unit | _PointLike) -> float:
method distance_to_squared (line 550) | def distance_to_squared(self, p: Unit | _PointLike) -> float:
method target_in_range (line 560) | def target_in_range(self, target: Unit, bonus_distance: float = 0) -> ...
method in_ability_cast_range (line 579) | def in_ability_cast_range(self, ability_id: AbilityId, target: Unit | ...
method calculate_damage_vs_target (line 603) | def calculate_damage_vs_target(
method calculate_dps_vs_target (line 811) | def calculate_dps_vs_target(
method facing (line 832) | def facing(self) -> float:
method is_facing (line 836) | def is_facing(self, other_unit: Unit, angle_error: float = 0.05) -> bool:
method footprint_radius (line 852) | def footprint_radius(self) -> float | None:
method radius (line 864) | def radius(self) -> float:
method build_progress (line 869) | def build_progress(self) -> float:
method is_ready (line 874) | def is_ready(self) -> bool:
method cloak (line 879) | def cloak(self) -> CloakState:
method is_cloaked (line 886) | def is_cloaked(self) -> bool:
method is_revealed (line 891) | def is_revealed(self) -> bool:
method can_be_attacked (line 896) | def can_be_attacked(self) -> bool:
method buffs (line 901) | def buffs(self) -> frozenset[BuffId]:
method is_carrying_minerals (line 906) | def is_carrying_minerals(self) -> bool:
method is_carrying_vespene (line 911) | def is_carrying_vespene(self) -> bool:
method is_carrying_resource (line 916) | def is_carrying_resource(self) -> bool:
method detect_range (line 921) | def detect_range(self) -> float:
method is_detector (line 926) | def is_detector(self) -> bool:
method radar_range (line 932) | def radar_range(self) -> float:
method is_selected (line 936) | def is_selected(self) -> bool:
method is_on_screen (line 941) | def is_on_screen(self) -> bool:
method is_blip (line 946) | def is_blip(self) -> bool:
method is_powered (line 951) | def is_powered(self) -> bool:
method is_active (line 956) | def is_active(self) -> bool:
method mineral_contents (line 963) | def mineral_contents(self) -> int:
method vespene_contents (line 968) | def vespene_contents(self) -> int:
method has_vespene (line 973) | def has_vespene(self) -> bool:
method is_flying (line 979) | def is_flying(self) -> bool:
method is_burrowed (line 984) | def is_burrowed(self) -> bool:
method is_hallucination (line 989) | def is_hallucination(self) -> bool:
method attack_upgrade_level (line 994) | def attack_upgrade_level(self) -> int:
method armor_upgrade_level (line 1000) | def armor_upgrade_level(self) -> int:
method shield_upgrade_level (line 1005) | def shield_upgrade_level(self) -> int:
method buff_duration_remain (line 1011) | def buff_duration_remain(self) -> int:
method buff_duration_max (line 1017) | def buff_duration_max(self) -> int:
method orders (line 1025) | def orders(self) -> list[UnitOrder]:
method order_target (line 1032) | def order_target(self) -> int | Point2 | None:
method is_idle (line 1043) | def is_idle(self) -> bool:
method is_using_ability (line 1047) | def is_using_ability(self, abilities: AbilityId | set[AbilityId]) -> b...
method is_moving (line 1057) | def is_moving(self) -> bool:
method is_attacking (line 1063) | def is_attacking(self) -> bool:
method is_patrolling (line 1069) | def is_patrolling(self) -> bool:
method is_gathering (line 1075) | def is_gathering(self) -> bool:
method is_returning (line 1081) | def is_returning(self) -> bool:
method is_collecting (line 1087) | def is_collecting(self) -> bool:
method is_constructing_scv (line 1093) | def is_constructing_scv(self) -> bool:
method is_transforming (line 1099) | def is_transforming(self) -> bool:
method is_repairing (line 1105) | def is_repairing(self) -> bool:
method add_on_tag (line 1111) | def add_on_tag(self) -> int:
method has_add_on (line 1116) | def has_add_on(self) -> bool:
method has_techlab (line 1121) | def has_techlab(self) -> bool:
method has_reactor (line 1126) | def has_reactor(self) -> bool:
method add_on_land_position (line 1131) | def add_on_land_position(self) -> Point2:
method add_on_position (line 1140) | def add_on_position(self) -> Point2:
method passengers (line 1153) | def passengers(self) -> set[Unit]:
method passengers_tags (line 1159) | def passengers_tags(self) -> set[int]:
method cargo_used (line 1164) | def cargo_used(self) -> int:
method has_cargo (line 1170) | def has_cargo(self) -> bool:
method cargo_size (line 1175) | def cargo_size(self) -> int:
method cargo_max (line 1180) | def cargo_max(self) -> int:
method cargo_left (line 1185) | def cargo_left(self) -> int:
method assigned_harvesters (line 1190) | def assigned_harvesters(self) -> int:
method ideal_harvesters (line 1195) | def ideal_harvesters(self) -> int:
method surplus_harvesters (line 1201) | def surplus_harvesters(self) -> int:
method weapon_cooldown (line 1209) | def weapon_cooldown(self) -> float:
method weapon_ready (line 1224) | def weapon_ready(self) -> bool:
method engaged_target_tag (line 1229) | def engaged_target_tag(self) -> int:
method rally_targets (line 1234) | def rally_targets(self) -> list[RallyTarget]:
method has_buff (line 1240) | def has_buff(self, buff: BuffId) -> bool:
method train (line 1248) | def train(
method build (line 1272) | def build(
method build_gas (line 1307) | def build_gas(
method research (line 1338) | def research(
method warp_in (line 1361) | def warp_in(
method attack (line 1384) | def attack(self, target: Unit | Point2, queue: bool = False) -> UnitCo...
method smart (line 1393) | def smart(self, target: Unit | Point2, queue: bool = False) -> UnitCom...
method gather (line 1401) | def gather(self, target: Unit, queue: bool = False) -> UnitCommand | b...
method return_resource (line 1410) | def return_resource(self, queue: bool = False) -> UnitCommand | bool:
method move (line 1417) | def move(self, position: Unit | Point2, queue: bool = False) -> UnitCo...
method hold_position (line 1426) | def hold_position(self, queue: bool = False) -> UnitCommand | bool:
method stop (line 1433) | def stop(self, queue: bool = False) -> UnitCommand | bool:
method patrol (line 1442) | def patrol(self, position: Point2, queue: bool = False) -> UnitCommand...
method repair (line 1452) | def repair(self, repair_target: Unit, queue: bool = False) -> UnitComm...
method __hash__ (line 1460) | def __hash__(self) -> int:
method __eq__ (line 1463) | def __eq__(self, other: Unit | Any) -> bool:
method __call__ (line 1469) | def __call__(
FILE: sc2/unit_command.py
class UnitCommand (line 13) | class UnitCommand:
method __init__ (line 14) | def __init__(
method combining_tuple (line 39) | def combining_tuple(self) -> tuple[AbilityId, Unit | Point2 | None, bo...
method __repr__ (line 42) | def __repr__(self) -> str:
FILE: sc2/units.py
class Units (line 17) | class Units(list[Unit]):
method from_proto (line 21) | def from_proto(cls, units: list[raw_pb2.Unit], bot_object: BotAI) -> U...
method __init__ (line 24) | def __init__(self, units: Iterable[Unit], bot_object: BotAI) -> None:
method __call__ (line 32) | def __call__(self, unit_types: UnitTypeId | Iterable[UnitTypeId]) -> U...
method __iter__ (line 39) | def __iter__(self) -> Generator[Unit, None, None]:
method copy (line 42) | def copy(self) -> Units:
method __or__ (line 49) | def __or__(self, other: Units) -> Units:
method __add__ (line 61) | def __add__(self, other: Units) -> Units:
method __and__ (line 73) | def __and__(self, other: Units) -> Units:
method __sub__ (line 82) | def __sub__(self, other: Units) -> Units:
method __hash__ (line 91) | def __hash__(self) -> int:
method amount (line 95) | def amount(self) -> int:
method empty (line 99) | def empty(self) -> bool:
method exists (line 103) | def exists(self) -> bool:
method find_by_tag (line 106) | def find_by_tag(self, tag: int) -> Unit | None:
method by_tag (line 115) | def by_tag(self, tag: int) -> Unit:
method first (line 125) | def first(self) -> Unit:
method take (line 129) | def take(self, n: int) -> Units:
method random (line 138) | def random(self) -> Unit:
method random_or (line 142) | def random_or(self, other: Any) -> Unit:
method random_group_of (line 145) | def random_group_of(self, n: int) -> Units:
method in_attack_range_of (line 153) | def in_attack_range_of(self, unit: Unit, bonus_distance: float = 0) ->...
method closest_distance_to (line 178) | def closest_distance_to(self, position: Unit | Point2) -> float:
method furthest_distance_to (line 196) | def furthest_distance_to(self, position: Unit | Point2) -> float:
method closest_to (line 215) | def closest_to(self, position: Unit | Point2) -> Unit:
method furthest_to (line 238) | def furthest_to(self, position: Unit | Point2) -> Unit:
method closer_than (line 260) | def closer_than(self, distance: float, position: Unit | Point2) -> Units:
method further_than (line 286) | def further_than(self, distance: float, position: Unit | Point2) -> Un...
method in_distance_between (line 312) | def in_distance_between(
method closest_n_units (line 344) | def closest_n_units(self, position: Unit | Point2, n: int) -> Units:
method furthest_n_units (line 362) | def furthest_n_units(self, position: Unit | Point2, n: int) -> Units:
method in_distance_of_group (line 380) | def in_distance_of_group(self, other_units: Units, distance: float) ->...
method in_closest_distance_to_group (line 408) | def in_closest_distance_to_group(self, other_units: Units) -> Unit:
method _list_sorted_closest_to_distance (line 424) | def _list_sorted_closest_to_distance(self, position: Unit | Point2, di...
method n_closest_to_distance (line 440) | def n_closest_to_distance(self, position: Point2, distance: float, n: ...
method n_furthest_to_distance (line 450) | def n_furthest_to_distance(self, position: Point2, distance: float, n:...
method subgroup (line 458) | def subgroup(self, units: Iterable[Unit]) -> Units:
method filter (line 465) | def filter(self, pred: Callable[[Unit], Any]) -> Units:
method sorted (line 488) | def sorted(self, key: Callable[[Unit], Any], reverse: bool = False) ->...
method _list_sorted_by_distance_to (line 491) | def _list_sorted_by_distance_to(self, position: Unit | Point2, reverse...
method sorted_by_distance_to (line 505) | def sorted_by_distance_to(self, position: Unit | Point2, reverse: bool...
method tags_in (line 513) | def tags_in(self, other: Iterable[int]) -> Units:
method tags_not_in (line 527) | def tags_not_in(self, other: Iterable[int]) -> Units:
method of_type (line 541) | def of_type(self, other: UnitTypeId | Iterable[UnitTypeId]) -> Units:
method exclude_type (line 557) | def exclude_type(self, other: UnitTypeId | Iterable[UnitTypeId]) -> Un...
method same_tech (line 573) | def same_tech(self, other: set[UnitTypeId]) -> Units:
method same_unit (line 610) | def same_unit(self, other: UnitTypeId | Iterable[UnitTypeId]) -> Units:
method center (line 643) | def center(self) -> Point2:
method selected (line 654) | def selected(self) -> Units:
method tags (line 659) | def tags(self) -> set[int]:
method ready (line 664) | def ready(self) -> Units:
method not_ready (line 669) | def not_ready(self) -> Units:
method idle (line 674) | def idle(self) -> Units:
method owned (line 679) | def owned(self) -> Units:
method enemy (line 684) | def enemy(self) -> Units:
method flying (line 689) | def flying(self) -> Units:
method not_flying (line 694) | def not_flying(self) -> Units:
method structure (line 699) | def structure(self) -> Units:
method not_structure (line 704) | def not_structure(self) -> Units:
method gathering (line 709) | def gathering(self) -> Units:
method returning (line 714) | def returning(self) -> Units:
method collecting (line 719) | def collecting(self) -> Units:
method visible (line 724) | def visible(self) -> Units:
method mineral_field (line 730) | def mineral_field(self) -> Units:
method vespene_geyser (line 735) | def vespene_geyser(self) -> Units:
method prefer_idle (line 740) | def prefer_idle(self) -> Units:
FILE: sc2/wsl.py
function win_path_to_wsl_path (line 14) | def win_path_to_wsl_path(path) -> Path:
function wsl_path_to_win_path (line 19) | def wsl_path_to_win_path(path) -> PureWindowsPath:
function get_wsl_home (line 24) | def get_wsl_home():
function run (line 43) | def run(popen_args, sc2_cwd) -> subprocess.Popen[str]:
function kill (line 57) | def kill(wsl_process) -> bool:
function detect (line 73) | def detect() -> str | None:
FILE: test/autotest_bot.py
class TestBot (line 18) | class TestBot(BotAI):
method __init__ (line 19) | def __init__(self):
method on_start (line 41) | async def on_start(self):
method on_step (line 46) | async def on_step(self, iteration):
method clean_up_center (line 71) | async def clean_up_center(self):
method test_botai_properties (line 87) | async def test_botai_properties(self):
method test_botai_functions (line 110) | async def test_botai_functions(self):
method test_game_state_static_variables (line 127) | async def test_game_state_static_variables(self):
method test_game_info_static_variables (line 137) | async def test_game_info_static_variables(self):
method test_botai_actions1 (line 143) | async def test_botai_actions1(self):
method test_botai_actions2 (line 154) | async def test_botai_actions2(self):
method test_botai_actions3 (line 187) | async def test_botai_actions3(self):
method test_botai_actions4 (line 205) | async def test_botai_actions4(self):
method test_botai_actions5 (line 216) | async def test_botai_actions5(self):
method test_botai_actions6 (line 240) | async def test_botai_actions6(self):
method test_botai_actions7 (line 266) | async def test_botai_actions7(self):
method test_botai_actions8 (line 290) | async def test_botai_actions8(self):
method test_botai_actions9 (line 322) | async def test_botai_actions9(self):
method test_botai_actions10 (line 363) | async def test_botai_actions10(self):
method test_botai_actions11 (line 403) | async def test_botai_actions11(self):
method test_botai_actions12 (line 436) | async def test_botai_actions12(self):
class EmptyBot (line 481) | class EmptyBot(BotAI):
method on_start (line 482) | async def on_start(self):
method on_step (line 486) | async def on_step(self, iteration: int):
function main (line 501) | def main():
FILE: test/battery_overcharge_bot.py
class BatteryOverchargeBot (line 16) | class BatteryOverchargeBot(BotAI):
method on_start (line 17) | async def on_start(self):
method on_step (line 27) | async def on_step(self, iteration):
function main (line 42) | def main():
FILE: test/benchmark_array_creation.py
function numpy_array (line 12) | def numpy_array(x, y):
function numpy_array_tuple (line 17) | def numpy_array_tuple(my_tuple):
function numpy_asarray (line 22) | def numpy_asarray(x, y):
function numpy_asarray_tuple (line 27) | def numpy_asarray_tuple(my_tuple):
function numpy_asanyarray (line 32) | def numpy_asanyarray(x, y):
function numpy_asanyarray_tuple (line 37) | def numpy_asanyarray_tuple(my_tuple):
function numpy_fromiter (line 42) | def numpy_fromiter(x, y):
function numpy_fromiter_tuple (line 47) | def numpy_fromiter_tuple(my_tuple):
function numpy_fromiter_np_float (line 52) | def numpy_fromiter_np_float(x, y):
function numpy_fromiter_np_float_tuple (line 57) | def numpy_fromiter_np_float_tuple(my_tuple):
function numpy_zeros (line 62) | def numpy_zeros(x, y):
function numpy_ones (line 70) | def numpy_ones(x, y):
function test_numpy_array (line 82) | def test_numpy_array(benchmark):
function test_numpy_array_tuple (line 87) | def test_numpy_array_tuple(benchmark):
function test_numpy_asarray (line 92) | def test_numpy_asarray(benchmark):
function test_numpy_asarray_tuple (line 97) | def test_numpy_asarray_tuple(benchmark):
function test_numpy_asanyarray (line 102) | def test_numpy_asanyarray(benchmark):
function test_numpy_asanyarray_tuple (line 107) | def test_numpy_asanyarray_tuple(benchmark):
function test_numpy_fromiter (line 112) | def test_numpy_fromiter(benchmark):
function test_numpy_fromiter_tuple (line 117) | def test_numpy_fromiter_tuple(benchmark):
function test_numpy_fromiter_np_float (line 122) | def test_numpy_fromiter_np_float(benchmark):
function test_numpy_fromiter_np_float_tuple (line 127) | def test_numpy_fromiter_np_float_tuple(benchmark):
function test_numpy_zeros (line 132) | def test_numpy_zeros(benchmark):
function test_numpy_ones (line 137) | def test_numpy_ones(benchmark):
FILE: test/benchmark_bot_ai_init.py
function _test_run_bot_ai_init_on_all_maps (line 8) | def _test_run_bot_ai_init_on_all_maps(pickle_data: list[tuple[Any, Any, ...
function test_bench_bot_ai_init (line 13) | def test_bench_bot_ai_init(benchmark):
FILE: test/benchmark_distance_two_points.py
function distance_to_python_raw (line 17) | def distance_to_python_raw(s, p):
function distance_to_squared_python_raw (line 21) | def distance_to_squared_python_raw(s, p):
function distance_to_math_dist (line 27) | def distance_to_math_dist(s, p):
function distance_to_math_hypot (line 31) | def distance_to_math_hypot(s, p):
function distance_scipy_euclidean (line 35) | def distance_scipy_euclidean(p1, p2) -> int | float:
function distance_numpy_linalg_norm (line 42) | def distance_numpy_linalg_norm(p1, p2):
function distance_sum_squared_sqrt (line 47) | def distance_sum_squared_sqrt(p1, p2) -> int | float:
function distance_sum_squared (line 52) | def distance_sum_squared(p1, p2) -> int | float:
function check_result (line 93) | def check_result(result1, result2, accuracy=1e-5):
function test_distance_to_math_dist (line 99) | def test_distance_to_math_dist(benchmark):
function test_distance_to_math_hypot (line 104) | def test_distance_to_math_hypot(benchmark):
function test_distance_to_python_raw (line 109) | def test_distance_to_python_raw(benchmark):
function test_distance_to_squared_python_raw (line 114) | def test_distance_to_squared_python_raw(benchmark):
function test_distance_scipy_euclidean (line 119) | def test_distance_scipy_euclidean(benchmark):
function test_distance_numpy_linalg_norm (line 124) | def test_distance_numpy_linalg_norm(benchmark):
function test_distance_sum_squared_sqrt (line 129) | def test_distance_sum_squared_sqrt(benchmark):
function test_distance_sum_squared (line 134) | def test_distance_sum_squared(benchmark):
FILE: test/benchmark_distances_cdist.py
function distance_matrix_scipy_cdist_braycurtis (line 7) | def distance_matrix_scipy_cdist_braycurtis(ps):
function distance_matrix_scipy_cdist_canberra (line 12) | def distance_matrix_scipy_cdist_canberra(ps):
function distance_matrix_scipy_cdist_chebyshev (line 17) | def distance_matrix_scipy_cdist_chebyshev(ps):
function distance_matrix_scipy_cdist_cityblock (line 22) | def distance_matrix_scipy_cdist_cityblock(ps):
function distance_matrix_scipy_cdist_correlation (line 27) | def distance_matrix_scipy_cdist_correlation(ps):
function distance_matrix_scipy_cdist_cosine (line 32) | def distance_matrix_scipy_cdist_cosine(ps):
function distance_matrix_scipy_cdist_hamming (line 37) | def distance_matrix_scipy_cdist_hamming(ps):
function distance_matrix_scipy_cdist_jaccard (line 42) | def distance_matrix_scipy_cdist_jaccard(ps):
function distance_matrix_scipy_cdist_jensenshannon (line 47) | def distance_matrix_scipy_cdist_jensenshannon(ps):
function distance_matrix_scipy_cdist_mahalanobis (line 52) | def distance_matrix_scipy_cdist_mahalanobis(ps):
function distance_matrix_scipy_cdist_matching (line 57) | def distance_matrix_scipy_cdist_matching(ps):
function distance_matrix_scipy_cdist_rogerstanimoto (line 67) | def distance_matrix_scipy_cdist_rogerstanimoto(ps):
function distance_matrix_scipy_cdist_russellrao (line 72) | def distance_matrix_scipy_cdist_russellrao(ps):
function distance_matrix_scipy_cdist_seuclidean (line 77) | def distance_matrix_scipy_cdist_seuclidean(ps):
function distance_matrix_scipy_cdist_sokalmichener (line 82) | def distance_matrix_scipy_cdist_sokalmichener(ps):
function distance_matrix_scipy_cdist_sokalsneath (line 87) | def distance_matrix_scipy_cdist_sokalsneath(ps):
function distance_matrix_scipy_cdist_yule (line 97) | def distance_matrix_scipy_cdist_yule(ps):
function distance_matrix_scipy_cdist (line 102) | def distance_matrix_scipy_cdist(ps):
function distance_matrix_scipy_pdist (line 107) | def distance_matrix_scipy_pdist(ps):
function distance_matrix_scipy_cdist_squared (line 112) | def distance_matrix_scipy_cdist_squared(ps):
function distance_matrix_scipy_pdist_squared (line 117) | def distance_matrix_scipy_pdist_squared(ps):
function test_distance_matrix_scipy_cdist_braycurtis (line 131) | def test_distance_matrix_scipy_cdist_braycurtis(benchmark):
function test_distance_matrix_scipy_cdist_canberra (line 136) | def test_distance_matrix_scipy_cdist_canberra(benchmark):
function test_distance_matrix_scipy_cdist_chebyshev (line 141) | def test_distance_matrix_scipy_cdist_chebyshev(benchmark):
function test_distance_matrix_scipy_cdist_cityblock (line 146) | def test_distance_matrix_scipy_cdist_cityblock(benchmark):
function test_distance_matrix_scipy_cdist_correlation (line 151) | def test_distance_matrix_scipy_cdist_correlation(benchmark):
function test_distance_matrix_scipy_cdist_cosine (line 156) | def test_distance_matrix_scipy_cdist_cosine(benchmark):
function test_distance_matrix_scipy_cdist_hamming (line 161) | def test_distance_matrix_scipy_cdist_hamming(benchmark):
function test_distance_matrix_scipy_cdist_jaccard (line 166) | def test_distance_matrix_scipy_cdist_jaccard(benchmark):
function test_distance_matrix_scipy_cdist_jensenshannon (line 171) | def test_distance_matrix_scipy_cdist_jensenshannon(benchmark):
function test_distance_matrix_scipy_cdist_mahalanobis (line 176) | def test_distance_matrix_scipy_cdist_mahalanobis(benchmark):
function test_distance_matrix_scipy_cdist_matching (line 181) | def test_distance_matrix_scipy_cdist_matching(benchmark):
function test_distance_matrix_scipy_cdist_rogerstanimoto (line 191) | def test_distance_matrix_scipy_cdist_rogerstanimoto(benchmark):
function test_distance_matrix_scipy_cdist_russellrao (line 196) | def test_distance_matrix_scipy_cdist_russellrao(benchmark):
function test_distance_matrix_scipy_cdist_seuclidean (line 201) | def test_distance_matrix_scipy_cdist_seuclidean(benchmark):
function test_distance_matrix_scipy_cdist_sokalmichener (line 206) | def test_distance_matrix_scipy_cdist_sokalmichener(benchmark):
function test_distance_matrix_scipy_cdist_sokalsneath (line 211) | def test_distance_matrix_scipy_cdist_sokalsneath(benchmark):
function test_distance_matrix_scipy_cdist_yule (line 221) | def test_distance_matrix_scipy_cdist_yule(benchmark):
function test_distance_matrix_scipy_cdist (line 226) | def test_distance_matrix_scipy_cdist(benchmark):
function test_distance_matrix_scipy_pdist (line 231) | def test_distance_matrix_scipy_pdist(benchmark):
function test_distance_matrix_scipy_cdist_squared (line 236) | def test_distance_matrix_scipy_cdist_squared(benchmark):
function test_distance_matrix_scipy_pdist_squared (line 241) | def test_distance_matrix_scipy_pdist_squared(benchmark):
FILE: test/benchmark_distances_points_to_point.py
function distance_matrix_scipy_cdist_squared (line 10) | def distance_matrix_scipy_cdist_squared(ps, p1):
function distance_numpy_basic_1 (line 18) | def distance_numpy_basic_1(ps, p1):
function distance_numpy_basic_2 (line 30) | def distance_numpy_basic_2(ps, p1):
function distance_numpy_einsum (line 39) | def distance_numpy_einsum(ps, p1):
function distance_numpy_einsum_pre_converted (line 49) | def distance_numpy_einsum_pre_converted(ps, p1):
function distance_pure_python (line 86) | def distance_pure_python(ps, p1):
function distance_math_hypot (line 97) | def distance_math_hypot(ps, p1):
function test_distance_matrix_scipy_cdist_squared (line 134) | def test_distance_matrix_scipy_cdist_squared(benchmark):
function test_distance_numpy_basic_1 (line 138) | def test_distance_numpy_basic_1(benchmark):
function test_distance_numpy_basic_2 (line 142) | def test_distance_numpy_basic_2(benchmark):
function test_distance_numpy_einsum (line 146) | def test_distance_numpy_einsum(benchmark):
function test_distance_numpy_einsum_pre_converted (line 150) | def test_distance_numpy_einsum_pre_converted(benchmark):
function test_distance_pure_python (line 164) | def test_distance_pure_python(benchmark):
function test_distance_math_hypot (line 168) | def test_distance_math_hypot(benchmark):
FILE: test/benchmark_distances_units.py
function distance_matrix_scipy_cdist (line 8) | def distance_matrix_scipy_cdist(ps):
function distance_matrix_scipy_pdist (line 13) | def distance_matrix_scipy_pdist(ps):
function distance_matrix_scipy_cdist_squared (line 18) | def distance_matrix_scipy_cdist_squared(ps):
function distance_matrix_scipy_pdist_squared (line 23) | def distance_matrix_scipy_pdist_squared(ps):
function calc_row_idx (line 42) | def calc_row_idx(k, n):
function elem_in_i_rows (line 46) | def elem_in_i_rows(i, n):
function calc_col_idx (line 50) | def calc_col_idx(k, i, n):
function condensed_to_square (line 54) | def condensed_to_square(k, n):
function square_to_condensed (line 60) | def square_to_condensed(i, j, amount):
function test_distance_matrix_scipy_cdist (line 98) | def test_distance_matrix_scipy_cdist(benchmark):
function test_distance_matrix_scipy_pdist (line 103) | def test_distance_matrix_scipy_pdist(benchmark):
function test_distance_matrix_scipy_cdist_squared (line 108) | def test_distance_matrix_scipy_cdist_squared(benchmark):
function test_distance_matrix_scipy_pdist_squared (line 113) | def test_distance_matrix_scipy_pdist_squared(benchmark):
FILE: test/benchmark_prepare_units.py
function _run_prepare_units (line 11) | def _run_prepare_units(bot_objects: list[BotAI]):
function test_bench_prepare_units (line 16) | def test_bench_prepare_units(benchmark):
FILE: test/damagetest_bot.py
class TestBot (line 16) | class TestBot(BotAI):
method __init__ (line 17) | def __init__(self):
method on_start (line 41) | async def on_start(self):
method on_step (line 46) | async def on_step(self, iteration):
method clean_up_center (line 57) | async def clean_up_center(self):
method test_botai_actions1001 (line 73) | async def test_botai_actions1001(self):
class EmptyBot (line 319) | class EmptyBot(BotAI):
method on_start (line 320) | async def on_start(self):
method on_step (line 324) | async def on_step(self, iteration: int):
function main (line 339) | def main():
FILE: test/generate_pickle_files_bot.py
class ExporterBot (line 25) | class ExporterBot(BotAI):
method __init__ (line 26) | def __init__(self):
method on_step (line 30) | async def on_step(self, iteration):
method get_pickle_file_path (line 33) | def get_pickle_file_path(self) -> Path:
method get_combat_file_path (line 40) | def get_combat_file_path(self) -> Path:
method store_data_to_file (line 47) | async def store_data_to_file(self, file_path: Path):
method on_start (line 66) | async def on_start(self):
function main (line 103) | def main():
FILE: test/queries_test_bot.py
class TestBot (line 24) | class TestBot(BotAI):
method __init__ (line 25) | def __init__(self):
method on_start (line 29) | async def on_start(self):
method on_step (line 32) | async def on_step(self, iteration):
method clear_map_center (line 45) | async def clear_map_center(self):
method spawn_unit (line 69) | async def spawn_unit(self, unit_type: UnitTypeId | list[UnitTypeId]):
method spawn_unit_enemy (line 76) | async def spawn_unit_enemy(self, unit_type: UnitTypeId | list[UnitType...
method run_can_place (line 86) | async def run_can_place(self) -> bool:
method run_can_place_single (line 90) | async def run_can_place_single(self) -> bool:
method test_can_place_expect_true (line 94) | async def test_can_place_expect_true(self):
method test_can_place_expect_false (line 140) | async def test_can_place_expect_false(self):
method test_rally_points_with_rally_ability (line 193) | async def test_rally_points_with_rally_ability(self):
method test_rally_points_with_smart_ability (line 219) | async def test_rally_points_with_smart_ability(self):
class EmptyBot (line 250) | class EmptyBot(BotAI):
method on_step (line 251) | async def on_step(self, iteration: int):
function main (line 256) | def main():
FILE: test/real_time_worker_production.py
class RealTimeTestBot (line 23) | class RealTimeTestBot(BotAI):
method on_before_start (line 24) | async def on_before_start(self):
method on_start (line 36) | async def on_start(self):
method on_step (line 40) | async def on_step(self, iteration):
method on_building_construction_complete (line 90) | async def on_building_construction_complete(self, unit: Unit):
method on_end (line 95) | async def on_end(self, game_result: Result):
function main (line 101) | def main():
FILE: test/run_example_bots_vs_computer.py
function main (line 137) | async def main():
FILE: test/run_example_bots_vs_each_other.py
function main (line 124) | async def main():
FILE: test/test_directions.py
function rad_diff (line 12) | def rad_diff(a, b):
function test_test_rad_diff (line 20) | def test_test_rad_diff():
function test_distance (line 31) | def test_distance():
function test_towards (line 37) | def test_towards():
function test_random_on_distance (line 41) | def test_random_on_distance():
function test_towards_random_angle (line 66) | def test_towards_random_angle():
FILE: test/test_expiring_dict.py
function test_class (line 6) | def test_class():
FILE: test/test_pickled_data.py
function load_map_pickle_data (line 48) | def load_map_pickle_data(map_path: Path) -> tuple[Any, Any, Any]:
function build_bot_object_from_pickle_data (line 54) | def build_bot_object_from_pickle_data(raw_game_data, raw_game_info, raw_...
function get_map_specific_bot (line 67) | def get_map_specific_bot(map_path: Path) -> BotAI:
function test_protobuf_implementation (line 73) | def test_protobuf_implementation():
function test_bot_ai (line 78) | def test_bot_ai():
function test_game_info (line 400) | def test_game_info():
function test_game_data (line 424) | def test_game_data():
function test_game_state (line 465) | def test_game_state():
function test_pixelmap (line 488) | def test_pixelmap():
function test_blip (line 503) | def test_blip():
function test_score (line 509) | def test_score():
function test_unit (line 515) | def test_unit():
function test_units (line 785) | def test_units():
function test_exact_creation_ability (line 912) | def test_exact_creation_ability():
function test_dicts (line 969) | def test_dicts():
function test_position_pointlike (line 1007) | def test_position_pointlike(x1, y1, x2, y2, x3, y3):
function test_position_point2 (line 1072) | def test_position_point2(x1, y1, x2, y2):
function test_position_point3 (line 1129) | def test_position_point3(x1, y1, z1):
function test_position_size (line 1146) | def test_position_size(w, h):
function test_position_rect (line 1159) | def test_position_rect(x, y, w, h):
function test_missing_enum (line 1172) | def test_missing_enum():
FILE: test/test_pickled_ramp.py
function pytest_generate_tests (line 24) | def pytest_generate_tests(metafunc):
class TestClass (line 36) | class TestClass:
method test_main_base_ramp (line 42) | def test_main_base_ramp(self, map_path: Path):
method test_bot_ai (line 92) | def test_bot_ai(self, map_path: Path):
FILE: test/test_replays.py
function test_get_replay_version (line 9) | def test_get_replay_version():
FILE: test/upgradestest_bot.py
class TestBot (line 18) | class TestBot(BotAI):
method __init__ (line 19) | def __init__(self):
method on_start (line 43) | async def on_start(self):
method on_step (line 48) | async def on_step(self, iteration):
method clean_up_center (line 65) | async def clean_up_center(self):
method test_botai_actions1 (line 81) | async def test_botai_actions1(self):
class EmptyBot (line 173) | class EmptyBot(BotAI):
method on_start (line 174) | async def on_start(self):
method on_step (line 178) | async def on_step(self, iteration: int):
function main (line 193) | def main():
Condensed preview — 256 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,514K chars).
[
{
"path": ".github/workflows/ci.yml",
"chars": 15953,
"preview": "# If you change the name, change the link on the README.md for the badge too\nname: Tests\n\non:\n push:\n paths:\n "
},
{
"path": ".github/workflows/docker-ci.yml",
"chars": 6190,
"preview": "name: Build and push Docker image\n\n# Only run if Dockerfile or docker-ci.yml changed\non:\n push:\n paths:\n - dock"
},
{
"path": ".gitignore",
"chars": 249,
"preview": "# Misc\n.DS_Store\n\n# Python + mypy + pytest\n__pycache__/\n*.pyc\n\n.mypy_cache/\n.pytest_cache/\n\nbuild/\ndist/\n*.egg-info/\n\n.c"
},
{
"path": ".pre-commit-config.yaml",
"chars": 1600,
"preview": "repos:\n- repo: https://github.com/pre-commit/pre-commit-hooks\n rev: v4.4.0\n hooks:\n # Check yaml files like this on"
},
{
"path": "LICENSE",
"chars": 1072,
"preview": "MIT License\n\nCopyright (c) 2017 Hannes Karppila\n\nPermission is hereby granted, free of charge, to any person obtaining a"
},
{
"path": "README.md",
"chars": 8260,
"preview": "[](https://github.com/BurnySc2/python"
},
{
"path": "data/README.md",
"chars": 328,
"preview": "This data comes from dentosals tech tree and is only used to generate the dictionaries in /sc2/dicts/:\n\nhttps://github.c"
},
{
"path": "data/data.json",
"chars": 289423,
"preview": "{\"Ability\":[{\"id\":1,\"name\":\"SMART\",\"cast_range\":0.0,\"energy_cost\":0,\"allow_minimap\":true,\"allow_autocast\":false,\"effect\""
},
{
"path": "dockerfiles/Dockerfile",
"chars": 2252,
"preview": "# Set up StarCraft II Test Environment for python-sc2 bots (not pysc2 bots!)\nARG PYTHON_VERSION=3.10\n\n# https://docs.ast"
},
{
"path": "dockerfiles/README.md",
"chars": 460,
"preview": "# Dockerfile\nThis dockerfile is meant to be as small as possible, contain only the sc2 binary and maps.\n\nIt is used to r"
},
{
"path": "dockerfiles/download_maps.sh",
"chars": 1812,
"preview": "#!/bin/bash\n# Run via\n# sh dockerfiles/download_maps.sh\nset -e\n\n# Create maps directory if it doesn't exist\nmkdir -p doc"
},
{
"path": "dockerfiles/test_docker_image.sh",
"chars": 2067,
"preview": "# This script is meant for development, which produces fresh images and then runs tests\n# Run via\n# sh dockerfiles/test_"
},
{
"path": "dockerfiles/test_new_python_candidate.sh",
"chars": 1756,
"preview": "# This script is meant for development, which produces fresh images and then runs tests\n# If it succeeds, a new python v"
},
{
"path": "docs_generate/Makefile",
"chars": 634,
"preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the "
},
{
"path": "docs_generate/bot_ai/index.rst",
"chars": 396,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nbot_ai.py\n****************************\n\nThis basic bot class "
},
{
"path": "docs_generate/client/index.rst",
"chars": 144,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nclient.py\n****************************\n\n.. autoclass:: sc2.cl"
},
{
"path": "docs_generate/conf.py",
"chars": 2387,
"preview": "# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common op"
},
{
"path": "docs_generate/game_data/index.rst",
"chars": 419,
"preview": ".. toctree::\n :maxdepth: 2\n\n********************************************************\ngame_data.py\n********************"
},
{
"path": "docs_generate/game_info/index.rst",
"chars": 199,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\ngame_info.py\n****************************\n\n.. autoclass:: sc2"
},
{
"path": "docs_generate/game_state/index.rst",
"chars": 363,
"preview": ".. toctree::\n :maxdepth: 2\n\n********************************************************\ngame_state.py\n*******************"
},
{
"path": "docs_generate/ids/index.rst",
"chars": 371,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nids\n****************************\n\n.. autoclass:: sc2.ids.abil"
},
{
"path": "docs_generate/index.rst",
"chars": 778,
"preview": ".. python-sc2 documentation master file, created by\n sphinx-quickstart on Sat Jun 15 05:52:03 2019.\n You can adapt t"
},
{
"path": "docs_generate/make.bat",
"chars": 760,
"preview": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-bu"
},
{
"path": "docs_generate/pixel_map/index.rst",
"chars": 152,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\npixel_map.py\n****************************\n\n.. autoclass:: sc2"
},
{
"path": "docs_generate/position/index.rst",
"chars": 339,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nposition.py\n****************************\n\n.. autoclass:: sc2."
},
{
"path": "docs_generate/protocol/index.rst",
"chars": 150,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nprotocol.py\n****************************\n\n.. autoclass:: sc2."
},
{
"path": "docs_generate/score/index.rst",
"chars": 148,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nscore.py\n****************************\n\n.. autoclass:: sc2.sco"
},
{
"path": "docs_generate/text_files/docker.rst",
"chars": 4756,
"preview": "*****************************\nUsing docker to run SC2 bots\n*****************************\nThis is a small overview on how"
},
{
"path": "docs_generate/text_files/introduction.rst",
"chars": 13250,
"preview": "*************\nIntroduction\n*************\n\nThis is an overview to the BurnySc2/python-sc2 library which can be found here"
},
{
"path": "docs_generate/unit/index.rst",
"chars": 138,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nunit.py\n****************************\n\n.. autoclass:: sc2.unit"
},
{
"path": "docs_generate/unit_command/index.rst",
"chars": 161,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nunit_command.py\n****************************\n\n.. autoclass:: "
},
{
"path": "docs_generate/units/index.rst",
"chars": 141,
"preview": ".. toctree::\n :maxdepth: 2\n\n****************************\nunits.py\n****************************\n\n.. autoclass:: sc2.uni"
},
{
"path": "examples/__init__.py",
"chars": 133,
"preview": "from pathlib import Path\n\n__all__ = [p.stem for p in Path().iterdir() if p.is_file() and p.suffix == \".py\" and p.stem !="
},
{
"path": "examples/arcade_bot.py",
"chars": 5104,
"preview": "\"\"\"\nTo play an arcade map, you need to download the map first.\n\nOpen the StarCraft2 Map Editor through the Battle.net la"
},
{
"path": "examples/bot_vs_bot.py",
"chars": 1262,
"preview": "\"\"\"\nThis script shows how to let two custom bots play against each other.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom "
},
{
"path": "examples/competitive/README.md",
"chars": 1248,
"preview": "# Example competitive bot\n\nThis is a small example bot that should work with [AI-Arena](https://aiarena.net/), [Sc2AI](h"
},
{
"path": "examples/competitive/__init__.py",
"chars": 2949,
"preview": "import argparse\nimport asyncio\n\nimport aiohttp\nfrom loguru import logger\n\nfrom sc2.client import Client\nfrom sc2.main im"
},
{
"path": "examples/competitive/bot.py",
"chars": 446,
"preview": "from sc2.bot_ai import BotAI\nfrom sc2.data import Result\n\n\nclass CompetitiveBot(BotAI):\n async def on_start(self):\n "
},
{
"path": "examples/competitive/ladderbots.json",
"chars": 313,
"preview": "{\n \"Bots\": {\n \"YOUR_BOTS_NAME_HERE\": {\n \"Race\": \"Put Terran Zerg or Protoss here\",\n \"Typ"
},
{
"path": "examples/competitive/run.py",
"chars": 759,
"preview": "import sys\n\nfrom examples.competitive.__init__ import run_ladder_game\n\n# Load bot\nfrom examples.competitive.bot import C"
},
{
"path": "examples/distributed_workers.py",
"chars": 1384,
"preview": "from sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.unit_typeid import "
},
{
"path": "examples/external_bot.py",
"chars": 1021,
"preview": "from pathlib import Path\n\nfrom sc2 import maps\nfrom sc2.data import Race\nfrom sc2.main import GameMatch, run_multiple_ga"
},
{
"path": "examples/fastreload.py",
"chars": 744,
"preview": "from importlib import reload\n\nfrom examples.zerg import zerg_rush\nfrom sc2 import maps\nfrom sc2.data import Difficulty, "
},
{
"path": "examples/host_external_norestart.py",
"chars": 551,
"preview": "from examples.zerg.zerg_rush import ZergRushBot\nfrom sc2 import maps\nfrom sc2.data import Race\nfrom sc2.main import _hos"
},
{
"path": "examples/observer_easy_vs_easy.py",
"chars": 404,
"preview": "from examples.protoss.cannon_rush import CannonRushBot\nfrom sc2 import maps\nfrom sc2.data import Difficulty, Race\nfrom s"
},
{
"path": "examples/play_tvz.py",
"chars": 400,
"preview": "\"\"\"\nThis script let's you play as human against a simple zerg rush bot.\n\"\"\"\n\nfrom examples.zerg.zerg_rush import ZergRus"
},
{
"path": "examples/protoss/__init__.py",
"chars": 133,
"preview": "from pathlib import Path\n\n__all__ = [p.stem for p in Path().iterdir() if p.is_file() and p.suffix == \".py\" and p.stem !="
},
{
"path": "examples/protoss/cannon_rush.py",
"chars": 3231,
"preview": "import random\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.unit"
},
{
"path": "examples/protoss/find_adept_shades.py",
"chars": 2685,
"preview": "import math\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.abilit"
},
{
"path": "examples/protoss/threebase_voidray.py",
"chars": 6248,
"preview": "from sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.ability_id import A"
},
{
"path": "examples/protoss/warpgate_push.py",
"chars": 6504,
"preview": "from loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom "
},
{
"path": "examples/simulate_fight_scenario.py",
"chars": 3027,
"preview": "from loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom "
},
{
"path": "examples/terran/__init__.py",
"chars": 133,
"preview": "from pathlib import Path\n\n__all__ = [p.stem for p in Path().iterdir() if p.is_file() and p.suffix == \".py\" and p.stem !="
},
{
"path": "examples/terran/cyclone_push.py",
"chars": 6061,
"preview": "from sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.unit_typeid import "
},
{
"path": "examples/terran/mass_reaper.py",
"chars": 22101,
"preview": "\"\"\"\nBot that stays on 1base, goes 4 rax mass reaper\nThis bot is one of the first examples that are micro intensive\nBot h"
},
{
"path": "examples/terran/onebase_battlecruiser.py",
"chars": 9194,
"preview": "from __future__ import annotations\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, R"
},
{
"path": "examples/terran/proxy_rax.py",
"chars": 2707,
"preview": "from sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.unit_typeid import "
},
{
"path": "examples/terran/ramp_wall.py",
"chars": 12299,
"preview": "import random\n\nimport numpy as np\nfrom loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2."
},
{
"path": "examples/too_slow_bot.py",
"chars": 584,
"preview": "import asyncio\nimport random\n\nfrom examples.terran.proxy_rax import ProxyRaxBot\nfrom sc2 import maps\nfrom sc2.data impor"
},
{
"path": "examples/watch_replay.py",
"chars": 1569,
"preview": "import platform\nfrom pathlib import Path\n\nfrom loguru import logger\n\nfrom sc2.main import run_replay\nfrom sc2.observer_a"
},
{
"path": "examples/worker_rush.py",
"chars": 626,
"preview": "from sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.main import run_game\nfr"
},
{
"path": "examples/worker_stack_bot.py",
"chars": 5192,
"preview": "\"\"\"\nThis bot attempts to stack workers 'perfectly'.\nThis is only a demo that works on game start, but does not work when"
},
{
"path": "examples/zerg/__init__.py",
"chars": 133,
"preview": "from pathlib import Path\n\n__all__ = [p.stem for p in Path().iterdir() if p.is_file() and p.suffix == \".py\" and p.stem !="
},
{
"path": "examples/zerg/banes_banes_banes.py",
"chars": 5438,
"preview": "import random\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.abil"
},
{
"path": "examples/zerg/expand_everywhere.py",
"chars": 3096,
"preview": "import random\nfrom contextlib import suppress\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Di"
},
{
"path": "examples/zerg/hydralisk_push.py",
"chars": 5970,
"preview": "import random\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfrom sc2.ids.abil"
},
{
"path": "examples/zerg/onebase_broodlord.py",
"chars": 5723,
"preview": "# noqa: SIM102\nimport random\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Difficulty, Race\nfr"
},
{
"path": "examples/zerg/worker_split.py",
"chars": 1653,
"preview": "\"\"\"\nThis bot is just to demonstrate that you can do worker split\nat game start without having to use 'synchronous_do()'."
},
{
"path": "examples/zerg/zerg_rush.py",
"chars": 6532,
"preview": "import numpy as np\nfrom loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc2.data import Dif"
},
{
"path": "generate_dicts_from_data_json.py",
"chars": 23759,
"preview": "\"\"\"\nThis script does the following:\n\n- Loop over all abilities, checking what unit they create and if it requires a plac"
},
{
"path": "generate_id_constants_from_stableid.py",
"chars": 147,
"preview": "from sc2.generate_ids import IdGenerator\n\nif __name__ == \"__main__\":\n id_updater = IdGenerator()\n id_updater.updat"
},
{
"path": "pyproject.toml",
"chars": 4721,
"preview": "[project]\nname = \"burnysc2\"\nversion = \"7.2.1\"\ndescription = \"A StarCraft II API Client for Python 3\"\nauthors = [{ name ="
},
{
"path": "sc2/__init__.py",
"chars": 305,
"preview": "from pathlib import Path\n\n\ndef is_submodule(path):\n if path.is_file():\n return path.suffix == \".py\" and path.s"
},
{
"path": "sc2/action.py",
"chars": 4280,
"preview": "from __future__ import annotations\n\nfrom itertools import groupby\nfrom typing import TYPE_CHECKING\n\nfrom s2clientprotoco"
},
{
"path": "sc2/bot_ai.py",
"chars": 63379,
"preview": "from __future__ import annotations\n\nimport math\nimport random\nimport warnings\nfrom collections import Counter\nfrom funct"
},
{
"path": "sc2/bot_ai_internal.py",
"chars": 50032,
"preview": "from __future__ import annotations\n\nimport itertools\nimport math\nimport time\nimport warnings\nfrom abc import ABC\nfrom co"
},
{
"path": "sc2/cache.py",
"chars": 1911,
"preview": "from __future__ import annotations\n\nfrom collections.abc import Callable, Hashable\nfrom typing import TYPE_CHECKING, Any"
},
{
"path": "sc2/client.py",
"chars": 39538,
"preview": "from __future__ import annotations\n\nfrom collections.abc import Iterable\nfrom pathlib import Path\nfrom typing import Any"
},
{
"path": "sc2/constants.py",
"chars": 24932,
"preview": "from __future__ import annotations\n\nfrom collections import defaultdict\nfrom typing import Any\n\nfrom sc2.data import All"
},
{
"path": "sc2/controller.py",
"chars": 3569,
"preview": "from __future__ import annotations\n\nimport platform\nfrom pathlib import Path\nfrom typing import TYPE_CHECKING\n\nfrom aioh"
},
{
"path": "sc2/data.py",
"chars": 3046,
"preview": "\"\"\"For the list of enums, see here\n\nhttps://github.com/Blizzard/s2client-proto/tree/bff45dae1fc685e6acbaae084670afb7d1c0"
},
{
"path": "sc2/data.pyi",
"chars": 10172,
"preview": "\"\"\"Type stubs for sc2.data module\n\nThis stub provides static type information for dynamically generated enums.\nThe enums"
},
{
"path": "sc2/dicts/__init__.py",
"chars": 331,
"preview": "# DO NOT EDIT!\n# This file was automatically generated by \"generate_dicts_from_data_json.py\"\n\n__all__ = [\n \"generic_r"
},
{
"path": "sc2/dicts/generic_redirect_abilities.py",
"chars": 17036,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/unit_abilities.py",
"chars": 44824,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/unit_research_abilities.py",
"chars": 17243,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/unit_tech_alias.py",
"chars": 2060,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/unit_train_build_abilities.py",
"chars": 19680,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/unit_trained_from.py",
"chars": 5774,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/unit_unit_alias.py",
"chars": 2498,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/dicts/upgrade_researched_from.py",
"chars": 5687,
"preview": "# THIS FILE WAS AUTOMATICALLY GENERATED BY \"generate_dicts_from_data_json.py\" DO NOT CHANGE MANUALLY!\n# ANY CHANGE WILL "
},
{
"path": "sc2/expiring_dict.py",
"chars": 5882,
"preview": "from __future__ import annotations\n\nfrom collections import OrderedDict\nfrom collections.abc import Hashable, Iterable\nf"
},
{
"path": "sc2/game_data.py",
"chars": 13094,
"preview": "from __future__ import annotations\n\nfrom bisect import bisect_left\nfrom contextlib import suppress\nfrom dataclasses impo"
},
{
"path": "sc2/game_info.py",
"chars": 14325,
"preview": "from __future__ import annotations\n\nimport heapq\nfrom collections import deque\nfrom collections.abc import Iterable\nfrom"
},
{
"path": "sc2/game_state.py",
"chars": 12741,
"preview": "from __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom functools import cached_property\nfrom itertoo"
},
{
"path": "sc2/generate_ids.py",
"chars": 7637,
"preview": "from __future__ import annotations\n\nimport importlib\nimport json\nimport platform\nimport sys\nfrom pathlib import Path\nfro"
},
{
"path": "sc2/ids/__init__.py",
"chars": 191,
"preview": "from __future__ import annotations\n\n# DO NOT EDIT!\n# This file was automatically generated by \"generate_ids.py\"\n\n__all__"
},
{
"path": "sc2/ids/ability_id.py",
"chars": 58310,
"preview": "from __future__ import annotations\n\n# DO NOT EDIT!\n# This file was automatically generated by \"generate_ids.py\"\nimport e"
},
{
"path": "sc2/ids/buff_id.py",
"chars": 9534,
"preview": "from __future__ import annotations\n\n# DO NOT EDIT!\n# This file was automatically generated by \"generate_ids.py\"\nimport e"
},
{
"path": "sc2/ids/effect_id.py",
"chars": 684,
"preview": "from __future__ import annotations\n\n# DO NOT EDIT!\n# This file was automatically generated by \"generate_ids.py\"\nimport e"
},
{
"path": "sc2/ids/id_version.py",
"chars": 35,
"preview": "ID_VERSION_STRING = \"4.11.4.78285\"\n"
},
{
"path": "sc2/ids/unit_typeid.py",
"chars": 63890,
"preview": "from __future__ import annotations\n\n# DO NOT EDIT!\n# This file was automatically generated by \"generate_ids.py\"\nimport e"
},
{
"path": "sc2/ids/upgrade_id.py",
"chars": 9568,
"preview": "from __future__ import annotations\n\n# DO NOT EDIT!\n# This file was automatically generated by \"generate_ids.py\"\nimport e"
},
{
"path": "sc2/main.py",
"chars": 32027,
"preview": "from __future__ import annotations\n\nimport asyncio\nimport json\nimport platform\nimport signal\nimport sys\nfrom contextlib "
},
{
"path": "sc2/maps.py",
"chars": 1593,
"preview": "from __future__ import annotations\n\nfrom pathlib import Path\n\nfrom loguru import logger\n\nfrom sc2.paths import Paths\n\n\nd"
},
{
"path": "sc2/observer_ai.py",
"chars": 5278,
"preview": "\"\"\"\nThis class is very experimental and probably not up to date and needs to be refurbished.\nIf it works, you can watch "
},
{
"path": "sc2/paths.py",
"chars": 4857,
"preview": "from __future__ import annotations\n\nimport os\nimport platform\nimport re\nimport sys\nfrom contextlib import suppress\nfrom "
},
{
"path": "sc2/pixel_map.py",
"chars": 4276,
"preview": "from __future__ import annotations\n\nfrom collections.abc import Callable\nfrom pathlib import Path\n\nimport numpy as np\n\nf"
},
{
"path": "sc2/player.py",
"chars": 7683,
"preview": "from __future__ import annotations\n\nfrom abc import ABC\nfrom pathlib import Path\n\nfrom s2clientprotocol import sc2api_pb"
},
{
"path": "sc2/portconfig.py",
"chars": 3112,
"preview": "from __future__ import annotations\n\nimport json\n\n# pyre-fixme[21]\nimport portpicker\n\n\nclass Portconfig:\n \"\"\"\n A da"
},
{
"path": "sc2/position.py",
"chars": 14373,
"preview": "from __future__ import annotations\n\nimport itertools\nimport math\nimport random\nfrom collections.abc import Iterable\nfrom"
},
{
"path": "sc2/power_source.py",
"chars": 1027,
"preview": "from __future__ import annotations\n\nfrom dataclasses import dataclass\n\nfrom s2clientprotocol import raw_pb2\nfrom sc2.pos"
},
{
"path": "sc2/protocol.py",
"chars": 5512,
"preview": "from __future__ import annotations\n\nimport asyncio\nimport sys\nfrom contextlib import suppress\nfrom typing import overloa"
},
{
"path": "sc2/proxy.py",
"chars": 10413,
"preview": "from __future__ import annotations\n\nimport asyncio\nimport os\nimport platform\nimport subprocess\nimport sys\nimport time\nim"
},
{
"path": "sc2/py.typed",
"chars": 75,
"preview": "# Required by https://peps.python.org/pep-0561/#packaging-type-information\n"
},
{
"path": "sc2/renderer.py",
"chars": 6492,
"preview": "from __future__ import annotations\n\n\nimport datetime\nfrom typing import TYPE_CHECKING\n\nfrom s2clientprotocol import scor"
},
{
"path": "sc2/sc2process.py",
"chars": 10220,
"preview": "from __future__ import annotations\n\nimport asyncio\nimport os\nimport shutil\nimport signal\nimport subprocess\nimport sys\nim"
},
{
"path": "sc2/score.py",
"chars": 12066,
"preview": "from __future__ import annotations\n\nfrom s2clientprotocol import score_pb2\n\n\nclass ScoreDetails:\n \"\"\"Accessable in se"
},
{
"path": "sc2/unit.py",
"chars": 59485,
"preview": "from __future__ import annotations\n\nimport math\nimport warnings\nfrom dataclasses import dataclass\nfrom functools import "
},
{
"path": "sc2/unit_command.py",
"chars": 1420,
"preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom sc2.constants import COMBINEABLE_ABILITIES\nfr"
},
{
"path": "sc2/units.py",
"chars": 29203,
"preview": "from __future__ import annotations\n\nimport random\nfrom collections.abc import Callable, Generator, Iterable\nfrom itertoo"
},
{
"path": "sc2/versions.py",
"chars": 19077,
"preview": "from __future__ import annotations\n\nVERSIONS: list[dict[str, int | str]] = [\n {\n \"base-version\": 52910,\n "
},
{
"path": "sc2/wsl.py",
"chars": 4282,
"preview": "from __future__ import annotations\n\nimport os\nimport re\nimport subprocess\nfrom pathlib import Path, PureWindowsPath\n\nfro"
},
{
"path": "test/Dockerfile",
"chars": 1061,
"preview": "# Buildable via command from root folder\n# docker build -f test/Dockerfile -t test_image --build-arg PYTHON_VERSION=3.10"
},
{
"path": "test/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "test/autotest_bot.py",
"chars": 22014,
"preview": "from __future__ import annotations\n\nfrom loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc"
},
{
"path": "test/battery_overcharge_bot.py",
"chars": 1657,
"preview": "\"\"\"\nThis bot tests if battery overcharge crashes the bot.\n\"\"\"\n\nfrom loguru import logger\n\nfrom sc2 import maps\nfrom sc2."
},
{
"path": "test/benchmark_array_creation.py",
"chars": 3638,
"preview": "\"\"\"\nTesting what the fastest way is to create a 1D Array with 2 values\n\"\"\"\n\nimport random\n\nimport numpy as np\n\nx, y = ra"
},
{
"path": "test/benchmark_bot_ai_init.py",
"chars": 690,
"preview": "from __future__ import annotations\n\nfrom typing import Any\n\nfrom test.test_pickled_data import MAPS, build_bot_object_fr"
},
{
"path": "test/benchmark_distance_two_points.py",
"chars": 5370,
"preview": "from __future__ import annotations\n\nimport math\nimport platform\nimport random\n\nimport numpy as np\nfrom scipy.spatial imp"
},
{
"path": "test/benchmark_distances_cdist.py",
"chars": 7790,
"preview": "import random\n\nimport numpy as np\nfrom scipy.spatial.distance import cdist, pdist\n\n\ndef distance_matrix_scipy_cdist_bray"
},
{
"path": "test/benchmark_distances_points_to_point.py",
"chars": 5755,
"preview": "from __future__ import annotations\n\nimport math\nimport random\n\nimport numpy as np\nfrom scipy.spatial.distance import cdi"
},
{
"path": "test/benchmark_distances_units.py",
"chars": 3627,
"preview": "import math\nimport random\n\nimport numpy as np\nfrom scipy.spatial.distance import cdist, pdist\n\n\ndef distance_matrix_scip"
},
{
"path": "test/benchmark_prepare_units.py",
"chars": 563,
"preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom test.test_pickled_data import MAPS, get_map_s"
},
{
"path": "test/damagetest_bot.py",
"chars": 14494,
"preview": "from __future__ import annotations\n\nimport math\n\nfrom loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import "
},
{
"path": "test/generate_pickle_files_bot.py",
"chars": 7204,
"preview": "\"\"\"\nThis \"bot\" will loop over several available ladder maps and generate the pickle file in the \"/test/pickle_data/\" sub"
},
{
"path": "test/queries_test_bot.py",
"chars": 10861,
"preview": "\"\"\"\nThis testbot's purpose is to test the query behavior of the API.\nThese query functions are:\nself.can_place (RequestQ"
},
{
"path": "test/real_time_worker_production.py",
"chars": 4035,
"preview": "\"\"\"\nThis bot tests if on 'realtime=True' any nexus has more than 1 probe in the queue.\n\"\"\"\n\nfrom __future__ import annot"
},
{
"path": "test/run_example_bots_vs_computer.py",
"chars": 4216,
"preview": "\"\"\"\nThis script makes sure to run all bots in the examples folder to check if they can launch.\n\"\"\"\n\nfrom __future__ impo"
},
{
"path": "test/run_example_bots_vs_each_other.py",
"chars": 4158,
"preview": "\"\"\"\nThis script makes sure to run all bots in the examples folder to check if they can launch against each other.\n\"\"\"\n\nf"
},
{
"path": "test/test_directions.py",
"chars": 2670,
"preview": "import random\nfrom math import atan2, cos, pi, sin, sqrt\n\nfrom sc2.position import EPSILON, Point2\n\nP0 = Point2((0, 0))\n"
},
{
"path": "test/test_expiring_dict.py",
"chars": 2692,
"preview": "from contextlib import suppress\n\nfrom sc2.expiring_dict import ExpiringDict\n\n\ndef test_class():\n class State:\n "
},
{
"path": "test/test_pickled_data.py",
"chars": 48859,
"preview": "\"\"\"\nYou can execute this test running the following command from the root python-sc2 folder:\nuv run pytest test/test_pic"
},
{
"path": "test/test_pickled_ramp.py",
"chars": 7038,
"preview": "\"\"\"\nYou can execute this test running the following command from the root python-sc2 folder:\nuv run pytest test/test_pic"
},
{
"path": "test/test_replays.py",
"chars": 400,
"preview": "from pathlib import Path\n\nfrom sc2.main import get_replay_version\n\nTHIS_FOLDER = Path(__file__).parent\nREPLAY_PATHS = [p"
},
{
"path": "test/travis_test_script.py",
"chars": 3793,
"preview": "\"\"\"\nThis script is made as a wrapper for sc2 bots to set a timeout to the bots (in case they can't find the last enemy s"
},
{
"path": "test/upgradestest_bot.py",
"chars": 8399,
"preview": "from __future__ import annotations\n\nfrom loguru import logger\n\nfrom sc2 import maps\nfrom sc2.bot_ai import BotAI\nfrom sc"
}
]
// ... and 109 more files (download for full content)
About this extraction
This page contains the full source code of the BurnySc2/python-sc2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 256 files (1.4 MB), approximately 408.0k tokens, and a symbol index with 1283 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.