Skip to content

Grand Underground Generation

SteveCookTU edited this page Aug 11, 2022 · 6 revisions

Grand Underground

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.

Step 0 - Setup

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.

Special Pokemon

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.

Regular Pokemon

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.

All Pokemon Data

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.

MonsDataIndexs (internal name)

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.

Type Rate list

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.

Size 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.

Egg Move Table

A table of available egg moves keyed by species number.

Egg Move Ignore Table

A table of egg moves to exclude keyed by species number.

Rare Try Count

This is the amount of pid rerolls for shiny Pokemon. If Diglett bonus is active, there are two rolls otherwise one.

Secret Base Tiles

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.

Step 1 - Slot Generation

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.

Spawn Count

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.

Rare Pokemon

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.

Slots (Encounter Type 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.

Step 2 - Pokemon Generation

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.