Just realized you were talking specifically about stage 1-1.
I found these exits using a method I call "drilling". Basically, I freeze the value of 030071B0 (spongebob's damage state) to be permanently 1, that way you can bypass the kill layers. Then I freeze 03003737 (downward momentum) to a high number, so spongebob is clipping through everything.
It's quite an efficient way to find the coordinates of oob exit, but of course says nothing about whether or how they are actually reachable.
Huh, that's pretty strange. Here's a video of me exploring the oob area with the camera following me. https://youtu.be/Hs8T_zDGJx0
I've slightly altered your script so it goes like this:
memory.usememorydomain("IWRAM")
local Addresses = {
display_x = 0x3728,
display_y = 0x372E,
game_state = 0x25C0,
x = 0x3728,
y = 0x372C
}
--function for checking an input with how many frames to delay
function inputdelay(inputs, delay)
local is = input.get()
local start = false
if inputs ~= nil and (is[tostring(inputs)] ~=nil) then
--console.log(is) --debugging
while (delay > 0) do
emu.frameadvance()
delay = delay -1
end
start = true
return start
end
return start
end
while true do
local x = memory.read_u32_le(Addresses.x)
local y = memory.read_u32_le(Addresses.y)
local display_x = memory.read_u32_le(Addresses.display_x)
local display_y = memory.read_u32_le(Addresses.display_y)
local x_speed = 6
local y_speed = 16
-- if inputdelay("C",30) then
-- memory.writebyte(Addresses.State,7) --Instant recruit
-- elseif inputdelay("V",30) then
-- memory.writebyte(Addresses.State,8) --Instant win (5 for xp, 8 for item interface)
-- elseif inputdelay("B",10) then
-- memory.writebyte(Addresses.Win,1)
-- memory.writebyte(Addresses.State,5)
-- --toggle = (toggle == 0) and 1 or 0
-- --if toggle == 0 then toggle = 1 else toggle = 0 end
-- end
if (joypad.getimmediate().R == true) then
if (joypad.getimmediate().Left == true) then
x = memory.read_u32_le(Addresses.x)-65536*x_speed
elseif (joypad.getimmediate().Right == true) then
x = memory.read_u32_le(Addresses.x)+65536*x_speed
else
x = memory.read_u32_le(Addresses.x)
end
if (joypad.getimmediate().Down == true) then
y = memory.read_u32_le(Addresses.y)+65536*y_speed
elseif (joypad.getimmediate().Up == true) then
y = memory.read_u32_le(Addresses.y)-65536*y_speed
else
y = memory.read_u32_le(Addresses.y)
end
memory.write_u32_le(Addresses.x,x)
memory.write_u32_le(Addresses.y,y)
end
gui.text(0,40, "X:"..display_x.." Y:"..display_y)
gui.text(0,60, "State: "..memory.read_u8(Addresses.game_state))
emu.frameadvance()
end
Will do! If I remember correcty, it happened in level 6-4.
That script is awesome btw. There are some interesting addresses I've found myself:
For me, the Y address that can change Sponge's position is 0300372E.
There are addresses that determine how far the camera will follow Sponge, even OoB - 03001650 (downward), 030015FC, 03001D80, 030025B0
When Sponge hits an exit trigger: 030072AC (I like setting a breakpoint there, so I can take my time to write down the coordinates of an OoB exit)
Also, here is a list of all OoB exits I've found so far (coordinates are taken from the 0300372A/E addresses):
https://drive.google.com/open?id=1gRJtfXyrY7JgvrZ7sJzRSFaR0_mMubZ6
There's some cool new stuff that us non-TAS runners have discovered.
In any level with the wind mechanic, you can glitch yourself into a wall that's to the left of you by just dashing into it at a specific point of the wind cycle. This will transport you to the top of the wall immediately.
In the Trench Bottom stage, this trick can be used at the very beginning of the stage to get out of bounds and find the exit trigger fairly quickly.
Here's a video of that:
https://www.youtube.com/watch?v=pF-mONtCHHo
So, I can't say I know a lot about how games actually work, but isn't this out of bounds area the game's RAM? I'm probably too optimistic here, but if that's the case, it might be possible to edit the memory values in that area to achieve some fancy stuff, like a credits warp, for example...