Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Sorry, but I ended up finding yet another improvement; this time its the celestial globe stage. Turns out using the front porch to clip into the house is faster than using the kid. Edit: Globe is now 2990 frames. This also gets rid of the only other source of randomness in the game since there's no need to manipulate the food from messing up the walk cycle except in the odd case RJ throws very far away.
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Link to video I did it. I improved the last part of the last stage. :D Even though this part was sub-optimal, it still saved 200 frames. I'm not going to submit this (yet), since it got me thinking other stages can be improved.
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
jlun2 wrote:
First stage done. The reason I used (EU) rom is because I can't seem to find a (U) version that doesn't freeze on the emulator. Anyways, movement is usually allowed every other frame, with some slight changes every now and then. Addresses annoyingly change locations every stage, so I have to refind them over and over unless the pointer(s) are found.
I think I found how the addresses move around. Sorta. The pointers seems to be 02161DB4, 021625C4 The first one works fine on reset and garden areas, but glitches badly in certain spots + if you have more than 1 character at a time. The second pointer does not seem to always work, but it changes to another character only if you swap, unlike the first address. I tried to make it not update falsely, but I haven't managed yet. At least no more needing to refind addresses. Download display.lua
Language: lua

--pointer may be 02161DB4, 02161DB8, 021625C4 --first one works shit when on certain stages, but works fine-ish elsewise --second is wonky on reset and garden areas local pointer1 = 0x21625C4 local pointer2 = 0x2161DB4 local pointer3 = 0x2161DB8 --Declarations here player = {direction = 0, x = 0, y = 0, z = 0, speed = 0, run = 0, cooldown = 0} --first pointer names = {[0x211E66C] = "RJ", [0x211EE94] = "Verne", [0x211CE70] = "Hammy"} --[[the following offsets from above, in hex ptr + 0x18 = direction ptr + 0x30 = x ptr + 0x34 = y ptr + 0x38 = z ptr + 0x84 = speed ptr + 0x460 = Hammy run ptr + 0x464 = Hammy run cooldown The pointer should point to an address 0x18 before the direction address. That address should be the following: 211E66C - RJ 211EE94 - Verne 211CE70 - Hammy Anything else then something is wrong. 0212BE48,02131B3C determines what char you are 1 Verne, 2 RJ, 3 Hammy ]]-- --both for single player; just sanity test function update(state, pointer) --Results from reading the pointer; this should be a value that when read again, should point to the character local ptr = pointer if (state == p1) then player.direction = memory.readlongsigned(ptr + 0x18) player.x = memory.readlongsigned(ptr+0x30) player.y = memory.readlongsigned(ptr + 0x34) player.z = memory.readlongsigned(ptr + 0x38) player.speed = memory.readlongsigned(ptr + 0x84) player.run = memory.readlongsigned(ptr + 0x460) player.cooldown = memory.readlongsigned(ptr + 0x464) end if (state == p2) then player.direction = memory.readlongsigned(ptr + 0x18) player.x = memory.readlongsigned(ptr + 0x30) player.y = memory.readlongsigned(ptr + 0x34) player.z = memory.readlongsigned(ptr + 0x38) player.speed = memory.readlongsigned(ptr + 0x84) player.run = memory.readlongsigned(ptr + 0x460) player.cooldown = memory.readlongsigned(ptr + 0x464) end if (state == p3) then player.direction = memory.readlongsigned(ptr + 0x18) player.x = memory.readlongsigned(ptr + 0x30) player.y = memory.readlongsigned(ptr + 0x34) player.z = memory.readlongsigned(ptr + 0x38) player.speed = memory.readlongsigned(ptr + 0x84) player.run = memory.readlongsigned(ptr + 0x460) player.cooldown = memory.readlongsigned(ptr + 0x464) else player1 = {direction = 0, x = 0, y = 0, z = 0, speed = 0, run = 0} end end function fn() local ptr1 = memory.readlongsigned(pointer1) local ptr2 = memory.readlongsigned(pointer2) local ptr3 = memory.readlongsigned(pointer3) local char = memory.readlongsigned(0x212BE48) --Testing if it points to char if (memory.readlongsigned(ptr1) == 0x211E66C and char == 2) or (memory.readlongsigned(ptr1) == 0x211EE94 and char == 1) or (memory.readlongunsigned(ptr1) == 0x211CE70 and char == 3) then update(p1,ptr1) gui.drawtext(0,60,"p1") end if (memory.readlongsigned(ptr2) == 0x211E66C and char == 2) or (memory.readlongsigned(ptr2) == 0x211EE94 and char == 1) or (memory.readlongunsigned(ptr2) == 0x211CE70 and char == 3) then update(p2,ptr2) gui.drawtext(10,60,"p2") end if (memory.readlongsigned(ptr3) == 0x211E66C and char == 2) or (memory.readlongsigned(ptr3) == 0x211EE94 and char == 1) or (memory.readlongunsigned(ptr3) == 0x211CE70 and char == 3) then update(p3,ptr3) gui.drawtext(20,60,"p3") else end gui.drawtext(0,0,"Player: ("..string.format('%.6f',player.x/65536.0)..","..string.format('%.6f',player.y/65536.0)..","..string.format('%.6f',player.z/65536.0)..")\nDirection:"..string.format('%.6f',player.direction/65536.0).."Speed:"..string.format('%.6f',player.speed/65536.0*100)) --debug; ptr# + ofset for x/y/z; "ptr result" is pointer -> ptr -> character things gui.drawtext(0,30,"Ptr1: "..string.format('%.8x',ptr1).." "..(names[memory.readlongsigned(ptr1)] ~= nil and names[memory.readlongsigned(ptr1)] or ' ')) gui.drawtext(0,40,"Ptr2: "..string.format('%.8x',ptr2).." "..(names[memory.readlongsigned(ptr2)] ~= nil and names[memory.readlongsigned(ptr2)] or ' ')) gui.drawtext(0,50,"Ptr3: "..string.format('%.8x',ptr3).." "..(names[memory.readlongsigned(ptr3)] ~= nil and names[memory.readlongsigned(ptr3)] or ' ')) gui.drawtext(0,70,"Frame: "..movie.framecount()+18) gui.drawtext(0,80,"Run: "..player.run.."("..player.cooldown..")") end gui.register(fn)
Edit: Rewrote the code to make use of 0212BE48 which determines what character you're using to prevent using the wrong pointer.
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
I noticed that some safes such as the one in the rocking chair stage if unlocked also acts as switches. The apple at the globe stage that's out of bounds (I walk past it during the TAS) seems unreachable; it immediately unloads if I walk towards it. In some stages, there's adults. While all of them will use a phone to call the Taxidermist if attacked, some stages are bugged, such as the calculator stage. I haven't managed to trigger the crashes that plagued me like hell on console. Basically, while TASing, I noticed if I "quick exit" a bunch of certain stages, it crashes the next time I enter a different stage. Quick exit as in achieve the goal, then leave the stage by Start menu like the Any%.