Hi,
I've been a (very) long time lurker, and I've enjoyed many of the TASs submitted over the years, and I've finally felt compelled to become part of what I enjoy. Ok, formalities aside, I'm learning how to use the tools, but I require assistance with several aspects of them.
I want to play around with Robotrek and use it as a testbed for gaining experience. I made a quick movie years ago, to get familiar with frame advance and working frame by frame. It's about 2 minutes in length and mainly up to the point of making the first robot. It's probably not very optimized, but I'll get better with that in time.
http://dehacked.2y.net/microstorage.php/info/511323091/Robotrek%20%28U%29.smv
I would like some help with 1) figuring out how to effectively use RAM search, and 2) Using Lua to do various things (like putting boxes around npcs, objects, etc). I have programmed anything in ages, so I don't consider myself to have any basic coding skills. I did find this :
http://gshi.org/vb/threads/1536-My-PAR-Code-Proof, specifically : http://www.angelfire.com/nc/ugetab/imgs/robotrek.zip, and to save anyone the hassle of downloading unknown things, I've annotated a bit of the content here. I hope that's acceptable, please take appropriate action if it's not. I have no idea if it's useful or not for scripting in Lua.
Report for Robotrek
Created by Universal Game Editor
Num. Variable name OFFSET VAR.TYPE RANGE
===============================================================
1 Current World(2/4/6) 4541 1 byte 0 thru 255
2 Bonus Timer Time 4583 2 bytes +/- 32,767
3 Reference Name(Boy) 4645 7 letters TEXT
4 End must be 204 4646 1 byte 0 thru 255
...
74 LEFT(-)/RIGHT(+)Axis 7187 2 bytes 0 thru 65,535
75 UP(-)/DOWN(+) Axis 7189 2 bytes 0 thru 65,535
76 Facing Direction 7199 1 byte 0 thru 255
77 Equipped Item (Boy) 19731 1 byte 0 thru 255
...
I'm sure there's a lot more I will need help with, but I hope this was informative enough to get me started.
Well that's easy: check the wiki and post back if you have any specific questions.
Wow, that list of RAM offsets looks like a goldmine. Congrats on finding it. Here's a very basic example of how to use a memory address that may or may not actually work, but should be instructive nonetheless:
local cardinality = {[0]="left", "right", "up", "down"}
while true do
mydirection = memory.readbyte(19731)
gui.text(8,8, "I am facing " .. cardinality[mydirection])
emu.frameadvance()
end
A quick rundown of what's happening:
The variable "cardinality" is a table, which works a lot like arrays in C. It's an array of strings, basically. Lua's counting starts from 1, so I explicitly tell it that the first index is 0. You'll see why in a second.
The function "memory.readbyte" is how we get information from the game. I passed as an argument the number "19731" from the list of offsets you posted, and it returns the value at that RAM address. I'm assuming the address will have four possible values: 0 to 3 (inclusive), each representing a cardinal direction: up, down, left, or right, that will map to one of the strings in "cardinality."
The call to gui.text is probably self-explanatory at this point, but I'll point out that the ".." is Lua's concatenation operator, which connects the literal string "I am facing " to the string of the cardinality table at the offset given by "mydirection."
If my assumptions are correct, Snes9x will print the words "I am facing left" when the player-character is facing left, etc, with the message drawn on screen at 8 pixels from the left and 8 pixels from the top of the screen. My assumptions are probably wrong. :P
Hopefully that small application gives you some idea of what is possible. You should refer to any docs provided with the emulator, or emulua for other functions, like "gui.drawbox", which you'd use in much the same way for drawing outlines around sprites.
Thanks for the reply Dromiceius. I'm going to start tinkering with things when spring break comes around. I did try some of the code you posted, and I understand the basics of lua, and I'm going to try to wrap my head around the logistics of coding again. I forgot to mention I had already take a look at the RAM Search wiki page and found some of it useful.
My next set of questions is with the list of offsets I posted, do I have to translate them into Hexadecimal? Since its a list of offsets, what address is it offsetting from? I tested some of the offsets, and usually it returned a 0 as the value. Am I misunderstanding the concepts of "offsets"? My current understanding is that it represents a pointer that corresponds to a memory start address(i.e. 0x0000) + offset (i.e. 7199 (facing direction from the list above))= 0x7199 memory location.
You do. I've actually been out of the loop for awhile, so I forgot that Snes9x memory addresses are 6 digits, and usually take the form 0x7eXXXX. And that's what you pass to memory.readbyte.
The offsets you posted are... odd. I got the full list, and they all seem to be in decimal for some reason. I tested a few of them, but they don't seem to actually signify anything. They might be particular to whatever editing tool those docs appear to be packaged with— possibly pertaining to SRAM savestates.
I'd figure out what the deal is, but I have to do a bit of a reacharound to be able to search the RAM, and can't deal with it for the time being. :/
No, you don't have to translate the addresses into hexadecimal. If you actually have the decimal addresses, then you can just specify them as such. For example, to read a byte from position 15 (decimal), you would do emu.readbyte(15). This would be equivalent to emu.readbyte(0xf). The reason why hexadecimal usually is used, is that that, due to hardware reasons, gives the roundest numbers, with consistent numbers of digits, etc.
Normally when you find addresses yourself or on the internet, they will already be expressed in hexadecimal. You will then enter them with a 0x in front, to tell lua that it is a hexadecimal number, and not a decimal number. But since you seem to have found the something as rare as addresses expressed in decimal, you just enter them without the 0x in front.
Here is the most common memory layout of a snes game: http://en.wikibooks.org/wiki/Super_NES_Programming/SNES_memory_map
As you can see, not everything needs to start with 7e. For example, the address 0 is a faster way of accessing the memory at 7e0000 (faster for the game, not for LUA, of course). The only suspicious address he gives is 19731, which would be 0x4d13, which is a hardware register. It doesn't seem likely that you could read out the boy's item from a hardware register.
What I would do is to take a few of these addresses, search for them myself, and see if they agree with that table or not. And if they don't, try to find a translation that does make them agree.