Skip to main content

Bug Catching Contests

Author(s): MrHam88.
Research: pret/pokeheartgold.

This page is a guide to the Bug Catching Contest in Pokémon HeartGold and SoulSilver, specifically covering the encounter set data: which Pokémon can appear, when they appear, and how their effective encounter rates are determined. It also covers how to edit this data using DSPRE's Bug Contest editor, and via direct hex editing for reference.

info

This guide focuses on the encounter set data for the contest. Information on the contest's scripting, NPC opponents, and judging logic may be added to this page in the future.

The Bug Catching Contest takes place at the National Park on Tuesdays, Thursdays, and Saturdays, and is initiated by an NPC in either connecting gate building. The encounter set described in this page applies for any visit to the National Park where the contest has been initialised. For any visit to the National Park where the contest has not been initialised, the area's normal encounter set is used.


Encounter Sets

The game defines 4 separate encounter sets of 10 Pokémon each, stored sequentially in the binary file data/mushi/mushi_encount.bin. Which set is active depends on two factors: whether the player has obtained the National Pokédex, and the day of the week.

Set IDConditionDay(s)
0No National Pokédex (always), or National Pokédex on Sunday/MondayAny
1National Pokédex obtainedTuesday / Wednesday
2National Pokédex obtainedThursday / Friday
3National Pokédex obtainedSaturday

Set 0 acts as the default fallback. On any day where the National Pokédex is not obtained, Set 0 is always used.

note

The day of the week used to determine the active encounter set is the actual day on the hardware or emulator clock, not the day parameter passed to the BugContestControl script command. That script parameter may affect other aspects of the contest initialisation, but the encounter set selection is entirely driven by the hardware clock.

This logic is implemented in BugContest_InitEncounters in the game's source. Once the National Pokédex flag is set, the weekday index is divided by 2 (using integer division) to derive the set index. The full mapping across all days is:

DayWeekday IndexIndex / 2 (integer)Set Used
Sunday00Set 0
Monday10Set 0
Tuesday21Set 1
Wednesday31Set 1
Thursday42Set 2
Friday52Set 2
Saturday63Set 3

Sunday and Monday both map to Set 0 via division, consistent with the fallback behaviour.


Encounter Data Structure (Plain Language)

Each encounter set contains exactly 10 Pokémon entries. Each entry defines:

  • Species: Which Pokémon can appear.
  • Min Level / Max Level: The level range the Pokémon can be (a random level within the range is chosen when triggered).
  • Rate: A threshold value used to determine how likely this Pokémon is to appear (see The Rate System below).
  • Score (Rarity Factor): A component used in calculating the Pokémon's score when judged at the end of the contest (higher for rarer Pokémon).

Default Encounter Set (Set 0 - Pre-National Dex)

SlotSpeciesMin LvMax LvRate (Raw)Effective RateScore (Rarity Factor)
0Caterpie7188020%60
1Weedle7186020%60
2Metapod9185010%60
3Kakuna9184010%60
4Butterfree12153010%80
5Beedrill12152010%80
6Venonat1016155%80
7Paras1017105%80
8Scyther131455%100
9Pinsir131405%100

The Rate System

In Simple Terms

When a Bug Catching Contest encounter is triggered, the game picks a random number between 0 and 99. It then goes through the 10 Pokémon slots in order from top to bottom and checks whether the random number is greater than or equal to that slot's Rate value. The first slot where this is true determines the Pokémon that appears.

Because the Rate values are stored in descending order (high to low), only a specific range of numbers will "land" on each slot:

Example (Set 0):

  • Roll = 85 → 85 ≥ 80 (Caterpie) ✓ → Caterpie appears
  • Roll = 63 → 63 ≥ 80? No. 63 ≥ 60 (Weedle)? Yes ✓ → Weedle appears
  • Roll = 7 → Fails all checks until Pinsir (Rate 0) → Pinsir appears

The actual effective probability for a slot is calculated as:

  • First slot (index 0): 100 - Rate (since the roll space is 0-99, the ceiling is 100)
  • All other slots: Rate of previous slot - Rate of this slot (only valid when Rate values are in strictly descending order; see Key Rules below)

This means a Rate value is not a percentage -- it is a threshold. The probabilities only emerge from the gap between consecutive Rate values.

Key Rules

caution

Rate 0 does not mean 0% chance. A rate of 0 means the slot's check (roll >= 0) is always true, so it acts as the final fallback. Any rolls not caught by an earlier slot will result in this Pokémon appearing. For the vanilla data this means a Rate 0 slot always has a 5% effective rate.

caution

Order matters. Do not break the descending order of Rate values. If a later slot has a Rate value that is equal to or higher than the previous slot's Rate, the roll will always be caught by the earlier slot first, and the later slot will never be triggered (0% effective rate). This is covered in the DSPRE warning system described below.

note

All four encounter sets use the same Rate values (80, 60, 50, 40, 30, 20, 15, 10, 5, 0), so all sets share the same probability distribution (20%, 20%, 10%, 10%, 10%, 10%, 5%, 5%, 5%, 5%). Only the species assigned to each slot differ between sets.

Rate Value Reference

The table below shows how any valid descending sequence of Rate values translates to effective encounter probabilities:

SlotRate (Raw)FormulaEffective Rate
080100 − 8020%
16080 − 6020%
25060 − 5010%
34050 − 4010%
43040 − 3010%
52030 − 2010%
61520 − 155%
71015 − 105%
8510 − 55%
905 − 05%

The effective rates across all 10 slots must always sum to 100%.


Editing with DSPRE

The Bug Catching Contest encounter data can be edited using DS Pokémon Rom Editor (DSPRE), available as part of the Canary release (and should be included in the next stable release after v1.14.2.4). The Bug Contest editor is located under Sp. Encounters in the main toolbar, then the Bug Contest tab.

DSPRE Bug Contest Editor showing Set 0 with Caterpie selected

Interface Overview

  • Encounter Set dropdown: Selects which of the 4 sets to view and edit. The description below the dropdown explains the conditions under which that set is active.
  • Encounters list (10 per set): Lists all 10 slots, in order, in the active set. Each entry shows the species, level range, Rate, and Score values at a glance.
  • Encounter Details panel: Edit the selected slot's Species, Min Level, Max Level, Rate, and Score.
    • The ? button next to the Rate field opens the Rate System Help dialog, which explains the threshold system and common mistakes (see image below).
    • The Effective: ~X% label next to the Rate field displays the computed effective rate for the selected slot in real time, based on the raw Rate values in the current set.
  • Save: Writes changes to the ROM's unpacked project_DSPRE_contents folder. The main DSPRE "Save ROM" button must be used to pack everything into an .nds file (along with any other changes).
  • Export / Import: Work with the encounter set data as an external file.
  • Locate: Opens the file explorer at the location of the underlying data file (data/mushi/mushi_encount.bin) within the unpacked project folder.

DSPRE Rate System Help dialog explaining the threshold mechanic

Step-by-Step: Changing an Encounter

  1. Open your ROM in DSPRE.
  2. Navigate to Sp. Encounters in the top toolbar, then click the Bug Contest tab.
  3. Use the Encounter Set dropdown to select the set you want to edit (see the Encounter Sets table above for which set corresponds to which in-game condition).
  4. Click the slot in the Encounters list you want to modify.
  5. In the Encounter Details panel:
    • Change Species to the desired Pokémon.
    • Set the Min Level and Max Level. A random level between (and including) these values will be assigned when that encounter triggers.
    • Set the Rate. Check the Effective: ~X% label to confirm the resulting probability. All 10 Rate values must remain in strictly descending order (each lower than the one above it) to avoid unreachable slots. A warning message will display below the encounter list if this rule is violated.
    • Set the Score -- this is the rarity factor component added to the judge's score calculation for this Pokémon (see Scoring below).

DSPRE rate ordering warning, showing "Entry 5 (rate 20) never triggers - rate must be < 18." 6. Click Save to write changes to the ROM's unpacked project_DSPRE_contents folder. Use the main DSPRE "Save ROM" button when ready to pack into an .nds file.

note

Changes made to one set do not affect any other set. You must repeat the process for each set you want to modify.

Designing a Valid Rate Sequence

When customising encounter rates, keep these rules in mind:

  • Rates must be strictly descending across the 10 slots (each slot's Rate must be lower than the slot above it in the list).
  • The last slot (slot 9) must always have Rate = 0 to ensure all possible roll values (0-99) are accounted for, giving 100% total probability. Any other value here creates a chance of no encounter being selected, which will likely cause an in-game bug or crash.
  • The effective probability of any slot is Rate[slot-1] - Rate[slot] (or 100 - Rate[0] for the first slot).
  • It is not required to have 10 distinct Rate values. For example, if you want to reduce encounter diversity and have fewer than 10 species, you can assign duplicate Rate values to some slots -- but note that only the first of any two (or more) adjacent slots with equal Rate values will ever trigger (anything after the first will have a 0% effective rate and never appear).

Scoring

The Score field (labelled "Score" in DSPRE) is one component of the contest judging calculation. In the vanilla game it ranges from 60 (common Pokémon) to 100 (rare Pokémon). The full judge score formula is:

Total Score = Score_Rarity_Factor
+ (Level / Max_Level) x 100
+ (Sum of all 6 IVs / 186) x 100
+ (Current HP / Max HP) x 100

Higher Score (Rarity Factor) values give rarer Pokémon a baseline advantage in the judging results.


Hex Editing

Editing mushi_encount.bin directly (hex editor method)

The encounter data is stored in the file at:

data/mushi/mushi_encount.bin

This file is not inside a NARC. It is a flat binary file that can be opened directly from within the project folder after unpacking the ROM using DSPRE, or by unpacking the ROM file system using other tools.

File Layout

The file contains 4 encounter sets stored sequentially. Each set is 10 entries × 8 bytes = 80 bytes. The full file is therefore 320 bytes (4 × 80) for the vanilla data.

Offset RangeContent
0x000 to 0x04FSet 0 (10 entries)
0x050 to 0x09FSet 1 (10 entries)
0x0A0 to 0x0EFSet 2 (10 entries)
0x0F0 to 0x13FSet 3 (10 entries)

Entry Structure

Each 8-byte entry follows this format:

AA AA BB CC DD EE FF FF

Field Definitions

BytesNameTypeDescription
AA AASpecies IDuint16 (little-endian)The Pokémon species index.
BBMin Leveluint8Minimum encounter level (inclusive).
CCMax Leveluint8Maximum encounter level (inclusive).
DDRate (Raw)uint8The threshold value used in the encounter roll (see The Rate System).
EEScore (Rarity Factor)uint8The rarity/score factor component used in the judge's score calculation.
FF FFPaddinguint16Always 00 00. Not used by the game.

All multi-byte values are little-endian.

Example Entry

Set 0, Slot 0 - Caterpie (Species ID 0x000A), Levels 7-18, Rate 80, Score 60:

0A 00 07 12 50 3C 00 00

Breakdown:

ValueMeaning
0A 00Species 10 (Caterpie)
07Min Level 7
12Max Level 18 (decimal 18 = hex 0x12)
50Rate 80 (decimal 80 = hex 0x50)
3CScore Factor 60 (decimal 60 = hex 0x3C)
00 00Padding

Offset Formula

To locate a specific slot in the file:

offset = (set_id × 10 + slot_index) × 8

For example, Set 2 (set_id = 2), Slot 4 (slot_index = 4):

offset = (2 × 10 + 4) × 8 = 24 × 8 = 192 = 0xC0

See Also