diff --git a/bot/.gitignore b/bot/.gitignore new file mode 100644 index 0000000..122e90e --- /dev/null +++ b/bot/.gitignore @@ -0,0 +1,112 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# Intellij +*.iml +/.idea + +# Build output +/build + +# Gradle files +/.gradle + +# VSCode +.vscode/ +*.code-workspace diff --git a/bot/.pylintrc b/bot/.pylintrc new file mode 100644 index 0000000..9db66d4 --- /dev/null +++ b/bot/.pylintrc @@ -0,0 +1,2 @@ +[TYPECHECK] +generated-members=QuickChats.* diff --git a/bot/LICENSE b/bot/LICENSE new file mode 100644 index 0000000..b7ce65a --- /dev/null +++ b/bot/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 RLGym + +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. diff --git a/bot/README.md b/bot/README.md new file mode 100644 index 0000000..3da0491 --- /dev/null +++ b/bot/README.md @@ -0,0 +1,21 @@ +# RLGymExampleBot +RLGym example bot for the RLBot framework, based on the official RLBotPythonExample + +## How to use this + +This bot runs the Actor class in `src/actor.py`, you're expected to replace that with the output of your model + +By default we use DefaultObs from RLGym, AdvancedObs is also available in this project. + +You can also provide your own custom ObservationBuilder by copying it over and replacing the `rlgym` imports with `rlgym_compat` (check `src/obs/` for some examples) + +## Changing the bot + +- Bot behavior is controlled by `src/bot.py` +- Bot appearance is controlled by `src/appearance.cfg` + +See https://github.com/RLBot/RLBotPythonExample/wiki for documentation and tutorials. + +## Running a match + +You can start a match by running `run.py`, the match config for it is in `rlbot.cfg` diff --git a/bot/RefreshEnv.cmd b/bot/RefreshEnv.cmd new file mode 100644 index 0000000..567fd78 --- /dev/null +++ b/bot/RefreshEnv.cmd @@ -0,0 +1,66 @@ +@echo off +:: This file is taken from chocolatey: +:: https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd +:: +:: RefreshEnv.cmd +:: +:: Batch file to read environment variables from registry and +:: set session variables to these values. +:: +:: With this batch file, there should be no need to reload command +:: environment every time you want environment changes to propagate + +::echo "RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell" +echo | set /p dummy="Refreshing environment variables from registry for cmd.exe. Please wait..." + +goto main + +:: Set one environment variable from registry key +:SetFromReg + "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL + for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do ( + echo/set "%~3=%%B" + ) + goto :EOF + +:: Get a list of environment variables from registry +:GetRegEnv + "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp" + for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do ( + if /I not "%%~A"=="Path" ( + call :SetFromReg "%~1" "%%~A" "%%~A" + ) + ) + goto :EOF + +:main + echo/@echo off >"%TEMP%\_env.cmd" + + :: Slowly generating final file + call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd" + call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd" + + :: Special handling for PATH - mix both User and System + call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd" + call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd" + + :: Caution: do not insert space-chars before >> redirection sign + echo/set "Path=%%Path_HKLM%%;%%Path_HKCU%%" >> "%TEMP%\_env.cmd" + + :: Cleanup + del /f /q "%TEMP%\_envset.tmp" 2>nul + del /f /q "%TEMP%\_envget.tmp" 2>nul + + :: capture user / architecture + SET "OriginalUserName=%USERNAME%" + SET "OriginalArchitecture=%PROCESSOR_ARCHITECTURE%" + + :: Set these variables + call "%TEMP%\_env.cmd" + + :: reset user / architecture + SET "USERNAME=%OriginalUserName%" + SET "PROCESSOR_ARCHITECTURE=%OriginalArchitecture%" + + echo | set /p dummy="Finished." + echo . \ No newline at end of file diff --git a/bot/rlbot.cfg b/bot/rlbot.cfg new file mode 100644 index 0000000..ddfac8a --- /dev/null +++ b/bot/rlbot.cfg @@ -0,0 +1,76 @@ +[RLBot Configuration] +# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. + +[Team Configuration] +# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. + +[Match Configuration] +# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. +# Number of bots/players which will be spawned. We support up to max 64. +num_participants = 6 +game_mode = Soccer +game_map = Mannfield +enable_rendering = True +enable_state_setting = True + +[Mutator Configuration] +# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. + +[Participant Configuration] +# Put the name of your bot config file here. Only num_participants config files will be read! +# Everything needs a config, even players and default bots. We still set loadouts and names from config! +participant_config_0 = src/bot.cfg +participant_config_1 = src/bot.cfg +participant_config_2 = src/bot.cfg +participant_config_3 = src/bot.cfg +participant_config_4 = src/bot.cfg +participant_config_5 = src/bot.cfg +participant_config_6 = src/bot.cfg +participant_config_7 = src/bot.cfg +participant_config_8 = src/bot.cfg +participant_config_9 = src/bot.cfg + +# team 0 shoots on positive goal, team 1 shoots on negative goal +participant_team_0 = 0 +participant_team_1 = 1 +participant_team_2 = 0 +participant_team_3 = 1 +participant_team_4 = 0 +participant_team_5 = 1 +participant_team_6 = 0 +participant_team_7 = 1 +participant_team_8 = 0 +participant_team_9 = 1 + +# Accepted values are "human", "rlbot", "psyonix", and "party_member_bot" +# You can have up to 4 local players and they must be activated in game or it will crash. +# If no player is specified you will be spawned in as spectator! +# human - not controlled by the framework +# rlbot - controlled by the framework +# psyonix - default bots (skill level can be changed with participant_bot_skill +# party_member_bot - controlled by the framework but the game detects it as a human +participant_type_0 = rlbot +participant_type_1 = rlbot +participant_type_2 = rlbot +participant_type_3 = rlbot +participant_type_4 = rlbot +participant_type_5 = rlbot +participant_type_6 = rlbot +participant_type_7 = rlbot +participant_type_8 = rlbot +participant_type_9 = rlbot + + +# If participant is a bot and not RLBot controlled, this value will be used to set bot skill. +# 0.0 is Rookie, 0.5 is pro, 1.0 is all-star. You can set values in-between as well. +# Please leave a value here even if it isn't used :) +participant_bot_skill_0 = 1.0 +participant_bot_skill_1 = 1.0 +participant_bot_skill_2 = 1.0 +participant_bot_skill_3 = 1.0 +participant_bot_skill_4 = 1.0 +participant_bot_skill_5 = 1.0 +participant_bot_skill_6 = 1.0 +participant_bot_skill_7 = 1.0 +participant_bot_skill_8 = 1.0 +participant_bot_skill_9 = 1.0 diff --git a/bot/run.py b/bot/run.py new file mode 100644 index 0000000..23ea98a --- /dev/null +++ b/bot/run.py @@ -0,0 +1,33 @@ +import subprocess +import sys + +DEFAULT_LOGGER = 'rlbot' + +if __name__ == '__main__': + + try: + from rlbot.utils import public_utils, logging_utils + + logger = logging_utils.get_logger(DEFAULT_LOGGER) + if not public_utils.have_internet(): + logger.log(logging_utils.logging_level, + 'Skipping upgrade check for now since it looks like you have no internet') + elif public_utils.is_safe_to_upgrade(): + subprocess.call([sys.executable, "-m", "pip", "install", '-r', 'requirements.txt']) + subprocess.call([sys.executable, "-m", "pip", "install", 'rlbot', '--upgrade']) + + # https://stackoverflow.com/a/44401013 + rlbots = [module for module in sys.modules if module.startswith('rlbot')] + for rlbot_module in rlbots: + sys.modules.pop(rlbot_module) + + except ImportError: + subprocess.call([sys.executable, "-m", "pip", "install", '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) + + try: + from rlbot import runner + runner.main() + except Exception as e: + print("Encountered exception: ", e) + print("Press enter to close.") + input() diff --git a/bot/run_gui.py b/bot/run_gui.py new file mode 100644 index 0000000..a3bced8 --- /dev/null +++ b/bot/run_gui.py @@ -0,0 +1,7 @@ +from rlbot_gui import gui + +# This is a useful way to start up RLBotGUI directly from your bot project. You can use it to +# arrange a match with the settings you like, and if you have a good IDE like PyCharm, +# you can do breakpoint debugging on your bot. +if __name__ == '__main__': + gui.start() diff --git a/bot/__init__.py b/bot/src/__init__.py similarity index 100% rename from bot/__init__.py rename to bot/src/__init__.py diff --git a/bot/action/continuous_act.py b/bot/src/action/continuous_act.py similarity index 100% rename from bot/action/continuous_act.py rename to bot/src/action/continuous_act.py diff --git a/bot/action/default_act.py b/bot/src/action/default_act.py similarity index 100% rename from bot/action/default_act.py rename to bot/src/action/default_act.py diff --git a/bot/action/discrete_act.py b/bot/src/action/discrete_act.py similarity index 100% rename from bot/action/discrete_act.py rename to bot/src/action/discrete_act.py diff --git a/bot/agent.py b/bot/src/agent.py similarity index 100% rename from bot/agent.py rename to bot/src/agent.py diff --git a/bot/appearance.cfg b/bot/src/appearance.cfg similarity index 100% rename from bot/appearance.cfg rename to bot/src/appearance.cfg diff --git a/bot/bot.cfg b/bot/src/bot.cfg similarity index 100% rename from bot/bot.cfg rename to bot/src/bot.cfg diff --git a/bot/bot.py b/bot/src/bot.py similarity index 100% rename from bot/bot.py rename to bot/src/bot.py diff --git a/bot/obs/advanced_obs.py b/bot/src/obs/advanced_obs.py similarity index 100% rename from bot/obs/advanced_obs.py rename to bot/src/obs/advanced_obs.py diff --git a/bot/obs/default_obs.py b/bot/src/obs/default_obs.py similarity index 100% rename from bot/obs/default_obs.py rename to bot/src/obs/default_obs.py diff --git a/bot/requirements.txt b/bot/src/requirements.txt similarity index 100% rename from bot/requirements.txt rename to bot/src/requirements.txt