Post subject: Lua Script help for a Newbie
Joined: 10/21/2019
Posts: 4
Location: Brazil
Hellow. I'm new in this forum, even I visiting it from a long time. I'm into this LUA script thing and I'm in love with the possibilities. I found a specific LUA script around the Internet, and I think it's a great script, but I think it can be even greater. So I asked permition to the autor to check the code and update the script with fixes, new features and other updates. He said he don't care and he is glad to see someone is updating his script. After that, I make a lot of tests and added a lot of things even myself got marveled at the results, even with the hard work I had to it in some parts. But I want to add a script to make easier to access the secret features without using the game's secret codes, and there is where I got stuck. So, I need to know if there's some command to make a LUA script wait for a condition be set to start the execution. Example: If the address 0xFF000A is not 0, first wait the address 0xFF000A be 0. After that, if address 0xFF000A changes from 0 to 1 (or other value), execute function. If there's some command who can do it and someone give me some light with an example script, I'll be very grateful.
Lil_Gecko
He/Him
Player (98)
Joined: 4/7/2011
Posts: 520
You can just use "while".
Language: lua

if memory.readbyte(0xFF000A)~=0 then while memory.readbyte(0xFF000A)~=0 do emu.frameadvance(); end; while memory.readbyte(0xFF000A)==0 do emu.frameadvance(); end; function(); end;
Haven't tested but I think it should work.
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Example: If the address 0xFF000A is not 0, first wait the address 0xFF000A be 0. After that, if address 0xFF000A changes from 0 to 1 (or other value), execute function.
I like to work with modes:
Language: Lua

Mode=1 YourFunction = function() -- place your code here end while true do AddressVal=memory.read_u8(0xFF000A) if Mode==1 then if AddressVal == 0 then -- first it must be 0 Mode=2 end elseif Mode==2 then if AddressVal ~= 0 then -- changes from 0 to other value YourFunction() end Mode=1 -- reset mode? end emu.frameadvance() end
Joined: 10/21/2019
Posts: 4
Location: Brazil
Thanks for the quick reply, MUGG and Lil_Gecko, but I couldn't put the codes you suggested to work. It is crashing the emulators (MAME-rr and FBA-rr). Much probably I'm doing something wrong in put the scripts and codes I have at the example codes you gave me. Silly me!! I will try to explain my idea. The game in Street Fighter Alpha 3, and the script I'm updating is a "Traning Mode" script by Jed Possum. I want to make a script to put the cursor over the Dictator and, for each time I press Start, it changes the character to Boxer. Press Start again over Boxer, the character changes again to Juli. Start again and change to Juni. Start again and go back to Dictador. It's a code to make the command circles between these four characters, starting with Dictator. I'll put the codes I got here. The address 0xff8502 is the character slot for the Player 1. The values (memory.readbyte) for this address are: Dictator = 0x0A; Boxer = 0x15; Juli = 0x1E; Juli = 0x1F. The address 0xff8060 is for the Start Button. The values (memory.readword) for this address are: 0 = no input; 256 = Start pressed (1st frame); 257 = Start held (2nd frame and beyond); 1 = Start just released (1 frame). My original idea for this was:
if memory.readbyte(0xff8502) == 0x0A then --Dictator
	if memory.readword(0xff8060) == 256 then --Start just pressed
	memory.writebyte(0xff8502,0x15) --Boxer
	end
end
Just this code works perfectly to change from Dictator to Boxer. Now, if I add another code with the idea of changind from Boxer to the next character...
if memory.readbyte(0xff8502) == 0x15 then --Boxer
	if memory.readword(0xff8060) == 256 then --Start just pressed
	memory.writebyte(0xff8502,0x1E) --Juli
	end
end
The result makes the Dictator changes directly to Juli without stop at Boxer, and this change occour in one frame.
Lil_Gecko
He/Him
Player (98)
Joined: 4/7/2011
Posts: 520
Try this maybe :
Language: lua

t = {10,21,30,31}; while true do curr = memory.readbyte(0xFF8502); for i=1,4 do if curr == t[i] then a=i; end; end; if memory.readword(0xFF8060)==1 then memory.writebyte(0xFF8502,t[(a%4)+1]); end; emu.frameadvance(); end;
Joined: 10/21/2019
Posts: 4
Location: Brazil
Using these lines in the script file, it keep showing the message Lua Error in GUI function "can't call fba.frameadvance() from here" (using FBA-rr) / "can't call mame.frameadvance() from here" (using MAME-rr). Each time I press the OK button, the emulator advances one frame and calls the message again and again. But keeping the Enter button, I can jump the Error message frame-by-frame consecutively and check if the code works. And... YES!! It works!! Thanks a lot, Lil_Gecko!! :D Now I just need to get rid of the error message. Any idea?
Lil_Gecko
He/Him
Player (98)
Joined: 4/7/2011
Posts: 520
Hmm. I tried playing SFA3 with the script I wrote. If I declare the variable "a" at the begining like this :
Language: lua

t = {10,21,30,31}; a=0; while true do curr = memory.readbyte(0xFF8502); for i=1,4 do if curr == t[i] then a=i; end; end; if memory.readword(0xFF8060)==1 then memory.writebyte(0xFF8502,t[(a%4)+1]); end; emu.frameadvance(); end;
This script alone works as expected with no error. So I don't know really. Maybe if you post the whole code ?
Joined: 10/21/2019
Posts: 4
Location: Brazil
After a night of sleep, I manage to got the problem. The lines was put in a wrong file (this script uses multiple files with scripts inside each one). These lines must the put in the main file, and not in the "sub-files". Another thing I got was other error messages. First, I added some commands to make your command runs only at the player select screen, and just while the player don't confirm the character. After that, I got a different error. I make tests neutralizing some lines of your example and found out the line "while true do" was the final problem. I just removed it and everything is running flawless. In the end, the lines become this (just bellow the "function cheat()" line):
Language: lua

--Boss Select t = {10,21,30,31} a=0 curr = memory.readbyte(0xFF8502) for i=1,4 do if curr == t[i] then a=i end end if memory.readbyte(0xffbe52) == 0xFF and memory.readbyte(0xffbed2) == 0xFF and memory.readbyte(0xffbcca) == 0x00 then if memory.readword(0xFF8060)==256 then memory.writebyte(0xFF8502,t[(a%4)+1]) end end
I changed the memory.readword(0xFF8060) value from 1 to 256 to make the character change when the Start button is pressed, not when it is released. The final two lines of your code ("emu.frameadvance()" and "end") was already present in the files. So, no need to have redundant lines, do you agree? Now everything is perfect. For the Player 1... From now, I can play with the lines of your help, and try other possibilities with this script. First, I'll try to change the command to change the characters to see it's possible to make the thing work more elegantly (like put to change the characters with left and right). But, of course, I must change other variants with the memory.readword(0xFF8060), once it registers the P2's Start Button press as well. Anyway, I must say thank you for all the help and attention. You guys are amazing!! Again, thanks you!! EDIT: Added the "a=0" into the code.
Lil_Gecko
He/Him
Player (98)
Joined: 4/7/2011
Posts: 520
I don't have time to make a big answer now but yeah, while true do .... emu.frameadvance() end is just use for the script to be always active. You use it only once in the main file. If you just want to add lines inside a script, you don't want to add them again.