Post subject: Lua desync in v22 (Pokemon Blue)
Player (42)
Joined: 12/27/2008
Posts: 873
Location: Germany
Today, I was running a brute-force script on v22 starting at frame 5568 from this movie: http://dehacked.2y.net/microstorage.php/info/1709031519/POKEBLUE.vbm

local temp={}
local Max = 5
local i
local j
local total
local atual
local melhor
local AtDef
local SpdSpc

local wait={0,0,0,0}
local frame={5570,5759,5786,5855}

function avancar (n)
	for i=1,n do vba.frameadvance() end
end

function apertar()
	joypad.set(1,{["A"]=true})
	vba.frameadvance()
end

function darNome()
	joypad.set(1,{["left"]=true})
	vba.frameadvance()
	joypad.set(1,{["A"]=true})
	vba.frameadvance()
	joypad.set(1,{["start"]=true})
	vba.frameadvance()
end

function press(frame)
	avancar(frame-vba.framecount()-1)
	apertar()
end

function nome(frame)
	avancar(frame-vba.framecount()-1)
	darNome()
end

function resolveu()
	byte1=memory.readbyte(AtDef)
	byte2=memory.readbyte(SpdSpc)
	if byte1>=224 and byte2>=224 and byte2%16>=14 then
		return true
	else
		return false
	end
end

function imprime()
	for i=1,4 do
		io.write(wait[i]+frame[i])
		io.write(" ")
	end
	a=memory.readbyte(AtDef)
	b=memory.readbyte(SpdSpc)
	io.write(a)
	io.write(" ")
	io.write(b)
	io.write("\n")
end

out="solutions.txt"
io.output(out)

temp[0]=savestate.create()
savestate.save(temp[0])

melhor=Max
AtDef=0x0000D186
SpdSpc=0x0000D187

for i=0,Max do wait[1]=i
for i=wait[1],Max do wait[2]=i
for i=wait[2],Max do wait[3]=i
for i=wait[3],Max do wait[4]=i

	press(wait[1]+frame[1])
	press(wait[2]+frame[2])
	press(wait[3]+frame[3])
	nome(wait[4]+frame[4])
	avancar(80)
	if resolveu() then 
		imprime()
		vba.pause() --debugging purpose 
	end
	savestate.load(temp[0])

end
end
end
end

I ran it without the vba.pause() at line 87 because I only wanted the script to tell me where to do the presses. The script then gives me two solutions:
5570 5761 5790 5859 249 238
5571 5760 5790 5859 249 238
I try both of them and the result is different! I thought it was a mistake on the code and then I add the vba.pause() command and execute the same code I'm putting here, starting at frame 5568. The emulator pauses after a while and I immediately check D186 and D187 at memory viewer myself and they show F9 EE, the script's answer. Then, I stop movie recording, reset the game and play the movie again, frame advancing through the part where the script worked and see that it really did the presses at the frames it said. However, the addresses have E5 DB now, which indicates inaccurate emulation happened while the script was running. Is this an already known issue? Is there a way to bypass it?
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
It's been addressed a few times before: http://tasvideos.org/forum/viewtopic.php?t=9667 http://tasvideos.org/forum/viewtopic.php?t=8367 We currently don't know why it's messing up, unfortunately. Very little testing has been done on Lua. We suspect it is due to how frameadvance() works, but we are not sure. Try using gui.register() and movie.framecount() instead. The function registered by gui.register() should execute every frame.
Player (42)
Joined: 12/27/2008
Posts: 873
Location: Germany
I changed the script using gui.register() and movie.framecount() but it still desync'ed... I'll have to put my project on hold now until a version with more stable Lua scripting is released. Thanks for the help anyway.
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
The problem appears to be savestate.save() . I tested the function with my own script and managed to fix it by putting another vba.frameadvance() right before savestate.save() .
local g=savestate.create()

local x

while true do

x=movie.framecount()

if x==14538 then
 vba.frameadvance()
 savestate.save(g)
end

if x==14563 then
 savestate.load(g)
end

vba.frameadvance()

end
I don't know for sure if it works with the savestate.save() in your code. You might have to give one frame in advance. Edit: Sorry, it doesn't seem to work if I put other numbers instead of 14538. So it must be something else.