User File #638585240848962683

Upload All User Files

#638585240848962683 - Mega Man X-X6 and MM7 (and Rockman&Forte) RNG monitor

mmx-x6 and 7 RNG monitor.lua
Game: Mega Man 7 ( SNES, see all files )
16 downloads
Uploaded 8/6/2024 6:54 AM by FractalFusion (see all 87)
This is a small Lua script which is used for Mega Man games that use the "MMX RNG". In case you don't know what I mean by this, it's a 16-bit period-43534 RNG starting with the value 0xD37 and governed by the following formula:
local function nextrng(rng)
	local rngh=(math.floor(rng*3/256))%256
	local rngl=(rngh+rng)%256
	rng=rngh*256+rngl
	return rng
end
This Lua script uses a reverse lookup to display the index of the RNG (0xD37 = index 0, 0x275E = index 1, etc.).
This Lua script also displays the R-F value for X-X6, which is (RNG index minus current framecount) mod 43534. When inside a stage, a ROM subroutine auto-runs the RNG at one cycle per frame without using it, so this value can be used to detect unusual RNG advances which *are* used by the game. MM7 has similarly a "R-2F" value (since RNG runs at two cycles per frame), whereas R&F does not run the RNG except when needed and so does not need to display such a value.
This Lua script also displays the current RNG value, the 3 RNG values before it, and the 6 RNG values after it.
console.clear()

--Set the game variable as follows (note that Mega Man 8 is not supported since it uses a different RNG):
-- Mega Man X: game=1
-- Mega Man X2: game=2
-- Mega Man X3: game=3
-- Mega Man X4: game=4
-- Mega Man X5: game=5
-- Mega Man X6: game=6
-- Mega Man 7: game=7
-- Rockman & Forte: game=9

local game=7

local rngaddrtable={0xBA6,0x9D6,0x9D6,0x13E2E8,0x93F70,0x90E70,0xFA,0,0xFB}
local rngaddr=rngaddrtable[game]

local cur_rng=0xD37
local max_number=43534
local rng_table={}
local reverse_table={}


local function nextrng(rng)
	local rngh=(math.floor(rng*3/256))%256
	local rngl=(rngh+rng)%256
	rng=rngh*256+rngl
	return rng
end

for i=0,max_number-1 do
	rng_table[i]=cur_rng
	reverse_table[cur_rng]=i
	cur_rng=nextrng(cur_rng)
end

console.write("Done")

while true do
	local b=mainmemory.read_u16_le(rngaddr)
	local f=emu.framecount()
	local rc=reverse_table[b]
	if rc then
		gui.text(10,30,"RNG Index = ".. rc)
		if game<7 then
			gui.text(10,50,"R-F = ".. (rc-f)%43534)
		elseif game==7 then
			gui.text(10,50,"R-2F = ".. (rc-2*f)%43534)
		end
		rc=(rc-3)%43534
		for i=1,10 do
			if i==4 then
				gui.text(10,70+i*15, string.format("%04X <",rng_table[rc]))
			else
				gui.text(10,70+i*15, string.format("%04X",rng_table[rc]))
			end
			rc=(rc+1)%43534
		end
	else
		gui.text(10,30,"RNG Index = Unknown\nYou might need to change the \"game\" variable\nin the Lua file and reload the script.")
	end
	
	emu.frameadvance()
end