Skip to content

nunorbrito18/pokebot-gen3

 
 

Repository files navigation

PokéBot Gen3 (libmgba)

Python Discord YouTube Twitter

PokéBot Gen3 (libmgba) is a bot, written in Python that automatically shiny hunts 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 profiles/<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, 23.10 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.12 (64-bit)
  • Linux only: Install the following packages with apt or appropriate package manager: sudo apt install python3-tk libmgba0.10 portaudio19-dev
  • Note: running the bot will automatically install required Python packages and download + extract libmgba - if you're using Python for any other projects, consider using a venv to isolate these packages from your base environment

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 profiles/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 pokebot.py or run python pokebot.py in a terminal > type a profile name > click Load Existing Save
  • Open the save state file you just saved
  • A new bot profile will be created in the profiles/ folder and set up all required files

🌍 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

Spin clockwise on a single tile, useful for Safari Zone and repel tricking as it doesn't count steps

Start the mode while in the overworld, in any patch of grass/water/cave.

🎥 Click here to show a video example
spin.mp4
✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald 🔥 FireRed 🌿 LeafGreen
English
Japanese 🟨 🟨 🟨 🟨 🟨
German 🟨 🟨 🟨 🟨 🟨
Spanish 🟨 🟨 🟨 🟨 🟨
French 🟨 🟨 🟨 🟨 🟨
Italian 🟨 🟨 🟨 🟨 🟨

💼 Starters

Soft reset for starter Pokémon.

🎥 Click here to show a video example
hoenn_starters.mp4
  • 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 profiles/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 profiles/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)

FireRed and LeafGreen (Kanto)

  1. Select the starter in profiles/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

Emerald (Johto)

  1. Select the starter in profiles/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

Ruby, Sapphire and Emerald (Hoenn)

  1. Select the starter in profiles/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
✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald 🔥 FireRed 🌿 LeafGreen
English
Japanese - - - - -
German - - - - -
Spanish - - - - -
French - - - - -
Italian - - - - -

🎣 Fishing

Start the mode while facing the water, with any fishing rod registered.

🎥 Click here to show a video example
fishing.mp4
✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald 🔥 FireRed 🌿 LeafGreen
English
Japanese - - - - -
German - - - - -
Spanish - - - - -
French - - - - -
Italian - - - - -

🚲 Bunny Hop

Bunny hop on the spot with the Acro Bike, useful for Safari Zone and repel tricking as it doesn't count steps.

Start the mode while in the overworld, in any patch of grass/cave, with the Acro Bike registered.

  • Note: Bunny Hop is ~10% slower encounters/h on average than spin mode
🎥 Click here to show a video example
bunny_hop.mp4
✅🟨❌ Click here for support information
🟥 Ruby 🔷 Sapphire 🟢 Emerald
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 placeholder for future/planned features.

Multi-instance botting

The bot stores all profile information, such as save games, screenshots, statistics, etc. in the profile profiles/<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 profiles/<profile name>/stats/.

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

Example:

├── /profiles
    │
    ├── /emerald-profile
    │     current_save.sav
    │     current_state.ss1
    │     discord.yml          <-- config loaded for 'emerald-profile'
    │     general.yml          <-- config loaded for 'emerald-profile'
    │
    ├── /firered-profile
    │     current_save.sav
    │     current_state.ss1
    │     general.yml          <-- config loaded for 'firered-profile'
    │
    │   catch_block.yml        <-- config loaded for all profiles
    │   cheats.yml             <-- config loaded for all profiles
    │   customcatchfilters.py  <-- config loaded for all profiles
    │   customhooks.py         <-- config loaded for all profiles
    │   discord.yml            <-- config loaded for all profiles except 'emerald-profile'
    │   general.yml            <-- config loaded for all profiles except 'emerald-profile' and 'firered-profile'
    │   logging.yml            <-- config loaded for all profiles
    │   obs.yml                <-- config loaded for all profiles

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

starter - choose which starter Pokémon to hunt for, used when bot mode is 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

Save raw Pokémon data (.pk3)

The bot can dump individual Pokémon files (.pk3 format) to be managed/transferred in the PKHeX save editor.

The Pokémon are dumped to the pokemon/ folder in your profile, in the following format:

273 ★ - SEEDOT - Modest [180] - C88CF14B19C6.pk3 (<nat_dex_num> <shiny ★> - <mon_name> - <nature> [<IV sum>] - <pid>.pk3)

save_pk3:

  • all - dump all encounters
  • shiny - dump shiny encounters
  • custom - dump custom catch filter encounters

Feel free to share any rare/interesting .pk3 files in #pkhexchange💱!

Automatically add Pokémon to PC storage (.pk3)

While auto-catch is currently still a work in progress, the following option automatically import encountered Pokémon into your PC storage.

Imported Pokémon will be placed into the first available PC slot, in a regular PokéBall.

If space is available in the PC, and the Pokémon was successfully imported, the bot will run from the encounter and continue to hunt.

import_pk3 - enable automatic .pk3 import to PC storage

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 /stats returns the phase and total statistics (totals.json)

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

GET /event_flags returns all event flags for the current save file (optional parameter ?flag=FLAG_NAME to get a specific flag)

GET /emulator returns information about the emulator core + the current loaded game/profile

GET /fps returns a list of emulator FPS (frames per second), in intervals of 1 second, for the previous 60 seconds


⏩ 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 modes 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)

🐛 Debugging

The bot supports auto-starting a profile and can also be launched into a 'debug' mode which can aid bot development.

positional arguments:
  profile               Profile to initialize. Otherwise, the profile selection menu will appear.

options:
  -h, --help            show this help message and exit
  -m {Manual,Spin,Starters,Fishing,Bunny Hop}, --bot-mode {Manual,Spin,Starters,Fishing,Bunny Hop}
                        Initial bot mode (default: Manual)
  -s {0,1,2,3,4}, --emulation-speed {0,1,2,3,4}
                        Initial emulation speed (0 for unthrottled; default: 1)
  -nv, --no-video       Turn off video output by default
  -na, --no-audio       Turn off audio output by default
  -t, --always-on-top   Keep the bot window always on top of other windows
  -d, --debug           Enable extra debug options and a debug menu

❤ Attributions

Other awesome PokéBot projects:

This project would not be possible without the decompiled symbol tables and other various data from the following projects:

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%