Posts for aji

aji
Experienced Forum User
Joined: 11/19/2014
Posts: 4
Location: IRC
So last week I did manage to get 0:42 in Green Grove Zone Act 1, by collecting the 2nd flicky in the first part a bit faster: https://www.youtube.com/watch?v=ilZJvY_zRzw I guess I got lucky and the second half of the level synced perfectly, coming in at 42 seconds and 58 frames. I'm fairly confident there's not much room for improvement left. Maybe a frame here or there. 0:41 or less doesn't seem possible with current techniques, but I would love to be proven wrong about that. I'm considering a non-linear approach, using the level select cheat to do each act individually and splicing the input sequences together. I suspect most in-game events are controlled only by the level timer, possibly including randomness. However some levels (like boss fights) don't include any randomness at all, for example Rusty Ruin Act 3, so I could knock those out right away without knowing for sure if desyncs are a risk. I might also do a separate bonus movie of Final Fight this way, since it's not part of an any% run. After all, a good TAS should beat all existing records.
aji
Experienced Forum User
Joined: 11/19/2014
Posts: 4
Location: IRC
BizHawk's Lua interface is indeed quite different from the one in Gens, and I'm not sure how much of the Sonic HUD code would be reusable without major modifications. For example, I went to write a basic jump predictor and found that apparently BizHawk Lua has no equivalent to gens.emulateframeinvisible(), or even a way to automate frame advance at all since every call to emu.frameadvance() just defers the script. I'll have to write that functionality as a "jump finder" bot instead, it seems. The other option I considered was figuring out how speed is calculated during a jump and doing the prediction that way. I unfortunately wasn't able to figure that out, but I did figure out that the values at FFC204 and FFC206 are the forward and lateral components of Sonic's speed. These values are computed from his angle and X/Z speed, and might only be used for choosing animations and detecting skids. Comicalflop was calling FFC204 "speed" and was optimizing based on that. This does reflect Sonic's speed if he's moving in the same direction he's facing, but if facing a direction other than the one he's moving (such as when turning) the value at FFC204 will be less than Sonic's absolute speed. I spent last night converting some code into C, starting at loc_3510 and going backwards, since I understand C better, and here's the code that computes those values. This is a very short part of sub_2DDE which is called from IngameRun and appears to be the subroutine to update Sonic's motion. (Sonic's base address is loaded into a6 pretty early and not touched for the rest of the subroutine.) By the way, here's the .wch file I've put together so far. It doesn't have a lot you don't have already, but should save a bit of time. (Also, I did manage to save some frames, and now am only 7 frames away from the level timer showing 0:42. Guess I'm not done with GGz1 yet!)
aji
Experienced Forum User
Joined: 11/19/2014
Posts: 4
Location: IRC
Thanks for getting the disassembly, feos! It does have names, just very few of them. Usefully, there are at least IngameRun, RunLevel, and RunSonic labels.
marzojr wrote:
I am interested in helping; if not with outright TASing (because last I checked I still could not use BizHawk in Linux), at least with information. Since I can peruse the disassembly without difficulty, feel free to ask questions and I will try to find answers.
I would love to have your help, marzojr! I know my way around 68000 asm a bit, but as this is my first ever TAS I can definitely use the help, especially from someone with your experience. I don't have any big questions right now. Better visibility into the in-memory structures would certainly be useful, since at some point I want to write a more comprehensive HUD. Something I've learned that might help: at FF11C6 is what appears to be a list of short pointers to on-screen objects, which should make it a lot easier to locate object memory. There's a similar-looking list at FF1124. I haven't figured out what either of them are actually used for yet. The game runs fine (albeit with missing sprites and no collisions, though shadows still show up and objects appear to be receiving updates) with either both lists frozen or just the FF11C6 list frozen, but with just the FF1124 list frozen the game soft locks after a bit. At FF0A08 is a 4-byte value that flips between these two addresses, and according to Sik's notes, FF0A0C is the number of active objects.
aji
Experienced Forum User
Joined: 11/19/2014
Posts: 4
Location: IRC
So, almost 10 years later, I'm picking this game back up. Sonic 3D Blast was a big part of my childhood and I'm surprised there's still not any published runs for it, especially given the attention that other Sonic titles for the Genesis have gotten. I started about 2 weeks ago, and 1 week ago started comparing my work against Comicalflop's WIP. The GMV wouldn't play correctly in BizHawk without changes, but once I fixed up the menu navigation to sync up the first gameplay frame, the rest of the movie played fine. BizHawk reported that the ROM hash didn't match. I suspect this is because the GMV is so old that it doesn't have a ROM hash (or maybe BizHawk doesn't import that info? or maybe GMVs don't have it to begin with? or maybe it was a bad ROM?) so I'm chalking this up to changes in emulation accuracy over 10 years, especially since the desync was only during title and menu sequences. I couldn't find a ROM anywhere that either didn't have the hash mismatch warning or could play Comicalflop's work without any changes. I waited to make this post until I could at least match Comicalflop's Green Grove Act 1 time from scratch. At first I was 40 frames behind, then 9 frames behind, and now I'm 18 frames ahead! Final in-game time is :43, TSC record is :48. (Saving ~15 frames should bring the in-game timer to :42, but I'm at a loss for where I'd find those. I might try at it, but I don't want to spend forever optimizing this level.) Video: https://www.youtube.com/watch?v=R2Lku0m5kZA Comparison video: https://www.youtube.com/watch?v=OOpa4hL1T-A It's going to be tough going forward without a reference like this! Surprisingly, there's not a lot of new information about this game. There's a disassembly by Sik that I can't read because I don't have IDA Pro, but there are some text files with memory addresses that made setting up RAM watches a bit easier. There's also better maps and better world records, but that's about all I can find. Some additional things I've learned: Physics:
  • Sonic's motion seems controlled primarily by a "direction" variable (2 bytes at 0xff2c18) with values like 0x100 to mean directly left, 0x400 meaning up-right, etc. The direction is modulo 0x800, and changes by 0x40 in the direction the D-pad is pressed. This means, for example, a complete U-turn takes 16 frames. It seems the "force" felt by Sonic in this direction is only affected by whether any D-pad buttons are being pressed, but I haven't tried to confirm this. I made a basic HUD to show this direction and the "actual" direction indicated by Sonic's speed, since certain parts of the physics seem to be controlled by their difference.
  • The "direction" variable tends to stick at the 8 main directions. That means if you're facing 0x400 (up-right) and press any of right, down-right, or down for 1 frame, Sonic will rotate toward 0x500 over 4 frames. However, you can cause Sonic to move in between these directions by quickly alternating the held direction. For example, if facing 0x400, you can hold right for 3 frames until the direction is 0x4c0, then alternate between holding up-right and right to cause the direction to flip between 0x480 and 0x4c0, which will cause Sonic to move up and slightly to the right. Sonic can still reach his top speeds when moving this way. This trick is really annoying to pull off sometimes, due to lag frames, but can help when optimizing routes. This doesn't work with spin dashing, unfortunately.
  • Since the force on Sonic seems to be affected by whether D-pad buttons are held, but the direction of this force is controlled solely by the direction variable, it's possible to more finely control Sonic's motion during direction changes by letting go of D-pad buttons in situations where the direction variable is otherwise changing on its own. For example, there are a variety of ways to U-turn from 0x100 to 0x500 (left to right). One is to simply hold right. The most minimal option is to only press right every 4 frames to trigger each 45 degree turn. In all cases, the U-turn still requires 16 frames to complete, but Sonic's final position and speed can be manipulated slightly.
Rules:
  • Flickies can only be caught 30 frames (depending on how you count) after popping the robot. This doesn't matter a lot of the time, since catching a Flicky optimally isn't always the best choice for the overall route.
  • When exiting an area after freeing all the Flickies, it's a small handful of frames faster to spin dash and U-turn into a skid to quickly reduce speed to trigger the transition.
  • Lag frames are counted toward the level timer. I haven't found a good way to control lag yet, but I think the main source of lag is loading new sections of the screen.
And no glitches yet, but I have a hunch it might be possible to get Sonic off-screen where objects aren't yet loaded, like in other Sonic games. (You can get to some pretty high speeds by falling far enough.)