This is the third version of my Metroid Fusion 100% TAS. My testing was much more rigorous and I looked for creative solutions. The in-game completion time is 55 minutes and 28 seconds. This beats the previous version's in-game time by 3030 frames or 47 seconds (an in-game second is 64 frames). Because I aimed for in-game time, I opted to pause the game in order to manipulate luck, as the in-game timer does not run on the pause screen. I placed most of the pauses right before door transitions, so as not to detract from the flow of the run. One thing I've learned: shinesparks are slow. This run features several less shinesparks than the previous. The reason for this is that shinesparks have a delay both while Samus is "charging" it and once she has hit something.
Notes by Section
Main Deck/Arachnus
Not much is different here. Before Arachnus, I pause in order to get a faster eye door, which hopefully isn't too distracting.
Sector 1
After fixing each atmospheric stabilizer, the doors are on a timer until they open. Apparently, the lag from opening and closing the pause screen reduces this timer.
There is a slight route change. In the third atmospheric stabilizer room, it is faster to skip the missile tank and grab it (much) later in the game.
Sector 2/Zazabi
Not much different here aside from general optimization.
Sector 4/Serris
There are a few new room strategies, but otherwise just general optimization.
Sector 3/BOX
Faster BOX fight, other small improvements.
Sector 6/Mega-X
There are two less shinesparks here. Both were slower before.
I would have had bad luck on Mega-X, so I had to briefly pause.
Sector 5
For the missile tank right after getting ice missiles, I used a clever strategy to climb the room faster.
Sector 3/Meltdown
General optimization, along with a creative new way to get to the eye door.
Main Deck
I collect an early powerbomb tank, just like last time.
Sector 5
I collect another early powerbomb tank along with a missile tank as part of a faster route change.
There are a few new room strategies after getting powerbombs.
Yes, I pass through the ripper. Frozen enemies have strange properties.
I grab a missile tank on the way out instead of later. This allows me to run straight through the room with the speedbooster twice later in the run.
Main Deck/Yakuza
I had Yakuza grab me as high as possible, so I don't think the fight can be improved.
Sector 2/Nettori
Several improvements here and there.
Sector 5/Nightmare
Thanks to P.JBoy for telling me how Nightmare behaves. This time, I was able to kill Nightmare exactly where it needed to be.
Sector 4
General optimization, and a new strategy to grab the powerbomb expansion before leaving Sector 4 (one less powerbomb is used).
Sector 6/BOX II
The BOX II fight is faster, thanks to taking damage and standing inside of it.
Sector 1/Ridley
A few new room strategies, and more efficient use of the charge beam on Ridley.
Cleanup
In Sector 1, I collect the missile tank that I skipped from the beginning of the run. I don't use a shinespark to go up the vertical shaft next to the save room, because I would have to go far out of my way to charge it up.
I somehow didn't realize that there's a faster route to get back to the first room of Sector 2. It ended up saving four seconds.
Once again, I use one less shinespark in the beginning of Sector 6.
I found a new strategy for the tanks when I first enter Sector 3.
Final Bosses
All three forms of the SA-X are faster. The first two forms are faster due to a new strategy, while the core-x is faster due to better positioning.
The Omega Metroid is killed with vertical shots instead of diagonal shots, which prevents it from making any swipes and saves about a second.
I hope you all enjoy the run. If you have any questions, don't hesitate to ask me. I'll improve the 0% run ... eventually.
this script can be used to create a cutsceneless encode:
Language: lua
--[[
start this script at the same time as you playback the movie and dump the avi.
when finished, be sure to hit "stop" in the lua script window to ensure that the created file gets flushed
you'll have an "mfskip.avs" that will contain a set of Trim() commands that will create a cutsceneless encode
]]
local pigf = -1
local skipping = true
local startframe = 0
local outfile = io.open ("mfskip.avs", "w")
local firstsegment = true
-- remember to hit "stop" to ensure that the io file gets cleaned up correctly!
while true do
local igf = memory.readbyte(0x0300013B) -- in game time counter
if igf ~= pigf then -- display this frame
if skipping then -- end skipping, so record start of new unskipped segment
startframe = avi.framecount()
skipping = false
end
else -- skip this frame
if not skipping then -- start skipping, so record finish of last unskipped segment
if avi.framecount () > 1 then -- avoid 1 frame edge case that causes avs problems
if firstsegment then
outfile:write (string.format (" c0.Trim (%i, %i)\n", startframe, avi.framecount () - 1))
firstsegment = false
else
outfile:write (string.format ("last + c0.Trim (%i, %i)\n", startframe, avi.framecount () - 1))
end
skipping = true
end
end
end
pigf = igf
emu.frameadvance()
end
Joined: 3/25/2006
Posts: 850
Location: stuck in Pandora's box HELLPP!!!
Here's a much simpler script
Language: lua
while true do
if memory.readbyte(0x03000BDE) ~= 0001 or memory.readbyte(0x03000BE0) ~= 0002 then
avi.pause()
else
avi.resume()
end
vba.frameadvance()
end
Joined: 4/17/2010
Posts: 11475
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
P.JBoy wrote:
Here's a much simpler script
Language: lua
while true do
if memory.readbyte(0x03000BDE) ~= 0001 or memory.readbyte(0x03000BE0) ~= 0002 then
avi.pause()
else
avi.resume()
end
vba.frameadvance()
end
Oh god this was really obvious! We don't need a frame perfect video after all! The Guide shall have this script for all cutsceneless GBA encodes. I also guess some other emuators allow that.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
while true do
if memory.readbyte(0x03000BDE) ~= 0001 or memory.readbyte(0x03000BE0) ~= 0002 then
avi.pause()
else
avi.resume()
end
vba.frameadvance()
end
hmmf... avi.pause() isn't documented on the official vba-rr site.
so... what's at 0x03000bde?
while true do
if memory.readbyte(0x03000BDE) ~= 0001 or memory.readbyte(0x03000BE0) ~= 0002 then
avi.pause()
else
avi.resume()
end
vba.frameadvance()
end
Oh god this was really obvious! We don't need a frame perfect video after all! The Guide shall have this script for all cutsceneless GBA encodes. I also guess some other emuators allow that.
I use this for super metroid in snes9x:
Language: lua
prev = -1
while true do
igframe = memory.readword(0x7e09da)
if igframe == prev then emu.speedmode("maximum") else emu.speedmode("normal") end
prev = igframe
emu.frameadvance()
end
This is similar to the above, but has the advantage that the same script can be used for skipping cutscenes while playing, not just while dumping. However, I think this method may not work with AVI dumping on windows with snes9x due to a bug which causes the audio dumping to ignore the speedmode.
I have also implemented support for emu.speedmode in my copy of VBA (for the linux version), which is what I used to create the cutsceneless encode. For that, I used this lua script:
Language: lua
pigf = -1
while true do
local igf = memory.readbyte(0x0300013B)
if igf ~= pigf then emu.speedmode("normal") else emu.speedmode("maximum") end
pigf = igf
emu.frameadvance()
end
Joined: 3/25/2006
Posts: 850
Location: stuck in Pandora's box HELLPP!!!
natt wrote:
hmmf... avi.pause() isn't documented on the official vba-rr site.
so... what's at 0x03000bde?
Oh damn, sorry guys, I never committed those avi functions to the SVN, I'll do that ASAP.
EDIT: I tell a lie, it's been in there since 2010 and I didn't check the update logs that far back
0x03000BDE is the game mode:
00 Title
01 In-game
02 Soft reset
03 Map
04 Most cut-scenes
05 SA-X close-up
06 Erase SRAM menu
07 Intro
08 Game over
09 Ending
0A Died from SR388 collision
0B Credits
0C Demo
--0D Unknown--
0E Nothing
0x03000BE0 is a sub-game mode that takes the default value 2 unless door transitioning or other similar situations
Could someone edit this movie's (and 1234M's) categories to include "Contains speed/entertainment tradeoffs?"
Doors have a 2 frame rule, and since this run aims for in-game time, biospark uses the frame rule to his advantage. He postpones exiting a cutscene by a frame whenever the frame rule doesn't line up with when Samus reaches the door's loading zone.
However, pauses also do not count towards in-game time, so they could also be used to shift from even to odd in any room. While pauses are used throughout the run to manipulate the RNG, they are not used in various other places where it would save one in-game frame (the second room, for instance).
This was not used in biospark's first 100% tas of this game, nor dragonfangs' 0% tases, so there were no intentional tradeoffs in those runs
Imho this is also another good reason not to aim for in-game time in the future, even though I'd love to see an 0:54
Is it really worth using "contains speed/entertainment tradeoffs" for single-frame differences? Especially since, as I understand it, taking advantage of those differences would require pausing the game, which costs more than a second each time? Usually that tag is used for when there are significant (i.e. readily-noticeable at normal speed) detours from "optimal" play specifically for purposes of entertainment.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
This is not a single frame difference, it is a single in-game frame difference. Without this tradeoff, there would be a second of pause time in roughly every other room. I don't know about you, but watching a run which pauses that often would be significantly less entertaining. Besides:
This is not a goal choice per se. This tag should not be used for non-speed-oriented runs such as maximum score runs or playarounds. Instead, it should be used for movies that primarily aim for fastest time but make some (small) time sacrifices for the sake of entertaining the audience, avoiding repetition, or avoiding doing something that would be uninteresting. It may also be to collect an item or show off a part of the game that increases entertainment value.
The pauses save time because pausing does not count towards in-game time, which this TAS aims to minimize.
Sorry for the huge bump, but I didn't notice this post until now.
Anty-Lemon wrote:
While pauses are used throughout the run to manipulate the RNG, they are not used in various other places where it would save one in-game frame (the second room, for instance).
Pauses can never save in-game time in this manner. Depending on the parity, you'll either lose 0-1 frames or 1-2 frames.
Anty-Lemon wrote:
Imho this is also another good reason not to aim for in-game time in the future, even though I'd love to see an 0:54
The next 0% and 100% runs must aim for real time anyway, since there's a memory corruption glitch that allows for a very low in-game time. Both runs will be over a minute faster because of new tricks (and new route changes for 100%).
While pauses are used throughout the run to manipulate the RNG, they are not used in various other places where it would save one in-game frame (the second room, for instance).
Pauses can never save in-game time in this manner. Depending on the parity, you'll either lose 0-1 frames or 1-2 frames.
That's not right. To elaborate, doors have a frame rule which is dependent on the game's global timer at 0x3000002, not the in-game timer. If the frame rule is not in your favor, you can pause for an odd number of frames to make it work. Try it for yourself
EDIT: Ohhhh I see what you're saying. I forgot pauses waste an in-game frame
BioSpark wrote:
The next 0% and 100% runs must aim for real time anyway, since there's a memory corruption glitch that allows for a very low in-game time. Both runs will be over a minute faster because of new tricks (and new route changes for 100%).
Yeah, at the time I made that post the memory corruption stuff hadn't taken off yet