Skip to content

kippermand/pokebot-gen3

 
 

Repository files navigation

PokéBot Gen3 (libmgba)

Python Discord YouTube Twitter

PokéBot Gen3 for mGBA is a Python script, written to automatically shiny hunt in Pokémon Ruby, Sapphire, Emerald, FireRed and LeafGreen.

Initially created to complete a Prof. Oak and Living ✨Shiny✨ Dex Challenge in Pokémon Emerald, a 🔴24/7 livestream of the challenge can be found ongoing here.

🔴24/7✨Shiny✨Hunting Bot

pokebot-gen3.mp4
Main Interface Load Save State Debugger
image image image
Shiny Notifications Phase Stats Milestones
image image image

📖 Preamble

  • This is still in development, as such, functionality is subject to change without warning - always make sure you back up your config/<profile name>/ folder before updating your bot!
  • Reach out in Discord #bot-support-libmgba❔ if you have any issues

The bot is frame perfect and can cheat by reading data from any point in memory. By default it will attempt to perform most actions as if a human were playing to make gameplay as representative as possible, some examples:

  • Starter Pokémon are generated just 1 frame after confirming the starter selection, the bot will wait until the battle begins, and the starter Pokémon sprite is visible before resetting
  • It's possible to peek inside un-hatched eggs to view stats and shininess as soon as they're received from the daycare, the bot will wait until the eggs are fully hatched before checking and logging
  • These are intentional design decisions, bot cheats can be used to bypass them (in most cases)

⚠ Photosensitivity Warning

  • Running mGBA at unbound speeds, will cause very fast and bright flashing!
  • Any unbounded video examples on this page will be hidden by default, and marked with ⚠ photosensitivity warning

🔒 Prerequisites

Operating Systems

  • Windows (64-bit)
  • Linux (64-bit)
    • Note: only tested and confirmed working on Ubuntu 23.04 and Debian 12

Download the Bot

To download the latest bot from GitHub, go to the top of the page > click the green Code button > Download ZIP.

Alternatively, if you'd like to be able to easily pull the latest updates without re-downloading the entire ZIP:

  • Install GitHub Desktop (you don't need an account)
  • Click Clone a repository from the Internet...
  • Use repository URL https://github.com/40Cakes/pokebot-gen3.git and choose a save location on your PC
  • Click Clone
  • Any time there's a new update, you can pull the latest changes by clicking Fetch origin, then Pull origin

Requirements

  • Python 3.11
  • Double click requirements.py or run python requirements.py in a terminal to install required Python modules and download libmgba automatically
    • Linux only: Install the following packages with apt or appropriate package manager: sudo apt install python3-tk libmgba0.10 portaudio19-dev

Optional

  • Windows Terminal - recommended for full 🌈colour🌈 and ✨emoji support✨ in the console output
  • Notepad++ - recommended for syntax highlighting while editing .yml config files

❓ How To Run

  • Place some official Pokémon .gba ROMs into the roms/ folder
  • Double click pokebot.py or run python pokebot.py in a terminal and follow the on-screen steps to create and/or select a profile

The bot ships with the default mGBA input mapping, see config/keys.yml to view the default mapping, or customise them to your preference.

The bot will pause once a shiny is encountered. You must ensure you are able to escape battle 100% of the time, otherwise the bot will get stuck. Auto-catching and other features will be added in due time.


💾 Import a Save

If you have a save from mGBA that you'd like to import and use with the bot, then you will need to import the save state.

  • In mGBA, run a game and load into the save file
  • File > Save State File... > Save
  • Double click import.py or run python import.py in a terminal to launch the save importer tool
  • Open the save state file you just saved
  • A new bot profile will be created in the config/ folder and set up all required files
  • If the importer tool detects files in the stats/ or config/ folders from old versions of the bot (from commit ec5d702, 7th October, 2023 or earlier), then they will be copied into your new profile

🌍 Supported Games and Languages

Variations of games, languages and revisions may have different memory offsets, there will be a table of supported/tested variations under each bot mode listed below.

  • ✅ Supported (tested)
  • 🟨 Supported (not tested)
  • ❌ Not supported

ROM hacks will likely not work, and are ❌ not supported or planned to be supported!

The ROMs in the roms/ folder are checked and verified against a list of all known official gen3 game hashes. If you really want to test a ROM hack with the bot, you must add the SHA1 hash of the ROM to modules/Roms.py.

The SHA1 hash of a ROM can be calculated with any of the following methods:

  • ROM Hasher
  • Windows Powershell: Get-FileHash 'rom_name.gba' -Algorithm SHA1
  • Linux: sha1sum 'rom_name.gba'

Please do not seek support or complain if you find that your ROM hack does not work with the bot.


🤖 Bot Modes

  • The bot mode can be changed at any time while the bot is running by using the menu on the UI
  • manual mode is the default mode
  • Press Tab to toggle between manual mode and a previously selected mode

🔧 manual

Manual mode simply disables all bot inputs, allowing you to track encounters and stats on your own shiny hunts as you play the game normally.

🔄 spin

Start the bot while in the overworld, in any patch of grass/water/cave. The bot will mash random directions to spin on a single tile.

  • spin mode is useful for Safari Zone and repel tricking as it doesn't count steps!
✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald 🔥 FireRed 🌿 LeafGreen
English
Japanese - - - - -
German - - - - -
Spanish - - - - -
French - - - - -
Italian - - - - -

💼 starters

Soft reset for starter Pokémon.

  • For modes that use soft resets such as starters, the bot will track RNG to ensure a unique frame is hit after every reset, this is to prevent repeatedly generating an identical Pokémon, this will cause soft resets to take progressively longer over time
  • If resets begin to take too long, it is recommended to start a new save file with a different TID to reset this delay or check out config/cheats.yml
  • Note: Even though you set the trainer to face the desired PokéBall, it is still important to set the correct starter in the config! This option is used by the bot to track frames to ensure a unique starter is generated every time
  • Note: For the time being, Johto starters will automatically enable the starters option in config/cheats.yml, the shininess of the starter is checked via memhacks as start menu navigation is WIP (in future, shininess will be checked via the party summary menu)

RSE

  1. Select the starter in config/general.yml - Treecko, Torchic or Mudkip
  2. Face the starters bag, and save the game (in-game, not a save state)
  3. Start the bot

FRLG

  1. Select the starter in config/general.yml - Bulbasaur, Charmander or Squirtle
  2. Face the desired PokéBall in Oak's lab, save the game (in-game, not a save state)
  3. Start the bot

Johto (Emerald)

  1. Select the starter in config/general.yml - Chikorita, Cyndaquil or Totodile
  2. Face the desired PokéBall in Birch's lab, save the game (in-game, not a save state)
  3. Start the bot
✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald 🔥 FireRed 🌿 LeafGreen
English
Japanese - - - - -
German - - - - -
Spanish - - - - -
French - - - - -
Italian - - - - -

🎣 fishing

Start the bot facing the water, with any fishing rod registered.

✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald 🔥 FireRed 🌿 LeafGreen
English
Japanese - - - - -
German - - - - -
Spanish - - - - -
French - - - - -
Italian - - - - -

🛠 Configuration

Configuration files are loaded and validated against a schema, once at bot launch. Any changes made while the bot is running will not take effect until the bot is stopped and restarted.

🚧 Work in progress 🚧

A lot of the config in .yml files is is placeholder for future/planned features.

Multi-instance botting

The bot stores all profile information, such as save games, screenshots, statistics, etc. in the profile config/<profile name>/) folder, which is automatically created once you create a new profile in the GUI.

Running multiple instances of the bot is as easy as starting the bot multiple times and loading a different profile each time. You should not run multiple instances of the bot with the same profile simultaneously!

Statistics are saved into a subfolder of your profile config/<profile name>/stats/.

The bot will first attempt to load individual config files from your profile folder (config/<profile name>/config/), if that folder does not exist or any of the configuration files are missing, it will load the default config file in the config/ folder. This allows you to selectively override specific config files on a per profile basis.

Example:

├── /config
    │   battle.yml             <-- loaded for all profiles
    │   catch_block.yml        <-- loaded for all profiles
    │   cheats.yml             <-- loaded for all profiles
    │   CustomCatchFilters.py  <-- loaded for all profiles
    │   CustomHooks.py         <-- loaded for all profiles
    │   discord.yml            <-- loaded for all profiles except my-pokemon-emerald-profile
    │   general.yml            <-- loaded for all profiles except my-pokemon-emerald-profile and my-firered-profile
    │   logging.yml            <-- loaded for all profiles
    │   obs.yml                <-- loaded for all profiles
    │
    ├── /my-pokemon-emerald-profile
    │   └───/config
    |           discord.yml    <-- loaded for my-pokemon-emerald-profile
    │           general.yml    <-- loaded for my-pokemon-emerald-profile
    │
    ├── /my-firered-profile
        └───/config
                general.yml    <-- loaded for my-firered-profile

keys.yml - Emulator input mapping

This file controls keyboard to GBA button mappings.

  • For a full list of available key codes, see here or here (column .keysym)

Default Input Mapping

  • A button: X
  • B button: Z
  • D-Pad: Arrow keys (Up, Down, Left, Right)
  • Start button: Enter
  • Select button: Backspace
  • Toggle manual bot mode on/off: Tab
  • Toggle video output on/off: V
  • Toggle audio output on/off: B
  • Zoom window scaling in/out: +, -
  • Create save state: Ctrl + S
  • Load save state menu: Ctrl + L
  • Reset emulator/reboot game: Ctrl + R
  • Exit the bot and emulator: Ctrl + Q
  • Emulator speed:
    • 1x speed: 1
    • 2x speed: 2
    • 3x speed: 3
    • 4x speed: 4
    • Unbound: 0 - ⚠ Photosensitivity warning: this will run the emulator as fast as possible!

general.yml - General config

Click to expand

General

bot_mode - set the bot to automatically launch into a specific mode (see 🤖 Bot Modes)

starter - used when bot_mode set to starters (see 💼 starters)

logging.yml - Logging and console output config

Click to expand

Logging

log_encounters - log all encounters to .csv (stats/encounters/ folder), each phase is logged to a separate file

Console output

The following console options will control how much data is displayed in the Python terminal/console, valid options are verbose, basic or disable

  • encounter_data
  • encounter_ivs
  • encounter_moves
  • statistics

discord.yml - Discord integration config

Click to expand

Discord

For privacy reasons, rich presence and webhooks are disabled by default.

Discord rich presence

rich_presence - Rich presence will display information on your Discord profile such as game, route, total encounters, total shinies and encounter rate.

Discord_tC7ni4A9L4

Discord webhooks

global_webhook_url - global Discord webhook URL, default webhook for all Discord webhooks unless specified otherwise

  • Warning: this webhook is considered sensitive! If you leak your webhook, anyone will be able to post in your channel
  • Edit Channel > Integrations > Webhooks > New Webhook > Copy Webhook URL to generate a new webhook

iv_format - changes IV formatting displayed in messages, set to basic or formatted

  • basic:
    HP: 31 | ATK: 31 | DEF: 31 | SPA: 31 | SPD: 31 | SPE: 31

  • formatted:

    ╔═══╤═══╤═══╤═══╤═══╤═══╗
    ║HP │ATK│DEF│SPA│SPD│SPE║
    ╠═══╪═══╪═══╪═══╪═══╪═══╣
    ║31 │31 │31 │31 │31 │31 ║
    ╚═══╧═══╧═══╧═══╧═══╧═══╝
    

bot_id - set to any string you want, this string is added to the footer of all Discord messages, it can be useful to identify bots if multiple are set to post in the same channel

Webhook parameters

enable - toggle the webhook on/off

webhook_url - set to post specific message types to different channels, defaults to global_webhook_url if not set

  • Commented out in config file by default, remove the leading # to uncomment

Each webhook type also supports pinging @users or @roles.

ping_mode - set to user or role

  • Leave blank to disable pings

ping_id - set to user/role ID

  • Settings > Advanced > Enable Developer Mode to enable Discord developer mode
  • Right click user/role > Copy ID

Webhook types

shiny_pokemon_encounter - Shiny Pokémon encounters

Discord_c0jrjiKGRE

pokemon_encounter_milestones - Pokémon encounter milestones messages every interval encounters

Discord_ObO28tVrPk

shiny_pokemon_encounter_milestones - Shiny Pokémon encounter milestones every interval encounters

Discord_w7UfnPxlJZ

total_encounter_milestones - Total encounter milestones every interval encounters

Discord_ual6ZrsLNm

phase_summary - Phase summary, first summary at first_interval, then every consequent_interval after that

Discord_plUyXtjnQt

anti_shiny_pokemon_encounter - Anti-shiny Pokémon encounters

  • Anti-shinies are just a bit of fun, they are mathematically, the complete opposite of a shiny
  • An SV of 65,528 - 65,535 is considered anti-shiny

Discord_G2hvTZG21a

catch_block.yml - Catch block config

Click to expand

Block list

A list of shinies to skip catching, useful if you don't want to fill up your PC with very common encounters.

block_list - list of Pokémon to skip catching, example:

block_list:
  - Poochyena
  - Pidgey
  - Rattata
  • Note: phase stats will still be reset after encountering a shiny on the block list.
  • The block list is reloaded by the bot after every shiny encounter, so you can modify this file while the bot is running!

cheats.yml - Cheats config

Click to expand

Cheats

Perform actions not possible by a human, such as peeking into eggs to check shininess, knowing instantly which route a roamer is on, instantly locate Feebas tiles etc.

RNG manipulation options may be added to the bot in the future, all cheats are disabled by default.

starters - soft reset as soon as possible after receiving the starter Pokémon, this will bypass slow battle/menu animations, saving time

starters_rng - inject a random value into gRngValue before selecting a starter Pokémon

  • Removes all delays before selecting a starter Pokémon, preventing resets from progressively slowing down over time as the bot waits for unique frames
  • Gen3 Pokémon games use predictable methods to seed RNG, this can cause the bot to find identical PID Pokémon repeatedly after every reset (which is why RNG manipulation is possible), see here and here for more technical information
  • Uses Python's built-in random library to generate and inject a 'more random' (still pseudo-random) 32-bit integer into the gRngValue memory address, essentially re-seeding the game's RNG

obs.yml - OBS config

Click to expand

OBS

OBS WebSocket Server Settings

The obs_websocket config will allow the bot to send commands to OBS via WebSockets, see here for more information on OBS WebSockets.

Enable WebSockets in OBS > Tools > Websocket Server Settings > Enable WebSocket Server

host - hostname/IP address OBS WebSockets is listening on

port - TCP port OBS WebSockets is listening on

password - password to authenticate to WebSocket server (required)

OBS WebSocket Parameters

shiny_delay - delay catching a shiny encounter by n frames, useful to give you viewers some time to react before saving a replay

discord_delay - delay Discord webhooks by n seconds, prevent spoilers if there is a stream delay

screenshot - take OBS screenshot of shiny encounter

  • Note: OBS > Settings > Hotkeys > Screenshot Output must be set to Ctrl + F11
  • The bot does not emulate keystrokes, it simply sends a TriggerHotkeyByKeySequence (Ctrl + F11) WebSocket command
  • Screenshot is taken after shiny_delay to allow stream overlays to update

replay_buffer - save OBS replay buffer after replay_buffer_delay

  • Note: OBS > Settings > Hotkeys > Replay Buffer > Save Replay must set to Ctrl + F12
  • The bot does not emulate keystrokes, it simply sends a TriggerHotkeyByKeySequence (Ctrl + F12) WebSocket command

replay_buffer_delay - delay saving OBS replay buffer by n seconds

  • Runs in a separate thread and will not pause main bot thread
  • If the replay buffer is long enough, it will also capture some encounters after the shiny encounter

discord_webhook_url - Discord webhook URL to post OBS screenshot, after a shiny encounter

replay_dir - OBS screenshot/replay buffer folder

  • OBS > Settings > Output > Recording > Recording Path
  • Relative folder to pokebot.py, this is used to post stream screenshot to Discord if discord_webhook_url is set

Web server

The http_server config will enable a Flask HTTP server, which can be used to retrieve data and drive stream overlays.

enable - toggle web server on/off

ip - IP address for server to listen on

port - TCP port for server to listen on

  • Port must be unique for each bot instance

HTTP Endpoints

All HTTP responses are in JSON format.

GET /trainer - returns trainer information such as name, TID, SID, map bank, map ID, X/Y coordinates etc.

GET /items - returns all a list of all items in the bag and PC, and their quantities

GET /party - returns a detailed list of all Pokémon in the party

GET /encounter_log returns a detailed list of the recent 10 Pokémon encounters

GET /shiny_log returns a detailed list of all shiny Pokémon encounters (shiny_log.json)

GET /encounter_rate returns the current encounter rate (encounters per hour)

GET /stats returns the phase and total statistics (totals.json)


⏩ Tips/Tricks

Optimal game settings

  • Set TEXT SPEED to FAST
  • Set BATTLE SCENE to OFF
  • Utilise repel tricks to boost encounter rates of target Pokémon
  • Using bot_mode spin or bunny_hop and repels will become effectively infinite + steps won't be counted in Safari Zone
  • Use a lead Pokémon with encounter rate boosting abilities, such as Illuminate
  • Use a lead Pokémon with a short cry
  • Use a lead Pokémon with a single character nickname
  • Don't use a shiny lead Pokémon (shiny animation takes a few frames at the start of every battle)

❤ Attributions

Other awesome PokéBot projects:

This project would not be possible without the symbols tables from the Pokémon decompilation projects:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%