Okay, I took a deeper look at how it generates the next RNG. This line should explain it well enough:
New
R= Old
R*109 + 1021
Every time the game wants a new random number, it does this, but keeps it a two byte value. This is applied to R1 or R2 as necessary.
I created a script which helps me to look at number of RNG rolls. I'm using it to check for a few things, such as quickly telling me just how many rolls take place with each action.
So far, this is what I saw:
- R2: 50 rolls - entering the options menu from title screen
- R2: 1 roll - Entering the forest (encounter stuff?)
- R2: 1 roll - Initiated a battle
- R1: 2 rolls - Message saying Treerats have appeared (
there are 2 of them)
- R1: 13 rolls - Prior to your command input (
Determining turn order and enemy actions, perhaps?)
- R1: 12 rolls - Round begin / initiate attack of Alchemist
- R2: 322 rolls - Melee animation (Wand) of Alchemist
- R1: 3 rolls - Treerat initiate attack
- R1: 3 rolls - initiate attack of Survivalist
- R2: 370 rolls - Melee animation (Knife) of Survivalist
... Eh, let's not bore you with the turn by turn. The Wand animation rolls 322 times, and Knife animation rolls 370 times. Enemy attacks do not appear to roll R2 crazy-lots like this.
So I'm going to analyze a few things using this script. Definitely better than doing things by hand -- Any thoughts on trying to check 370 rolls by hand?
The script is this:
Download EO_simpleRNGcheck.luaLanguage: lua
local R= {{addr= 0x020E9D04, count= 0, panic= 0},
{addr= 0x020E9D08, count= 0, panic= 0}}
R[1].n= memory.readword(R[1].addr)
R[2].n= memory.readword(R[2].addr)
--*****************************************************************************
local function Roll(rng) return bit.band( (rng*109 + 0x03FD) , 0xFFFF) end
--*****************************************************************************
--*****************************************************************************
local function ScanRNGs()
--*****************************************************************************
for i= 1, 2 do
local test= memory.readword(R[i].addr)
local c= 0
local sanity= false
if test ~= R[i].n then
local rng= R[i].n
for i= 1, 200 do
c= c+1
rng= Roll(rng)
if rng == test then sanity= true; break end
end
if sanity then
R[i].count= R[i].count + c
else
R[i].panic= R[i].panic + 1
end
R[i].n= test
end
end
end
emu.registerafter(ScanRNGs)
--*****************************************************************************
local function DisplayRNGs()
--*****************************************************************************
for i= 1, 2 do
gui.text(40*i, 1, string.upper(string.format('%x',R[i].n)))
gui.text(40*i,13, R[i].count,"green")
gui.text(40*i,25, R[i].panic,"red")
end
end
local keys, lastkeys= {}, {}
local function UpdateKeys() lastkeys= keys; keys= input.get() end
local function Press(k) return keys[k] and (not lastkeys[k]) end
--*****************************************************************************
local function ResetStats()
--*****************************************************************************
UpdateKeys()
if Press("space") then
for i= 1, 2 do
R[i].count= 0
R[i].panic= 0
end
end
end
gui.register(function() ResetStats(); DisplayRNGs() end)
I'm curious about names and what party I should make. In my quick test, these are the names I picked:
Goo Goo - guild name
C.Cannon - Landsknecht
F.Knight - Protector
GreenElf - Survivalist
Look! HP - Medic
Destiny - Alchemist
Then there's SDA's route which says starting with TSMAA might be desirable. Considering how the RNG works, I get the impression that anything route-wise that may work there will apply here.
I suspect a real-time speed-runner can match the route we make, step for step, and will successfully pull off anything we do using the actual console. All it takes is setting the clock to whatever we set and timing the initial moment where they turn on the game so that it matches down to the second. Fractions of a second doesn't matter here, it just needs to be precise to the second, not 1/60 of a second increment. Then it's closely studying what we do and matching everything from there.
But other than that, someone still has to pioneer the (
detailed, luck manipulating) route. I'm getting ideas from the RNG stuff, and since ShinerCCC at SDA did a good job of pioneering a general route, I might actually make some attempt to put the route to the test, TAS style.
But first, names. I am going to spend several frames on significant names. This cost in time is likely a one-shot deal (
all instances the names show up happen "instantly"; I do not expect extra lag), and we get recognizable names throughout the run. I feel the entertainment is justified for the tiny cost in time, so anyone got naming suggestions?