Add documentation for the caught level design flaw (#933)

Co-authored-by: vulcandth <vulcandth@gmail.com>
Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
This commit is contained in:
Colton G. Rushton 2022-07-09 15:39:07 -03:00 committed by GitHub
parent 4ee4bf0351
commit bd27c0d8dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,6 +11,7 @@ These are parts of the code that do not work *incorrectly*, like [bugs and glitc
- [Music IDs $64 and $80 or above have special behavior](#music-ids-64-and-80-or-above-have-special-behavior)
- [`ITEM_C3` and `ITEM_DC` break up the continuous sequence of TM items](#item_c3-and-item_dc-break-up-the-continuous-sequence-of-tm-items)
- [Pokédex entry banks are derived from their species IDs](#pokédex-entry-banks-are-derived-from-their-species-ids)
- [The 6-bit caught level can only record up to level 63](#the-6-bit-caught-level-can-only-record-up-to-level-63)
- [Identical sine wave code and data is repeated five times](#identical-sine-wave-code-and-data-is-repeated-five-times)
- [`GetForestTreeFrame` works, but it's still bad](#getforesttreeframe-works-but-its-still-bad)
@ -618,6 +619,47 @@ And edit [engine/pokegear/radio.asm](https://github.com/pret/pokecrystal/blob/ma
```
## The 6-bit caught level can only record up to level 63
Crystal added the Poké Seer, who tells you your Pokémon's caught data: where it was caught, what time, and at what level. The status screen also displays the gender of its Original Trainer, since Crystal added player genders. This data is packed into two previously-unused bytes in the `box_struct`; from [macros/wram.asm](https://github.com/pret/pokecrystal/blob/master/macros/wram.asm):
```asm
MACRO box_struct
\1Species:: db
...
\1CaughtData::
\1CaughtTime::
\1CaughtLevel:: db
\1CaughtGender::
\1CaughtLocation:: db
\1Level:: db
\1BoxEnd::
ENDM
```
These four pieces of data are packed into two bytes using the bitmasks in [constants/pokemon_data_constants.asm](https://github.com/pret/pokecrystal/blob/master/constants/pokemon_data_constants.asm):
```asm
DEF CAUGHT_TIME_MASK EQU %11000000
DEF CAUGHT_LEVEL_MASK EQU %00111111
DEF CAUGHT_GENDER_MASK EQU %10000000
DEF CAUGHT_LOCATION_MASK EQU %01111111
```
The caught level only uses six bits, so it can only record levels as high as 2^6 1 = 63. If a Pokémon is caught at level 64 or higher, its level overflows into the two bits used for the caught time, before the actual caught time is stored in the same byte with a bitwise `or` operation. For example, a Pokémon caught at level 70 (`%01000110`) in the morning (`%00000000`) would be reported as caught at level 6 (`%000110` in the low six bits) during the day (`%01` in the high two bits).
This limitation is probably why Lugia and Ho-Oh are both encountered at level 60 in Crystal, instead of level 70 in GS.
**Possible fixes:**
- Record any level higher than 63 as level 0, and have the Poké Seer report 0 as "very high".
- Use seven bits for the level (which can store up to level 2^7 1 = 127) and one for the time, simply recording 0 for morning or day and 1 for night.
- Move some data around into unused bits elsewhere in the `box_struct`, such as the high bit of `MON_LEVEL`, or the three high bits of `MON_EXP`.
- Add another byte for more caught data, making the `box_struct` larger; this would affect PC Box storage.
- Free up some other bytes in the `box_struct` (e.g. by [replacing](https://github.com/pret/pokecrystal/wiki/Replace-stat-experience-with-EVs) 2-byte stat experience with 1-byte EVs).
## Identical sine wave code and data is repeated five times
`_Sine` in [engine/math/sine.asm](https://github.com/pret/pokecrystal/blob/master/engine/math/sine.asm):