| GuyPerfect Catgirl Level: 68 Posts: 883/1096 EXP: 2663632 For next: 65168 Since: 07-23-07 Since last post: 1.6 years Last activity: 211 days |
|
||
|
Oy caramba. Every time I try to post this thread I end up writing an article. Well, not this time! Instead, I have a proof-of-concept ready! It's not user-friendly enough to be ready for prime time, but it gets the job done and it's a great start for planning some better software. Like I mentioned in another thread, I'm working on a technical experiment for migrating Pokémon from Generation 2 to Generation 3. There's some big philosophical discussion that can go on regarding this subject, but I'm gonna skip all of that. The whys aren't important. It's the whats I'm here to share with you today. ![]() I've done extensive work reverse-engineering the save data for Pokémon games. You can see most of my findings here, here and here. __________ Stat Growth This is the big 600-pound Hippowdon in the room. Generation 2 uses the old stat exp. mechanic, while Generation 3 uses the new(er) effort point mechanic. Converting between them is not graceful: you can achieve maximum growth for all stats under the old system, but not the new system. Migration therefore may necessitate a reduction in stats, which I'm sure some people would get all frothy-mouthed over. Legend has it this is the reason Nintendo opted to remake the generation 1 and 2 games rather than provide an official migration solution. Either way, it's a problem that needs to be solved. I'm working on the premise that stat exp./effort points are a reflection of... well, experience and effort. They are not a means to an end: that is, they're not a stepping stone to the final stat value. They indicate a Pokémon's growth in their stats, but not necessarily the final numerical stats themselves. To that end, I established a policy that makes migration easy: growth by stat should remain relative to all the other stats. Due to how stat exp. works (the base stats of the defeated Pokémon are added to the stat exp. on defeat), it's impossible to train up just one stat like you can do with EVs. This affords a simple migration technique: simply scale down all of the stats until they fit in the required range. This is a four-step process: I'm open to suggestions for this. One thing I don't want to do is allow the player to pick and choose which stats they want max'd and which ones they don't. That's what Super Training is for. This should be automated and treat all stats fairly. __________ Randomness Generation 2 has 16 bits of randomness per Pokémon (4 for each of 4 IVs), while Generation 3 has 62 (5 for each of 6 IVs, plus 32 "personality" bits). This means additional bits need to come from somewhere. The OT ID No. is also twice as large in Generation 3, which presents an interesting opportunity... I'm constructing a 32-bit OT ID by using the old OT ID as the lower 16 bits (since that will display the same 5-digit number in the Summary screen in-game), and the old IVs as the upper 16 bits. The resulting 32-bit value I then use as the seed for a pseudorandom number generator that is used to generate other random things, the personality value among them. Doing it this way guarantees that the data from a Generation 2 Pokémon will always result in the same Generation 3 Pokémon. The algorithm I decided to use, due to its appropriate context, is the one used to encrypt the Pokémon save data records in Generations 4 and 5. It looks something like this:
Output from this algorithm, after seeding with the 32-bit OT ID, is used for the initial personality value as well as selection for appropriate values of auxiliary attributes. __________ Gender In Generation 2, the Pokémon's gender is determined by the Attack IV. In Generation 3, the lowest byte of the personality value is used. Both are checking against the same value for the Pokémon's species, which represents the ratio of males to females for the species. For Generation 2, the check is whether the Attack IV is greater than the gender threshold. If it is, the Pokémon is male. For Generation 3, the check is whether the lowest personality byte is greater than or equal to the gender threshold instead. The thresholds are pretty much the same: the 4-bit value for Generation 2 is the upper 4 bits of the 8-bit Generation 3 value, and the lower 4 bits are all 1s. Using the random bits generated for the initial personality value, the Pokémon's random gender can be checked. If it happens to be the wrong gender, that byte can be corrected by simply subtracting it from 255. __________ Unown's Letter In Generation 2, Unown's letter is determined by concatenating the center 2 bits of the IVs, in the order of (high) Attack, Defense, Speed, Special (low). That 8-bit value is divided by 10 to yield a result from 0 to 25, which corresponds with the letter. In Generation 3, the lowest 2 bits of each of the 4 bytes of the personality value are used instead, retaining their order (the highest byte contains the highest 2 bits, etc.). This value is then divided by 28, and the remainder is the letter. 26 is ?, and 27 is !. Randomness should come into play here. There are 9 values that can express any given letter, where A, B, C and D can be expressed with 10 values. Ideally, a random value across all valid values should be selected. That's the easy part. The harder part is accounting for shininess. Shininess is explained below, but basically we need to account for this: bits 2-3 and 6-7 of the generated letter value, when XOR'd together, can produce any of the 4 combinations of 2 bits. This combination needs to be the same as the XOR result of bits 8-9 and 24-25 in the OT ID or the Pokémon will not be shiny. As luck would have it, for all 28 permutations of Unown, there's at least one valid value for each of the 4 combinations of two bits. All Unown can be shiny no matter what the OT ID is. So when an Unown needs to be shiny, its letter value is simply selected from a list of all the valid values that match both the letter and are shiny. The algorithm I wrote for this suits all permutations of Unown, but in Generation 2, the only Unown that can be shiny are letters I and V (coincidentally enough, considering shininess comes from the IVs in Generation 2). __________ Hidden Power Hidden Power's type and power both come from the IVs in Generations 2 and 3. Type is a 4-bit value, and both generations use the same list. Power can range from 30 to 70. In Generation 2, type is a 4-bit value using the lower 2 bits of the Attack IV as its upper 2 bits, and the lower 2 bits of the Defense IV as its lower 2 bits. In Generation 3, type uses a 6-bit value using the least-significant bit of each IV, in the order of (high) Special Defense, Special Attack, Speed, Defense, Attack, HP (low). This value is then scaled to the range of 0...15 with the expression "value * 15 / 63". For this reason, the maximum value of 15 can only come from an initial value of 63, making Dark the rarest type for Hidden Power. In Generation 2, power comes from the most significant bits of the IVs, in the order of (high) Attack, Defense, Speed, Special (low). This value is multiplied by 5, then added with 3 (if the Special IV is greater than 2), or the Special IV itself. The result is then divided by 2, which produces a number from 0 to 39. 31 is added to this to yield Hidden Power's power. In Generation 3, the same algorithm used to determine Hidden Power's type is used, but it uses the second least-significant bit from the IVs (same order). It's scaled to 40 (value * 40 / 63), then has 30 added to it. Likewise with the type, only IV bits of all 1s can produce the maximum value of 70. Retaining Hidden Power's attributes in Generation 3 necessitates modification of the IVs; there's no way around that. Since stat growth consistency between generations is all mangled up to begin with, IV accuracy isn't of utmost importance. What I ended up doing was building a list of valid matching values and selecting one at random, just like I did for Unown's letter. __________ Shininess One in every 8,192 Pokémon is shiny. It means nothing, but people still bend over backwards for it. In Generation 2, the 16-bit IVs value is AND'd with 0x2FFF, and if the result is 0x2AAA, the Pokémon is shiny. In Generation 3, the personality value is XOR'd with the OT ID value, and both halves of the result are XOR'd with each other. If the 16-bit result is less than 8 (meaning, bits 4-15 are all zeroes), the Pokémon is shiny. Checking whether a Generation 3 Pokémon is shiny is easy: just XOR down to that 16-bit mask value and see if it's less than 8. If it's not, you can easily use that mask value to "correct" the personality value and make it shiny. Here's what you do: The only bits in the upper half of the personality value that shouldn't be corrupted are bits 24 and 25, which are used for the letter if the Pokémon is Unown. However, since those bits were selected such that the result after the XOR would be zeroes, using this "correction" can't possibly modify those bits because the corresponding bits in the mask have to be zeroes by this point. In the event the personality value just so happened to be shiny when it wasn't supposed to be, you can "correct" that was well, resulting in "de-shinification", by XORing the upper half of the personality value with 0xFCF8. This time, it's a mask value that won't touch the Unown letter bits. __________ Ability, Egg The Ability bit (in the IVs field) is initialized as the least-significant bit of the final Personality value. If the species can only have one Ability (like our friend Unown), the bit must be cleared in the IVs field. If the Pokémon is in an egg (denoted by a "sprite ID" of 0xFD in Generation 2), the Egg bit in the IVs field should be set, and the nickname should be changed to 0x60 0x6F 0x8B (タマゴ). __________ Held Item If the Pokémon is holding an item, it may be able to be migrated as well. Most items in Generation 2 also exist in Generation 3. Some items don't exist per sé, but do have a functional equivalent. Other items have no equivalent at all. Incidentally, all TMs that teach a move in Generation 2 that can be taught by TM in Generation 3 share the same numbers as the Generation 3 TMs. Handy! The following items translate into the same item:
Amulet Coin, Antidote, Awakening, Berry Juice, Big Mushroom, Big Pearl, Black Belt, Black Glasses, Bright Powder, Burn Heal, Calcium, Carbos, Charcoal, Cleanse Tag, Dire Hit, Dragon Fang, Dragon Scale, Elixir, Energy Powder, Energy Root, Escape Rope, Ether, Everstone, Exp. Share, Fire Stone, Focus Band, Fresh Water, Full Heal, Full Restore, Great Ball, Guard Spec., Hard Stone, Heal Powder, HP Up, Hyper Potion, Ice Heal, Iron, King's Rock, Leaf Stone, Leftovers, Lemonade, Light Ball, Lucky Egg, Lucky Punch, Magnet, Master Ball, Max Elixir, Max Ether, Max Potion, Max Repel, Max Revive, Metal Coat, Metal Powder, Miracle Seed, Moomoo Milk, Moon Stone, Mystic Water, Never-Melt Ice, Nugget, Paralyze Heal, Pearl, Poison Barb, Poké Ball, Poké Doll, Potion, PP Up, Protein, Quick Claw, Rare Candy, Repel, Revival Herb, Revive, Sacred Ash, Scope Lens, Sharp Beak, Silver Powder, Smoke Ball, Soda Pop, Soft Sand, Spell Tag, Star Piece, Stardust, Stick, Sun Stone, Super Potion, Super Repel, Thick Club, Thunder Stone, Tiny Mushroom, TM05 Roar, TM06 Toxic, TM10 Hidden Power, TM11 Sunny Day, TM14 Blizzard, TM15 Hyper Beam, TM17 Protect, TM18 Rain Dance, TM19 Giga Drain, TM21 Frustration, TM22 Solar Beam, TM23 Iron Tail, TM25 Thunder, TM26 Earthquake, TM27 Return, TM28 Dig, TM29 Psychic, TM20 Shadow Ball, TM32 Double Team, TM36 Sludge Bomb, TM37 Sandstorm, TM38 Fire Blast, TM44 Rest, TM45 Attract, TM46 Thief, TM47 Steel Wing, Twisted Spoon, Ultra Ball, Up-Grade, Water Stone, X Accuracy, X Attack, X Defend, X Special, X Speed
The following items translate into identical items with different names:
Berry → Oran Berry Bitter Berry → Persim Berry Burnt Berry → Aspear Berry Gold Berry → Sitrus Berry Ice Berry → Rawst Berry Mint Berry → Chesto Berry Miracle Berry → Lum Berry Pink Bow → Silk Scarf PRZ Cure Berry → Cheri Berry PSN Cure Berry → Pecha Berry The following items translate into different items with similar effects:
Mystery Berry (+5 PP) → Leppa Berry (+10 PP) Polkadot Bow (+12.5% Normal Damage) → Silk Scarf (+10% Normal Damage) The following items have no analog in Generation 3 and must be returned to the bag or PC (or deleted):
Berserk Gene, Black Apricorn, Blue Apricorn, Blue Sky Mail, Brick Piece, Eon Mail, Fast Ball, Flower Mail, Friend Ball, Gold Leaf, Gorgeous Box, Green Apricorn, Heavy Ball, Level Ball, Light Blue Mail, Love Ball, Lovely Mail, Lure Ball, Mirage Mail, Moon Ball, Morph Mail, Music Mail, Normal Box, Park Ball, Pink Apricorn, Portrait Mail, Rage Candy Bar, Red Apricorn, Silver Leaf, Slowpoke Tail, Surf Mail, TM01 Dynamic Punch, TM02 Headbutt, TM03 Curse, TM04 Rollout, TM07 Zap Cannon, TM08 Rock Smash, TM09 Psych Up, TM12 Sweet Scent, TM13 Snore, TM16 Icy Wind, TM20 Endure, TM24 Dragon Breath, TM31 Mud Slap, TM33 Ice Punch, TM34 Swagger, TM35 Sleep Talk, TM39 Swift, TM40 Defense Curl, TM41 Thunder Punch, TM42 Dream Eater, TM43 Detect, TM48 Fire Punch, TM49 Fury Cutter, TM50 Nightmare, White Apricorn, Yellow Apricorn
The following items cannot be held by a Pokémon:
Basement Key, Bicycle, Blue Card, Card Key, Clear Bell, Coin Case, Egg Ticket, Good Rod, GS Ball, HM01 Cut, HM02 Fly, HM03 Surf, HM04 Strength, HM05 Flash, HM06 Whirlpool, HM07 Waterfall, Item Finder, Lost Item, Machine Part, Mystery Egg, Old Rod, Pass, Rainbow Wing, Red Scale, S.S. Ticket, Secret Potion, Silver Wing, Squirt Bottle, Super Rod
A handy conversion chart is as follows: -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -FValue 0 represents no held item in both generations Values marked "++" are items that can be held, but not migrated to Generation 3 Values marked "--" either cannot be held or are not valid items __________ Other Some other fields of interest: __________ Practical Example After it was all said and done, I successfully migrated my original Ariados from Gold to FireRed using a custom utility. This was the play-through from when I first picked Ariados as my favorite. ![]() The original: ![]() The migrated: ![]() During the testing phase, I did alter some attributes like gender, shininess and Unown's letter to make sure everything was working right. And it is. I haven't verified the Hidden Power stuff yet, but egads this is satisfying! Take note of how the stats wound up. Skitters's total Stat Exp. exceeded 510 effort points' worth of growth, so things had to be scaled back a bit. The reason Special Attack and Special Defense are different is because of its Impish nature, which boosts Defense and nerfs Special Attack. Now I'm really itching for an 8-bit cartridge interface on GBA so I can make this happen on the hardware.
|




.

