Why Metroid II's In-Game Timer Is Awful (Corrected)
- I believe, though I could be wrong, that this represents the first effort to truly document how the in-game timer in Metroid II: Return of Samus works. Before this, all that was really known was "The in-game timer is bad for segmented runs because it drops the seconds upon loading a saved game.", as stated by Bladegash at https://m2k2.taigaforum.com/post/new_problem_discovered_involving_game_time..html . As it turns out, the timer is bad for single-segment runs as well. Note that I found this out mainly for my own curiosity after getting an in-game time of 1:06 on a run. The run this beat by about 20 seconds actually had a LOWER in-game time of 1:05. This was the last straw for me, and so I dug into exactly how it works.
- First, the basics. Seconds as we humans think of them (IE there are 60 of them in a minute) are actually not tracked at all by the game. Instead, what happens is that every 256 frames, a counter is incremented. This counter goes from 00 to 0D (13 in Decimal), then repeats. Each time this counter reaches 00, it increments the in-game timer by one minute. This actually works fine on its own--256 * 14 (Remember, 00 to 13, so 14 numbers inclusive) = 3584 frames in an in-game minute. The Game Boy runs at 59.7 frames per second, and 59.7 * 60 = 3582 frames in a real-time minute. These don't quite match up, but it's close enough--you'll get about 2 seconds of drift per real-time hour.
- If this were all there was to the timer, it would be fine for single-segment times. But that's not all. Oh Lord, is it ever not all.
- One big thing to understand is that your assumption about how the timer works based on other Metroid games and what you see in the in-game timer relative to your real-time is probably wrong. You might think that the timer doesn't count item pickups. You'd be wrong. You may also think that it doesn't count room transitions. You'd be...sort of correct. Let me explain further.
- As mentioned, the timer effectively increments every 256 frames. The thing is that the timer is continually moving through everything, including pausing. Even when you haven't loaded a game yet, this timer is running. It just isn't incrementing. There are, from my research, three instances when the timer doesn't increment:
- 1. On the title screen, before you've loaded a save. This obviously makes sense.
- 2. When the game is paused. This also makes sense, but opens the timer up to heavy abuse even in a single-segment run. More on this later.
- 3. During certain portions of screen transitions. This includes the brief pauses before the screen moves on "shorter" transitions (EG falling down the initial hole near the start of the game), or the fadeouts of "longer" transitions (EG the transition when leaving the screen with Samus's ship). Note that the timer WILL increment on the REST of the transitions, IE while the screen is actually moving/fading in.
- Now, why are 2 and (Moreso in a real-time speedrun) 3 an issue? Well, the timer doesn't stop for X frames during these transitions. Rather, if the 256th frame occurs during a transition, the timer will simply skip incrementing altogether and merrily move along to the next one. I'll explain why this is bad with an extremely simplified example.
- Let's say Johnny Speedrun and Case McCasual are racing according to the in-game timer. Let's assume Johnny Speedrun makes it to the first (And in our extremely simple example, only) screen transition at frame 150, that the part of the screen transition where the timer doesn't increment lasts 50 frames, and that he beats the game at frame 3600. Let's also assume Case McCasual makes it to the first transition at frame 250, and he beats the game at frame 3750.
- Johnny Speedrun enters the transition at frame 150, exits it at 200, and first increments the counter at frame 256. Presuming I've done the math right, his in-game time on beating the game should be 1 minute.
- Case McCasual enters the transition at frame 250 and exits it at 300. Because he was in the screen transition at frame 256, he does NOT first increment the counter until frame 512, saving himself 256 frames (Slightly more than 4 seconds) of in-game time despite being WORSE at the start of the game than Johnny Speedrun. This extra 4+ seconds he earns is enough to allow him to win the in-game timer race, 0 minutes to 1 minute, despite the fact he was 2.5 real-time seconds slower than Johnny Speedrun. This is obviously a problem.
- Note that while situation 3 is the issue in a real-time run, a technical demonstration utilizing 2 could likely be performed to produce a 0:00 in-game single-segment run. Because the global timer always starts/runs at the same place, you can simply pause once every 256 frames (In real-time, it would probably have to be about once every 4-ish seconds, leaving it paused for a second or so to ensure the 256th frame occurs during the pause) to ensure the timer NEVER increments. While it would not be exciting except for the "look-what-I-can-do"-ness of the feat iself, I believe it would be possible with the help of an outside timer.
- There is one thing I still do not quite understand. It appears that the 256-frame counter is susceptible to lag at times--that is, it will increment one or two frames later than expected. It will then continue on this new cycle, every 256 frames. What I do not yet understand is what causes the lag--it doesn't seem tied to any of the "obviously" laggy sections, EG the first room with the infinitely respawning enemies.
- I may or may not dig further into this to understand what actually causes the lag. For now, though, I think I've explained why this in-game timer is a giant pile of useless garbage. If anyone wants me to demonstrate these findings, I'll happily fire up VBA on-stream and do so.