Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Generation III Glitch Discussion

Alternative PIDs for Glitzer Popping? - Page 1

Alternative PIDs for Glitzer Popping?

Posted by: papajefe
Date: 2020-05-01 16:16:14
Hey there,

I'm investigating some fun combinations of RNG Abuse and Glitzer Popping with Eggs.

So I know that the Horsea and Seedot in game trades have PIDs which are particularly compatible with corruption, allowing their HP\ATK EVs to act as the index for their species in the corrupted egg.

However, when doing this you only get Pokemon with terrible IV spreads and natures.

In theory I know that other PIDs could take the place of these Pokemon, and I know how to RNG specific Gen 3 PIDs with some effort.

So, will any Pokemon with a PID of 0x000000XX work? Or is there some sort of XOR I need to do on the PID to determine its viability?

Re: Alternative PIDs for Glitzer Popping?

Posted by: merrp
Date: 2020-05-03 12:18:47
TL;DR: You need to take the PID mod 24 and use that to figure out the substruct ordering, then figure out what that ordering is after corruption.

I wrote some short code to do this with comments, just scroll to the bottom (and hit RUN):

https://pyfiddle.io/fiddle/47c395f4-4d50-4906-a573-2e7a7a4b2a97/?i=true

I'll also include the code of that file in case the link goes dead:
# Pokemon Emerald: PIDs for Glitzer Popping
# See https://bulbapedia.bulbagarden.net/wiki/Glitzer_Popping
# For more info in general see https://pastebin.com/YaZaMQ4G

# Represent each substruct by an integer
# For a more detailed list of what each contains see https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_data_substructures_in_Generation_III
substructs = {'growth': 0, 'attacks': 1, 'evs/condition': 2, 'miscellaneous': 3}
r_substructs = {v: k for k, v in substructs.items()}  # The reverse mapping, from integers to names

# There are 24 possible substructure orderings, calculated by taking the PID mod 24
# For ordering i, substruct j appears in *position* orders[i][j]
# For example, ordering 22 has the substructs in order E M G A
# (Interestingly, if you just take the i-th lexicographic permutations of [0, 1, 2, 3],
# you can regenerate this table yourself)
orders = {0: [0, 1, 2, 3], 1: [0, 1, 3, 2], 2: [0, 2, 1, 3], 3: [0, 3, 1, 2],
          4: [0, 2, 3, 1], 5: [0, 3, 2, 1], 6: [1, 0, 2, 3], 7: [1, 0, 3, 2],
          8: [2, 0, 1, 3], 9: [3, 0, 1, 2], 10: [2, 0, 3, 1], 11: [3, 0, 2, 1],
          12: [1, 2, 0, 3], 13: [1, 3, 0, 2], 14: [2, 1, 0, 3], 15: [3, 1, 0, 2],
          16: [2, 3, 0, 1], 17: [3, 2, 0, 1], 18: [1, 2, 3, 0], 19: [1, 3, 2, 0],
          20: [2, 1, 3, 0], 21: [3, 1, 2, 0], 22: [2, 3, 1, 0], 23: [3, 2, 1, 0]}


# Corrupt a PID by ORing it with 0x40000000 (via Glitzer Popping)
# Technically with certain pokemon in the PC, corruptions that *XOR* with this value can happen.
# But if the PC area before the pokemon you want to corrupt is empty, only a logical OR can happen
# I'm pretty sure this is also the only corruption that can happen when using corruption initiators too?
# But anyway this is probably the corruption you want
def corrupt(pid):
    return pid | 0x40000000
   

# A PID is seedot(DOTS)-like if it swaps EVs into growth after corruption
def seedot_like(pid):
    order = pid % 24
    evs_before = orders[order][2]  # Position of EVs before corruption
    corrupted = corrupt(pid)
    c_order = corrupted % 24
    growth_after = orders[c_order][0]  # Position of growth after corruption
    return evs_before == growth_after  # Ensure they are the same


# A PID is Plusle(PLUSES)-like if it swaps EVs into attacks after corruption
# This lets you acquire any move
def plusle_like(pid):
    order = pid % 24
    evs_before = orders[order][2]  # Position of EVs before corruption
    corrupted = corrupt(pid)
    c_order = corrupted % 24
    attacks_after = orders[c_order][1]
    return evs_before == attacks_after


# Show a PID's substruct order
def show_order(pid):
    order = orders[pid % 24]
    structs = [None]*4
    for i in range(4):  # For each substruct number
        position = order[i]  # Get its position
        structs[position] = r_substructs[i][:1].upper()  # And set that position to the first letter
    return f'0x{pid:08X} (' + ' '.join(structs) + ')'
   

# Tells you what kind of swapping corrupting a PID will do
def corruption_type(pid):
    corrupted = corrupt(pid)
    if seedot_like(pid):
        extra = '(like DOTS)'
    elif plusle_like(pid):
        extra = '(like PLUSES)'
    else:
        extra = ''
    return f'{show_order(pid)} -> {show_order(corrupted)} {extra}'
   
if __name__ == '__main__':
    # PIDs to check
    dots_pid = 0x00000084
    pluses_pid = 0x0000006F
    your_pid = 0  # whatever you want really
    pids = [dots_pid, pluses_pid, your_pid]
    # Setup and display table
    print(f'{"PID":10} {"Before":12} {"Corrupted":10} After')
    for pid in pids:
    print(corruption_type(pid))


You might also be interested in: https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_data_substructures_in_Generation_III

Re: Alternative PIDs for Glitzer Popping?

Posted by: papajefe
Date: 2020-05-03 22:09:45
Ironically enough, I figured this stuff out last night on my own once I watched a Werster video where he mentioned the substructures. This would have been 10x easier if I had this python script!

Everything went swimmingly after some Trial and Error, and I wound up making a Google Sheet to check PIDs from Colo\XD, and the nature they've have afterward. I RNG'd a Sneasel (for easy Beat Up access) in Colosseum with a specific PID and IV spread.

I identified which substructure configuration would preserve IVs, but swap Attacks and Growth, thus yielding the Pokemon I wanted– Celebi.

Wound up with a Bold Celebi 31-12-30-31-31-30, and then RNG'd a specfic TID\SID on Ruby to hatch the glitch egg. The result? A competitively perfect shiny Celebi in Gen 3, without any cheating devices. Just Colosseum and Ruby RNG abuse.