PMD-Bot is a botting framework for Pokémon Mystery Dungeon: Explorers of Sky. You can use it to write fully autonomous dungeon bots! For example, you can write a bot that does runs of Mystery Dungeons without human input. Watch the showcase video! (Older version)
- PMD-Bot is written in FCEUX Lua and runs on DeSmuME for Windows (Lua scripting is sadly not supported on DeSmuME for Mac/Linux).
Broadly, PMD-Bot runs using a three-step process, repeated every turn:
- Detect what's happening in the dungeon by reading state information from RAM.
- Make decisions on how to act based on the current state.
- Make the necessary inputs (including menu navigation) in order to perform whatever action was decided on.
For a more detailed discussion, see Writing a bot.
- A modified version of the Jumper library for pathfinding (included as a submodule of this repository).
Once all the prerequsites are satisfied, you can install PMD-Bot one of two ways: with Git or by downloading. The Git way is easier if you're familiar with Git, but if not, you can use the Download method.
- Have Windows
- Install DeSmuME
- PMD-Bot is written for the North American version of Pokémon Mystery Dungeon: Explorers of Sky. No guarantees that it'll work on other versions.
- Before you can run any scripts, you'll need to set up Lua on DeSmuME. The FCEUX Lua documentation is for the FCEUX emulator, not DeSmuME, but is mostly applicable.
- If you need some help and don't want to comb through the documentation, here's a link to the necessary Lua binaries for 64-bit Windows (32-bit version). Extract the archive and copy
lua5.1.dllandlua51.dllinto the same directory as your DeSmuME executable file. After doing this, you should be able to run Lua scripts on DeSmuME.
- If you need some help and don't want to comb through the documentation, here's a link to the necessary Lua binaries for 64-bit Windows (32-bit version). Extract the archive and copy
- Retrieve the repository locally with the Jumper submodule (for example, by doing
git clone --recursive https://github.com/johanngan/pmd-bot.gitthrough the command line). - If you cloned the project but forgot to pull the submodule with the
--recursiveoption, rungit submodule update --initfrom within the PMD-Bot repository to set up the modified Jumper library.
- Download the latest release as a zip file. You can also download the latest version (possibly unreleased) by clicking the green "Code" button on the GitHub repository page, then clicking "Download ZIP".
- When downloading the PMD-Bot code this way, the
Jumperfolder will be empty and will need to be installed manually. Download the custom PMD-Bot Jumper code as a zip file. Unzip the file, and rename theJumper-jumper-1.8.1-1-pmd-botfolder to justJumper. Then replace theJumpersubfolder in the PMD-Bot folder with the newJumperfolder you just renamed.
Bots are defined through the Agent class, which is used by the main execution loop in main.lua. The Agent:act() method contains the main logic for the bot. This method is called every turn with the current dungeon information, and should take some action each turn in response to the environment. If you want to set up state information for your bot, you can do so in Agent:init(), which is called only once at instantiation. If you want to run any code at the beginning or end of each turn, right before or after Agent:act(), you can do so in Agent:setupTurn() and Agent:finalizeTurn().
Agent:setupTurn() and Agent:finalizeTurn() will not be called if the Agent.turnOngoing flag is set, so if you want an action in Agent:act() not to be treated as turn-ending, set the flag before returning. Note that Agent.turnOngoing will always be reset to false before Agent:act() is called (i.e., by default each call is assumed to consume a turn), so you must explicitly set Agent.turnOngoing to true in Agent:act() every time you want to continue a turn.
Note that since the return of Agent:act() may not necessarily signify the end of the turn (more events could still happen that change the state), Agent:finalizeTurn() should not rely on data that could dynamically change as the turn progresses, and should only be used to manipulate static data stored within the Agent instance.
This repository comes with example bots in the agent directory. However, you can modify them or write new ones to suit your needs. To write a new bot, create a file that implements the Agent class as a subclass of the BaseAgent base class; see the agent directory README for more information. To switch out the current bot with another, modify the require statement in main.lua to use the file containing the desired bot.
The example bots make direct use of the following utilities:
- Dungeon state information is accessed through the full
state(stateinfo.state) and visiblestate(visibleinfo.state) objects passed toAgent:act(). - Actions in game are performed using the
actionsmodule. - Internal ID codes are referenced from the
codesmodule. - Game mechanics utilities are referenced from the
mechanicsmodule. - Other utilities include pathfinding and message reporting, which are handled in their respective submodules in
utils.
Modifying Agent.lua should be sufficient for many use cases. However, if you need to change the nature of the main execution loop, you can also modify main.lua.
These instructions assume the interface of DeSmuME 0.9.12, but hopefully they won't change much in future versions.
- Start up Pokémon Mystery Dungeon: Explorers of Sky (NA), and enter a dungeon (this you'll have to do manually). Note that you won't be able to run a bot outside of a dungeon.
- In the DeSmuME "Tools" menu, select "Lua Scripting" -> "New Lua Script Window..."
- In the window that just opened, click "Browse..." and select
main.luain the PMD-Bot directory. - The bot should start automatically. If not, start it by clicking "Run".