Post subject: TASing with character off-screen
Dashjump
He/Him
Experienced player (578)
Joined: 8/18/2012
Posts: 82
Hi everyone! Sorry if this is in the wrong section. I guess I'll start by trying to explain my predicament and requesting for any suggestions/ideas you guys might have. First of all I have to declare that I have little to no coding/programming knowledge and hence I can't write lua scripts (I can only leech off others' lua scrips and use them for optimisations). I'm currently working on TASing Sonic Advance 2 (any%). Those who have watched Mukki's outstanding run of SA2 would probably notice that Sonic is able to break insane speeds in this game and go offscreen more often than not. Unfortunately this makes optimisations really difficult as I have no idea where my character is; I only can gauge his approximate position by watching changes in velocity. In some cases where it is necessary to make tough maneuvers by clipping into specific pixel positions, I hit a brick wall (figuratively) and can't seem to continue further. In Sonic Advance 1, nitsuja managed to make a camhack function where the camera always follows Sonic. Is it at all possible to use a cheat code function to change the memory address of the camera such that it always follows my character? Or would there be any easier alternatives to optimising runs with the character offscreen? I know this question is probably too generic to demand for specific answers, but nevertheless I would like to know more about the subject from experienced TASers. Thanks!
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
You’ve already mentioned the solution yourself. You need a cheat or Lua script or whatever to make the camera follow the character. When doing this kind of cheating you always need to make sure the run syncs without the cheats, but it usually does I think.
Alyosha
He/Him
Editor, Emulator Coder, Expert player (3821)
Joined: 11/30/2014
Posts: 2829
Location: US
Finding a way to tie camera position to sonic is probably the easiest solution you can hope for, but there is no garauntee there is a simple way to do it. What RAM addresses do you currently know? Have you found and tried manipulating camera coordinates? If you have a basic RAM map of the game I can try to help in making a camhack, it's something I'd be interested in experimenting with anyway. What emulator are you using? I had to solve the same problem of TASing with off screen characters in Donkey Kong Country. What I did was make a LUA HUD that would display an outline of the terrain around Diddy Kong with a representation of Diddy centered on the screen (kind of like a radar.) This was very labor intensive so I'd only recommend it as a last resort, but it proved invaluable.
Dashjump
He/Him
Experienced player (578)
Joined: 8/18/2012
Posts: 82
I have tried doing basic searches to look for an X-coordinate for the camera, but to no avail. Attempting to freeze any address which I believed to be camera coordinates did not yield any effects. I'm currently using VBA-rr v23.5.
Alyosha
He/Him
Editor, Emulator Coder, Expert player (3821)
Joined: 11/30/2014
Posts: 2829
Location: US
I'll try to look into this today. It's also possible that camera speed is capped in simple enough way that the ROM can be easily modified to remove the cap, but let's find out. EDIT: That version of VBA seems old so I am testing with BizHawk. So far I found that camera position is at 590X in IWRAM (2 Bytes per value.) So for example freezing bytes 5900-1 successfully freezes the camera at it's current X-posiiton. Apparently sonic can still move on the stage as collision detection is tied to Sonic's position not the camera's, so next I need Sonic's RAM values to see if I can make a cheat or lua or something to tie them together. Here's a LUA script in BizHawk that does roughly what you want, so it is at least possible to do . This produces a bit of camera shaking, but it should always force the camera to be on Sonic.
while (true) do
	
	cam_x=memory.read_u16_le(0x5900)

	sonic_x_low=memory.read_u16_le(0x59E8)
	sonic_x_high=memory.read_u16_le(0x59EA)

	sonic_x=sonic_x_high*65536+sonic_x_low
	
	gui.text(50,20,string.format('%d',sonic_x))
	gui.text(90,50,string.format('%d',cam_x))
	gui.text(90,50,string.format('%d',cam_x))

	memory.write_u16_le(0x5900,math.floor((sonic_x-30000)/256))

emu.frameadvance();

end
This one works in BizHawk, so you might want to test it out there in level 1. The 30000 there is just an offest from the starting post. It might be different in every level. At any rate this should at least get you going in the right direction.
Dashjump
He/Him
Experienced player (578)
Joined: 8/18/2012
Posts: 82
Thank you so much for this! It's gonna take some time for me to port over all my inputs to BizHawk and get used to it, but nevertheless I really appreciate your help on this matter. Hope everything works out for me!
Alyosha
He/Him
Editor, Emulator Coder, Expert player (3821)
Joined: 11/30/2014
Posts: 2829
Location: US
You can try Bizhawk's movie import feature I don't know if it works for VBA but it will give you a head start. Also now that you know the camera can be frozen, another possibility is to just freeze the camera where you know you need to do a clip and then just wait until sonic gets there. This approach might work better, just another idea to test. Good Luck!
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
I think if you use ordinary lua camhack in sonic adv 1, it causes desyncs. So be careful it doesn't happen in sonic adv 2.
Dashjump
He/Him
Experienced player (578)
Joined: 8/18/2012
Posts: 82
Apparently porting over the movies from VBA to BizHawk causes a desync, so I'll have to stick with VBA for now.. :/ How would I go about freezing the camera in VBA? Doing a memory search in 00005900 yields null values. Or do the memory addresses differ when using different emulators?
Experienced player (690)
Joined: 11/23/2013
Posts: 2232
Location: Guatemala
Have you tried editing the movie file to test if it desyncs again?
Here, my YouTube channel: http://www.youtube.com/user/dekutony
Samsara
She/They
Senior Judge, Site Admin, Expert player (2238)
Joined: 11/13/2006
Posts: 2822
Location: Northern California
Dashjump wrote:
How would I go about freezing the camera in VBA? Doing a memory search in 00005900 yields null values. Or do the memory addresses differ when using different emulators?
I mean, if I were you I'd just redo everything in BizHawk... Accuracy counts for a lot and VBA isn't exactly great in that department. But I guess if you're really dead set on using VBA... Yes, BizHawk and VBA handle memory search differently: VBA more or less crams all the domains together, while BizHawk separates by domain. In layman's terms, the domain is the first 2 digits of the address. The memory address doesn't change between emulators: You can take a set of VBA addresses and easily look them up in BizHawk and vice versa, so you're correct in continuing to look up 5900 as an address, you're just looking in the wrong domain. 00005900 is technically within the BIOS domain, which doesn't actually use any addresses above 00003FFF, so that's why it's returning null values. Alyosha mentioned IWRAM, which corresponds to the first two digits of its addresses being 03. Therefore, the value you want to search in VBA is 03005900. Here's a list of GBA memory domains that's helped me out a ton when working with RAM Search (also shoutouts to Anty-Lemon for linking me to that in the first place).
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family. Now infrequently posting on Bluesky
warmCabin wrote:
You shouldn't need a degree in computer science to get into this hobby.