summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2019-01-12 18:56:34 -0500
committerRangi <remy.oukaour+rangi42@gmail.com>2019-01-12 18:56:34 -0500
commitc5ddb5a51c658dc20d101eda820fc13c60feba65 (patch)
treeed74bc4ade813e9fe7938a95f0f5ca1324d98134
parentb964f373e9d94641ff6a7f47a33a24a8b705a980 (diff)
Erratic and Fluctuating experience growth rates
-rw-r--r--Erratic-and-Fluctuating-experience-growth-rates.md376
-rw-r--r--Tutorials.md2
2 files changed, 377 insertions, 1 deletions
diff --git a/Erratic-and-Fluctuating-experience-growth-rates.md b/Erratic-and-Fluctuating-experience-growth-rates.md
new file mode 100644
index 0000000..00e7064
--- /dev/null
+++ b/Erratic-and-Fluctuating-experience-growth-rates.md
@@ -0,0 +1,376 @@
+A Pokémon's growth rate determines how much experience it needs to reach a given level. Gen 1 and 2 each used four different growth rates, known as Fast, Slow, Medium Fast, and Medium Slow. (Gen 2 also has leftover formula data for two unused growth rates, "Slightly Fast" and "Slightly Slow".) The Fast rate reaches level 100 with just 800,000 experience, while the Slow rate needs 1,250,000.
+
+Gen 3 introduced two new growth rates: Erratic, which needs a mere 600,000 experience to reach level 100; and Fluctuating, which needs 1,640,000. Neither of these rates is used by many Pokémon even in Gen 3; and beyond Gen 3, only Cranidos → Rampardos, Shieldon → Bastiodon, and Finneon → Lumineon are in the Erratic group, and only Drifloon → Drifblim are in the Fluctuating group.
+
+The original growth rate formulas were all cubic polynomials, but the Erratic and Fluctuating formulas are more complicated piecewise quartic polynomials. It's simplest to do the calculating beforehand and store a lookup table of experience amounts for each level in the ROM (the same approach that Gen 3 took for every growth rate).
+
+
+## Contents
+
+1. [Define growth rate constants](#1-define-growth-rate-constants)
+2. [Define lookup tables of experience amounts](#2-define-lookup-tables-of-experience-amounts)
+3. [Look up experience amounts for a given level](#3-look-up-experience-amounts-for-a-given-level)
+4. [Fix a bank overflow error](#4-fix-a-bank-overflow-error)
+
+
+## 1. Define growth rate constants
+
+Edit [constants/pokemon_data_constants.asm](../blob/master/constants/pokemon_data_constants.asm):
+
+```diff
+ ; wBaseGrowthRate values
+ ; GrowthRates indexes (see data/growth_rates.asm)
+ const_def
+ const GROWTH_MEDIUM_FAST
+ const GROWTH_SLIGHTLY_FAST
+ const GROWTH_SLIGHTLY_SLOW
+ const GROWTH_MEDIUM_SLOW
+ const GROWTH_FAST
+ const GROWTH_SLOW
++ const GROWTH_ERRATIC
++ const GROWTH_FLUCTUATING
+```
+
+
+## 2. Define lookup tables of experience amounts
+
+Edit [data/growth_rates.asm](../blob/master/data/growth_rates.asm):
+
+```diff
++ErraticExperience:
++ dt 0 ; L:1
++ dt 15 ; L:2
++ dt 52 ; L:3
++ dt 122 ; L:4
++ dt 237 ; L:5
++ dt 406 ; L:6
++ dt 637 ; L:7
++ dt 942 ; L:8
++ dt 1326 ; L:9
++ dt 1800 ; L:10
++ dt 2369 ; L:11
++ dt 3041 ; L:12
++ dt 3822 ; L:13
++ dt 4719 ; L:14
++ dt 5737 ; L:15
++ dt 6881 ; L:16
++ dt 8155 ; L:17
++ dt 9564 ; L:18
++ dt 11111 ; L:19
++ dt 12800 ; L:20
++ dt 14632 ; L:21
++ dt 16610 ; L:22
++ dt 18737 ; L:23
++ dt 21012 ; L:24
++ dt 23437 ; L:25
++ dt 26012 ; L:26
++ dt 28737 ; L:27
++ dt 31610 ; L:28
++ dt 34632 ; L:29
++ dt 37800 ; L:30
++ dt 41111 ; L:31
++ dt 44564 ; L:32
++ dt 48155 ; L:33
++ dt 51881 ; L:34
++ dt 55737 ; L:35
++ dt 59719 ; L:36
++ dt 63822 ; L:37
++ dt 68041 ; L:38
++ dt 72369 ; L:39
++ dt 76800 ; L:40
++ dt 81326 ; L:41
++ dt 85942 ; L:42
++ dt 90637 ; L:43
++ dt 95406 ; L:44
++ dt 100237 ; L:45
++ dt 105122 ; L:46
++ dt 110052 ; L:47
++ dt 115015 ; L:48
++ dt 120001 ; L:49
++ dt 125000 ; L:50
++ dt 131324 ; L:51
++ dt 137795 ; L:52
++ dt 144410 ; L:53
++ dt 151165 ; L:54
++ dt 158056 ; L:55
++ dt 165079 ; L:56
++ dt 172229 ; L:57
++ dt 179503 ; L:58
++ dt 186894 ; L:59
++ dt 194400 ; L:60
++ dt 202013 ; L:61
++ dt 209728 ; L:62
++ dt 217540 ; L:63
++ dt 225443 ; L:64
++ dt 233431 ; L:65
++ dt 241496 ; L:66
++ dt 249633 ; L:67
++ dt 257834 ; L:68
++ dt 267406 ; L:69
++ dt 276458 ; L:70
++ dt 286328 ; L:71
++ dt 296358 ; L:72
++ dt 305767 ; L:73
++ dt 316074 ; L:74
++ dt 326531 ; L:75
++ dt 336255 ; L:76
++ dt 346965 ; L:77
++ dt 357812 ; L:78
++ dt 367807 ; L:79
++ dt 378880 ; L:80
++ dt 390077 ; L:81
++ dt 400293 ; L:82
++ dt 411686 ; L:83
++ dt 423190 ; L:84
++ dt 433572 ; L:85
++ dt 445239 ; L:86
++ dt 457001 ; L:87
++ dt 467489 ; L:88
++ dt 479378 ; L:89
++ dt 491346 ; L:90
++ dt 501878 ; L:91
++ dt 513934 ; L:92
++ dt 526049 ; L:93
++ dt 536557 ; L:94
++ dt 548720 ; L:95
++ dt 560922 ; L:96
++ dt 571333 ; L:97
++ dt 583539 ; L:98
++ dt 591882 ; L:99
++ dt 600000 ; L:100
++
++FluctuatingExperience:
++ dt 0 ; L:1
++ dt 4 ; L:2
++ dt 13 ; L:3
++ dt 32 ; L:4
++ dt 65 ; L:5
++ dt 112 ; L:6
++ dt 178 ; L:7
++ dt 276 ; L:8
++ dt 393 ; L:9
++ dt 540 ; L:10
++ dt 745 ; L:11
++ dt 967 ; L:12
++ dt 1230 ; L:13
++ dt 1591 ; L:14
++ dt 1957 ; L:15
++ dt 2457 ; L:16
++ dt 3046 ; L:17
++ dt 3732 ; L:18
++ dt 4526 ; L:19
++ dt 5440 ; L:20
++ dt 6482 ; L:21
++ dt 7666 ; L:22
++ dt 9003 ; L:23
++ dt 10506 ; L:24
++ dt 12187 ; L:25
++ dt 14060 ; L:26
++ dt 16140 ; L:27
++ dt 18439 ; L:28
++ dt 20974 ; L:29
++ dt 23760 ; L:30
++ dt 26811 ; L:31
++ dt 30146 ; L:32
++ dt 33780 ; L:33
++ dt 37731 ; L:34
++ dt 42017 ; L:35
++ dt 46656 ; L:36
++ dt 50653 ; L:37
++ dt 55969 ; L:38
++ dt 60505 ; L:39
++ dt 66560 ; L:40
++ dt 71677 ; L:41
++ dt 78533 ; L:42
++ dt 84277 ; L:43
++ dt 91998 ; L:44
++ dt 98415 ; L:45
++ dt 107069 ; L:46
++ dt 114205 ; L:47
++ dt 123863 ; L:48
++ dt 131766 ; L:49
++ dt 142500 ; L:50
++ dt 151222 ; L:51
++ dt 163105 ; L:52
++ dt 172697 ; L:53
++ dt 185807 ; L:54
++ dt 196322 ; L:55
++ dt 210739 ; L:56
++ dt 222231 ; L:57
++ dt 238036 ; L:58
++ dt 250562 ; L:59
++ dt 267840 ; L:60
++ dt 281456 ; L:61
++ dt 300293 ; L:62
++ dt 315059 ; L:63
++ dt 335544 ; L:64
++ dt 351520 ; L:65
++ dt 373744 ; L:66
++ dt 390991 ; L:67
++ dt 415050 ; L:68
++ dt 433631 ; L:69
++ dt 459620 ; L:70
++ dt 479600 ; L:71
++ dt 507617 ; L:72
++ dt 529063 ; L:73
++ dt 559209 ; L:74
++ dt 582187 ; L:75
++ dt 614566 ; L:76
++ dt 639146 ; L:77
++ dt 673863 ; L:78
++ dt 700115 ; L:79
++ dt 737280 ; L:80
++ dt 765275 ; L:81
++ dt 804997 ; L:82
++ dt 834809 ; L:83
++ dt 877201 ; L:84
++ dt 908905 ; L:85
++ dt 954084 ; L:86
++ dt 987754 ; L:87
++ dt 1035837 ; L:88
++ dt 1071552 ; L:89
++ dt 1122660 ; L:90
++ dt 1160499 ; L:91
++ dt 1214753 ; L:92
++ dt 1254796 ; L:93
++ dt 1312322 ; L:94
++ dt 1354652 ; L:95
++ dt 1415577 ; L:96
++ dt 1460276 ; L:97
++ dt 1524731 ; L:98
++ dt 1571884 ; L:99
++ dt 1640000 ; L:100
+```
+
+The values in these tables were taken from [src/data/pokemon/experience_tables.h](https://github.com/pret/pokeruby/blob/master/src/data/pokemon/experience_tables.h) in the [pokeruby](https://github.com/pret/pokeruby) disassembly.
+
+
+## 3. Look up experience amounts for a given level
+
+Edit [engine/pokemon/experience.asm](../blob/master/engine/pokemon/experience.asm):
+
+```diff
+ CalcExpAtLevel:
+ ; (a/b)*n**3 + c*n**2 + d*n - e
+ ld a, [wBaseGrowthRate]
++ cp GROWTH_ERRATIC
++ jp z, .erratic
++ cp GROWTH_FLUCTUATING
++ jp z, .fluctuating
+ add a
+ add a
+ ld c, a
+ ld b, 0
+ ld hl, GrowthRates
+ add hl, bc
+ ; Cube the level
+ call .LevelSquared
+ ld a, d
+ ldh [hMultiplier], a
+ call Multiply
+
+ ...
+
+ .LevelSquared:
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ldh [hMultiplier], a
+ jp Multiply
++
++.erratic:
++ ld hl, ErraticExperience
++ jr .lookup_table
++
++.fluctuating:
++ ld hl, FluctuatingExperience
++.lookup_table
++ ld c, d
++ ld b, 0
++ dec c
++ add hl, bc
++ add hl, bc
++ add hl, bc
++ xor a
++ ld [hProduct + 0], a
++ ld a, [hli]
++ ld [hProduct + 1], a
++ ld a, [hli]
++ ld [hProduct + 2], a
++ ld a, [hli]
++ ld [hProduct + 3], a
++ ret
+
+ INCLUDE "data/growth_rates.asm"
+```
+
+
+## 4. Fix a bank overflow error
+
+We're done implementing the new growth rates, but `make` won't compile the ROM:
+
+```
+Section 'bank14' is too big (max size = 0x4000 bytes).
+```
+
+It turns out that the lookup tables overflowed their ROM bank, so we need to move some of content from `bank14` to a different bank, or delete some. In fact, there is some unused content in `bank14` that can be deleted to free up space.
+
+Edit [main.asm](../blob/master/main.asm):
+
+```diff
+ SECTION "bank14", ROMX
+
+ INCLUDE "engine/pokemon/party_menu.asm"
+ INCLUDE "engine/events/poisonstep.asm"
+ INCLUDE "engine/events/sweet_scent.asm"
+ INCLUDE "engine/events/squirtbottle.asm"
+ INCLUDE "engine/events/card_key.asm"
+ INCLUDE "engine/events/basement_key.asm"
+ INCLUDE "engine/events/sacred_ash.asm"
+ INCLUDE "engine/pokemon/tempmon.asm"
+ INCLUDE "engine/pokemon/types.asm"
+-INCLUDE "engine/battle/unreferenced_getgen1trainerclassname.asm"
+ INCLUDE "engine/pokemon/mon_stats.asm"
+ INCLUDE "engine/link/init_list.asm"
+ INCLUDE "engine/pokemon/experience.asm"
+ INCLUDE "engine/pokemon/switchpartymons.asm"
+ INCLUDE "engine/gfx/load_pics.asm"
+ INCLUDE "engine/pokemon/move_mon_wo_mail.asm"
+ INCLUDE "data/pokemon/base_stats.asm"
+ INCLUDE "data/pokemon/names.asm"
+-INCLUDE "data/pokemon/unused_pic_banks.asm"
+-
+-UnknownEggPic::
+-; Another egg pic. This is shifted up a few pixels.
+-INCBIN "gfx/unknown/unknown_egg.2bpp.lz"
+```
+
+Now edit [home/mon_data.asm](../blob/master/home/mon_data.asm) to remove the pointless use of `UnknownEggPic`:
+
+```diff
+ .egg
+-; ????
+- ld de, UnknownEggPic
+-
+ ; Sprite dimensions
+ ld b, $55 ; 5x5
+ ld hl, wBasePicSize
+ ld [hl], b
+-
+-; ????
+- ld hl, wBasePadding
+- ld [hl], e
+- inc hl
+- ld [hl], d
+- inc hl
+- ld [hl], e
+- inc hl
+- ld [hl], d
+- jr .end
+```
+
+And finally delete [engine/battle/unreferenced_getgen1trainerclassname.asm](../blob/master/engine/battle/unreferenced_getgen1trainerclassname.asm), [data/pokemon/unused_pic_banks.asm](../blob/master/data/pokemon/unused_pic_banks.asm), [gfx/unknown/unknown_egg.png](../blob/master/gfx/unknown/unknown_egg.png), and [gfx/unknown/unknown_egg.2bpp.lz.a5b6cbfa](../blob/master/gfx/unknown/unknown_egg.2bpp.lz.a5b6cbfa).
+
+Now you'll be able to use the constants `GROWTH_ERRATIC` and `GROWTH_FLUCTUATING` when defining new Pokémon in [data/pokemon/base_stats](../tree/master/data/pokemon/base_stats/).
diff --git a/Tutorials.md b/Tutorials.md
index 2fbac27..e5e9c2a 100644
--- a/Tutorials.md
+++ b/Tutorials.md
@@ -65,6 +65,7 @@ Tutorials may use diff syntax to show edits:
- [Physical/Special split](Physical-Special-split)
- [Replace stat experience with EVs](Replace-stat-experience-with-EVs)
- [Don't gain experience at level 100](Don't-gain-experience-at-level-100)
+- [Erratic and Fluctuating experience growth rates](Erratic-and-Fluctuating-experience-growth-rates)
- [Infinitely reusable TMs](Infinitely-reusable-TMs)
- [Automatically reuse Repel](Automatically-reuse-Repel)
- [Evolution moves](Evolution-moves)
@@ -89,7 +90,6 @@ Tutorials may use diff syntax to show edits:
- More daily and weekly events
- Third trainer card page for Kanto badges
- Fourth stats page for caught data
-- Gen 3+ experience growth rates ([Fluctuating and Erratic](https://bulbapedia.bulbagarden.net/wiki/Experience))
- Colored party menu icons (overworld or battle sprite colors)
- Option to show shiny colors in Pokédex
- Automatic rain/sun/sandstorm on certain maps