From caf9a2aab7fda641d10034cfb18b18959d949afd Mon Sep 17 00:00:00 2001 From: Connor Date: Tue, 25 Apr 2017 11:44:45 -0700 Subject: [PATCH 1/3] --- rng.md | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 rng.md diff --git a/rng.md b/rng.md new file mode 100644 index 0000000..71c3692 --- /dev/null +++ b/rng.md @@ -0,0 +1,119 @@ +# info dump on the RNG in OoT and MM + +## the function itself + +the random number generator in both games is an LCG: +https://en.wikipedia.org/wiki/Linear_congruential_generator +specifically, it uses the constants from Numerical Recipes in C. + +```c +/* the C code looks something like this: */ +static uint32_t rng_value = 1; +uint32_t prng() { + /* note: intentional unsigned overflow. */ + rng_value = rng_value * 1664525 + 1013904223; + return rng_value; + /* note: in the game, there's some code to reinterpret the value + as a floating point number, which I've omitted here. */ +} +``` + +if you're interested, you can find the function(s) in any version by searching +for F35F in RAM. you should see a 660D nearby, usually a bit before. +you can find the rng_value variable +by looking at the disassembly of the RNG function. +note that there are a few different variations of the function +that are not commonly invoked. you can find these the same way. + +here are some known addresses: + +game, version | RNG value | RNG function | variants +------------- | --------- | ------------ | -------- +OoT 1.0 | 80105440 | 800CDC90 | ? +OoT 1.2 | 80105A80 | 800CE4D0 | ? +MM (J) 1.1 | 8009E890 | 8008797C | 80087940 +MM (U): | 80097530 | 80086FDC | ? + +## the quirks + +when a new scene is loaded, +the RNG value is set directly to the CPU's cycle count. +that means, depending on all the code that has been run +up to that point, the RNG value is set to a +pseudo-unpredictable value when you enter a new area. + +to clarify what a "new scene" being loaded is: + +* loading the title screen +* loading a save file +* entering a new area (TODO: do rooms within a scene count?) +* **not** the N64 logo being shown +* **not** the file select screen + +### other invocations + +creating a new file will invoke the RNG +to determine the Bomber's Code, etc. +this does not apply to OoT. + +although the GameCube versions don't have an N64 logo, +they still do similar initializations before the title screen is shown. + +i might be missing some details here, as i haven't searched exhaustively. +leave a comment or tweet at @antiformant if you know anything. + +### emulators + +as far as i know, the cycle counter in emulators +(including Virtual Console, excluding CEN64) +is very roughly approximated. +it's not a critical component to emulating most games, +so emulators can skimp on it to achieve better performance. + +this means RNG should be fairly consistent, given identical inputs. +*this does not mean RNG will be consistent across emulators.* +the plugins you use might affect this as well. + +## exploiting the RNG + +### in Ocarina of Time + +because the title screen sequence starts on Hyrule Field +with a ton of actors loaded, +the RNG value is updated many times each frame. + +as far as i know, you'd have to be frame perfect to reach the file select screen +with a consistent RNG, but i haven't done a lot of testing. +maybe there's a part of the title sequence +with wider gaps between RNG invocations, +giving you a wider window to enter the inputs to reach the file select screen. + +this might not be exploitable anyway due to +of the cycle-reset that occurs when loading scenes, as described earlier. + +### in Majora's Mask + +the first title screen in this game is very simple. +only a handful of actors are loaded and executing. +as a result, the RNG is only invoked +something like every 75 frames *on average.* + +this is a big window to reach the file select screen. +*in theory,* you should be able mash A and Start to reach the +file select to create a file, and that file will have the same +Bomber's code, lottery codes, and Spider House mask order. + +remember that "the same" is specific to each emulator, +as described earlier. + +### in practice + +this needs testing. + +i can somewhat consistently reach the file select screen +with the same RNG value in Project64 2.2 and Bizhawk 1.12.1. + +Virtual Console and N64 have not been tested. + +this might be useful for the new MM 100% ruleset +if it's found to be consistent, but don't hold your breath. From 8093266ec7dd6dd40e0a55265450ec7d820becf2 Mon Sep 17 00:00:00 2001 From: Connor Date: Tue, 25 Apr 2017 11:52:21 -0700 Subject: [PATCH 2/3] --- rng.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rng.md b/rng.md index 71c3692..9b2f42d 100644 --- a/rng.md +++ b/rng.md @@ -1,5 +1,10 @@ # info dump on the RNG in OoT and MM +if you find any discrepancies, please +leave a comment or tweet at [@antiformant][twitter]. + +[twitter]: https://twitter.com/antiformant + ## the function itself the random number generator in both games is an LCG: @@ -23,7 +28,7 @@ for F35F in RAM. you should see a 660D nearby, usually a bit before. you can find the rng_value variable by looking at the disassembly of the RNG function. note that there are a few different variations of the function -that are not commonly invoked. you can find these the same way. +that are not commonly invoked; you can find these the same way. here are some known addresses: @@ -54,14 +59,11 @@ to clarify what a "new scene" being loaded is: creating a new file will invoke the RNG to determine the Bomber's Code, etc. -this does not apply to OoT. +obviously, this does not apply to OoT. although the GameCube versions don't have an N64 logo, they still do similar initializations before the title screen is shown. -i might be missing some details here, as i haven't searched exhaustively. -leave a comment or tweet at @antiformant if you know anything. - ### emulators as far as i know, the cycle counter in emulators From 44a3945bf269cb0504a879f8bb8668747e89b88e Mon Sep 17 00:00:00 2001 From: Connor Date: Tue, 25 Apr 2017 11:57:05 -0700 Subject: [PATCH 3/3] --- rng.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rng.md b/rng.md index 9b2f42d..dc352be 100644 --- a/rng.md +++ b/rng.md @@ -91,7 +91,7 @@ with wider gaps between RNG invocations, giving you a wider window to enter the inputs to reach the file select screen. this might not be exploitable anyway due to -of the cycle-reset that occurs when loading scenes, as described earlier. +the reset that occurs when loading scenes, as described earlier. ### in Majora's Mask