Grand Underground Generation
The Grand Underground generation is what I like to call a mess when it comes to all the things being randomized and the little quirks that happen during the encounter slot generation.
This page will describe the process that is used to generate the Pokemon in the room.
The data is pulled for the specific room ID (internally called randMarkID). This includes a list of special Pokemon, the list of regular pokemon, and the underground specific data for all Pokemon. A list is then created for all available types and sizes along with a list of types and rates that are available based on the types in the types and size list. A list containing sizes is then created.
It reads through the list of special Pokemon and pulls them based on their ID. Each is given a rate for BD and SP. The rates will for each game add up to 1000 for an even distribution. A list of types and sizes is then created which is then used to create a list of types and rates based on the room data.
The game pulls the Pokemon from a defined encounter file for the room ID. This list of all Pokemon are then filtered down based on game version and story flag. It filters all that have version 1 and the version for the specific game (BD = 2, SP = 3). It also filters the story flags <= the player's current story flag.
Nothing special is done pulling this list. One thing to note though is that it contains data for all Pokemon in the game even if they are not able to be found in the underground. The Pokemon not found in the underground are given blank spawn rates but their size and type information is still available.
This is a list of all types and sizes available in the room. An entry is added for the first type of all Pokemon and a second if the Pokemon has another type. It does not store the species of any Pokemon, just the type and size. It also calculates a value based on the type id and size which is used for all future comparisons. This value is calculated as 10 ^ size + type
. This little calculation causes an interesting bug later.
Using the room data and the MonsDataIndexs, a list of all the types and rates are created. Each room is provided a rate for each type but they are not all used. Based on the types in MonsDataIndexs, if it contains the type then the rate is added to the list.
This list is based on the max numbers in the room data. The room data lists smax, mmax, lmax, and llmax. Entries are added to the size list based on the max for each size. Ex. If smax is 3, then 0 is added to the list 3 times. This list is created but NOT actually used.
A table of available egg moves keyed by species number.
A table of egg moves to exclude keyed by species number.
This is the amount of pid rerolls for shiny Pokemon. If Diglett bonus is active, there are two rolls otherwise one.
This is the amount of tiles covered in the secret base. It is recommended to keep this 0 in-game as the behavior of statues is bugged and does not correctly increase rates based on statues.
Every advance has a randomly generated encounter table. These slots are determined by a randomly chosen type and size. The amount of slots is equal to the spawn count of the room.
The spawn count is determined based on the room size (small or large, cave or cavern) as well as the tiles used in the secret base. With no tiles used, it is a 50% chance of having the maximum or minimum spawn count. The comparison is 50 - secret_base_tiles_used <= min_max_rand
.
There is a 50% chance of getting a rare Pokemon. A rare Pokemon is one from the Special Pokemon list, not a shiny Pokemon. If you get a rare Pokemon, 1 is subtracted from the spawn count and Pokemon species is determined before the encounter table.
The game get a random float from 0 to the sum of the type rates listed in the Type Rate List and is used to pick a type in the list. If the rand is greater than or equal to the rate, subtract the rate from the rand. Otherwise, use that type.
A list is then created containing all the TypeAndSize entries in MonsDataIndexs that have that type.
An existing size list is then created. It contains one instance of each size present in the previous list. A random size is chosen from this list. It is then pushed into the slots list with a calculated value of 10^(size) + type
.
For every slot generated, it pulls a list from the MonsDataIndexs that share the same value as the slot. This is where the bug mentioned earlier comes in. Certain types can mismatch with different sizes causing a Pokemon of a different type to be selected. Because of this bug, statues do not work as intended. Each type has a "paired" type and size that is also reachable because of this math.
A filtered list is created from the Regular Pokemon list and the previous list. If the either of the Pokemon's types and the size matches, it is added to the filtered list.
A list of rates is then created based on the filtered list. Each Pokemon is given a rate based on the story flag. If Diglett bonus is active, a rate_up
value is added. This list is then sorted by the rates.
The Pokemon is then selected based on a random float value similar to the type rand and generated used the game's generation functions.
After all regular slots are complete, the rare Pokemon is generated using the species selected before the slot list was created.