"Scramble" here means filling in random values in the RNG addresses of the game in order to test different sorts of possible outcomes for an RNG-based event.
--AUTHOR: VelpaChallenger, you can find me with that username in both YouTube and Discord (open to DMs for
--any questions, concerns, etc., in YouTube you can also find other of my social media if you don't use
--Discord for example.)
--[[ HOW TO USE
Whenever you load a savestate, if the movie state (it's supposed to be used with a movie) is read+write, then
the memory address in write_random_values function will be filled with a random value, helping you play the
same section with different RNG values. This was designed to practice sections for a No Damage Run, however it
could potentially also be used for a TAS to see different outcomes depending on the value of the RNG. Also,
for Dinosaur level, 0xC210 works as a 'sort of' RNG: this means that the value is set depending on given
circumstances, like giving a hit or receiving a hit, so it's not totally random in that sense. However, it's
then used to change behaviors in varied bosses like Smithers+Burns or Homer+Moe, and it ends up producing
RNG-like behavior, so that's why it's also included here. Scrambling that address can also result in very
different outcomes.
Now, why the read-only option, you might ask? Well, if the movie is read-only, the idea is that you can replay
the last events when the movie was still read+write. This shouldn't scramble the RNG again or the movie would
end out of sync. That's why I make the distinction here.
]]
function write_random_values(random_values_table)
mainmemory.write_u16_be(0xC676, random_values_table[0]) --0xC676 for most of the game, 0xC210 for Dinosaur
end
function create_random_values_table(random_values_table)
random_values_table[0] = math.random(0, 0xFFFF)
return random_values_table
end
function loadingState(index)
if not random_values_table then
random_values_table = {} --Initialize global variable so that state can persist (and therefore be accessed) after each function call. This is important for reading the random values generated in the last call in case the movie is now in read-only state.
end
local is_read_only = movie.getreadonly()
if not is_read_only then
random_values_table = create_random_values_table(random_values_table)
end
write_random_values(random_values_table)
end
event.onloadstate(loadingState) --This way the function registers only once, thus only one instance is called when the event (loading a savestate) happens.
while true do
emu.frameadvance()
end