This page documents memory editing using Lua.
Warning: TASes for this site are not allowed to use direct memory editing (whether it is Lua or Game Genie codes). Memory editing is for information or planning purposes only! Make sure you are not running a memory-changing script while making the actual TAS.

Memory Overwrite.

Memory overwrite is a useful way to test possibilities when it would be hard to generate otherwise.
Note that often, you can use a cheat code (e.g. Game Genie) in place of memory overwrite. However, memory overwrite is more powerful as you have power over what the value can be changed to, and you can overwrite large sections of memory.
The memory-changing functions are memory.writebyte(int addr, int value) (one byte), memory.writeword (two bytes), and memory.writedword (four bytes).
There are two basic ways to overwrite memory:

One-time overwrite

To overwrite a desired memory address once, simply use one of the memory-changing functions above, without using a loop. For example, if 0x1000 is the address representing the stage number and you want to jump to stage 9, you run the following script:
memory.writebyte(0x1000,9)

Continuous overwrite

To continuously overwrite an address with a value, you now use a loop. For example, if 0x1357 is the address containing the number of lives, chances are you can give yourself infinite lives by fixing its value as, say, 2:
while true do
  memory.writeword(0x1357,2)
  emu.frameadvance()
end
The following example compares both one-time overwrite and continuous overwrite. The goal of the following script is to stop the clock in Super Mario Bros. The address 0x07FA is the ones digit of the clock. The first script overwrites the clock value every frame, effectively freezing the clock. The second script overwrites the clock just one time, allowing it to further decrease.
First script:
local Clock = 0x07FA
local Value = 8
while true do
  memory.writebyte(Clock,Value)
  emu.frameadvance()
end
Second script:
local Clock = 0x07FA
local Value = 8
memory.writebyte(Clock,Value)

Overwriting entire regions

This is where Lua becomes useful, as you would need too many cheat codes to cover a whole region. This is useful if you wanted to void a whole region (say, to remove all obstacles), or you want to easily identify the IDs of tiles in a tileset, or you are a ROM hacker and you want to corrupt regions of memory just to see what happens (note that you can only corrupt RAM, not the ROM itself).
To do this, just use a for loop. For example, overwriting four-byte addresses with 0, 1, 2, 3, ... :
local i
for i=0, 250, 1 do
  memory.writedword(0x3000+4*i, i)
end
And an example to corrupt memory with random garbage:
local i
for i=0, 1000, 1 do
  memory.writebyte(0x3000+i, math.random(0, 255)'''')
end

Using input.get() to trigger overwrite

It is often desired that a script does not alter memory only once, or keep it a fixed value while it's running. But rather, alter the memory at a precise moment the user desires it. The ability to change the memory at a key press rather than reloading the whole script has a number of useful advantages.
Hold A to force the value at 15:
while true do
  local keys= input.get()
  if keys.A then
    memory.writebyte(0xA1A1,15)
  end
  emu.frameadvance()
end
Hold Q to increment the value, and W to reduce it:
while true do
  local keys= input.get()
  if keys.Q then
    local v= memory.readbyte(0xA1A1) + 1
    memory.writebyte(0xA1A1,v)
  end
  if keys.W then
    local v= memory.readbyte(0xA1A1) - 1
    memory.writebyte(0xA1A1,v)
  end
  emu.frameadvance()
end

LuaScripting/MemoryEditing last edited by feos on 8/4/2022 1:59 PM
Page History Latest diff List referrers View Source