Posts for FatRatKnight

Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Approximately 560 frames faster at getting a Medusa than my previous run. First, it appears I've messed up a little around the Rhino; I couldn't summon a Rhino meat by Flaming him with the Mutant, costing two actions compared to the test run. Second, I had to change formations so I could affect the RNG how I like prior to the random encounter in Ashura World. I spot a few things I can do differently. One is I start with the Mutant F in the second slot to begin with, but this would only be helpful in this specific case. Another is I pick Dissolve instead of Fire at the BabyWyrm battle, but Dissolve has a longer animation and spawns an extra message, though it does increment an RNG for me. Lastly, I can run away from a battle that I chose to reset-dodge instead, which affects those RNGs differently. I had to increment the RNG at C0A6 to get the Rhino to drop meat, which is why he didn't die at the first opportunity. In this run, the value is 0x7D. Nearby values that will drop a meat in my favor are 0x7A, 0x7C, 0x7D, and 0x7E. Had I not wasted time using the Bow, the RNG would have hit 0x7B, which is not one of these magic numbers. This RNG is not incremented when I use Flame, as this is an RNG that determines chance to hit, and most magics can't miss. All the way back at BabyWyrm, I could have used Dissolve instead to increment this same RNG just once, assuming all my run aways still work, and I might be able to get a meat drop. Nothing else, except possibly my run aways, would be affected. As a quick test, I modified the memory to match the likely case prior to the battle. It failed. Apparently, whatever routine makes the enemy decide what to do is rolled a varying number of times, which ends up setting specific numbers for C0A6 anyway. Darn. So now I'm looking at the various starting RNGs I can pick for C0A6 and trying to see if I can give myself the right one, and hopefully without wasting two actions' worth of time. My test run sure did it well (it uses a weapon that can miss, thus incrementing C0A6), so now I'm looking to see if I can get away with the straight-forward Thunder+Flame strat or if I must end up wasting a bit of time without the handy Colt.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
There is my Multitrack script, and most other emulators support lua scripts (but this particular multitrack script I pointed out is for FCEUX alone). It displays input onscreen, as well as keep all future input stored so none of it is lost, make it much easier to work with multiple players, and even has several options you can set on it. And you can have it for the low price of zero dollars and zero cents! Well, yeah. No matter how I put it, it will seem like I'm advertising my own work. Still, I want to present my script as something to play around with. Has a somewhat steep learning curve, but try it out and see if it even comes close to what you're asking for. The script does overlay an input display on the emulator window, but I'm not sure if this sort of display is what you want. I have released rather poor versions of this script for Snes9x and VBA, but I can't recommend using them. The whole "lack of run while paused" thing kind of gets in the way.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Since you mentioned your x_functions script, I want to ask, have you taken a look at my own auxiliary script? I'm curious what you can add to the subtitles script. You're more familiar with your stuff than I am, and if you can produce a nice result, I will want to see it.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
[code lua]--Subtitles intended for Snes9x. Might work for other emulators. --Script mostly by FatRatKnight, zidanax added some modifications, then FatRatKnight went rampaging to make the perfect script -- Now with extra boxes! --Important functions: --S(StartFrame,EndFrame , Xpos,Ypos , Line1, Line2, ..., LineN) --Subtitle. --Paints the subtitle at selected location at specified time --Allows for multiple lines. --B(StartFrame,EndFrame , Xpos,Ypos , Xpos2,Ypos2 , Fill,Border) --Box. --Paints a box at selected location at specified time --Specify the color as well, will ya? --A(StartFrame,EndFrame , Xpos,Ypos , Fill,Border , Line1, Line2, ..., LineN) --Auto text+box --Paints a properly-fitting box around the subtitle you want displayed. --Manually putting in B(...) and S(...) lines for the same sub is inconvenient. --TypicalLoopOfSubbies() --By default, this is shoved into emu.registerafter() --It will handle all the subroutine junk for you. local Fn= {} local Time,End , x,y= {},{} , {},{} -- Universal local TextLines= {} -- Text local BoxW,BoxH , Fill,Border= {},{} , {},{} -- Boxes local i= 1 --***************************************************************************** local function CoRoutine_DispMsg(SelfRef, NextCo, Index) --***************************************************************************** if not Index then return end local D , X,Y= End[Index] , x[Index], y[Index] local L= {} local n= 1 while TextLines[n] do L[n]= TextLines[n][Index] -- Load lines into routine n= n+1 end n= n-1 while (movie.framecount() < D) do local cmd= coroutine.yield(SelfRef) local tst= true if NextCo then tst, cmd= coroutine.resume(NextCo,cmd) end if tst then if cmd == "die" then return "die" end NextCo= cmd else NextCo= nil -- Error took place. Just ignore it... end for j= 1, n do if L[j] then gui.text( X , Y +9*(j-1), L[j] ) end end end return NextCo end --***************************************************************************** local function CoRoutine_DispBox(SelfRef, NextCo, Index) --***************************************************************************** if not Index then return end local D , X,Y= End[Index] , x[Index], y[Index] local W,H , F,B= BoxW[Index],BoxH[Index] , Fill[Index],Border[Index] while (movie.framecount() < D) do local cmd= coroutine.yield(SelfRef) local tst= true if NextCo then tst, cmd= coroutine.resume(NextCo,cmd) end if tst then if cmd == "die" then return "die" end NextCo= cmd else NextCo= nil -- Error took place. Just ignore it... end gui.box( X,Y , W,H , F,B ) end return NextCo end -- Can take an arbitrary number of lines -- Its name is one letter long to save bytes. Lots of them. --***************************************************************************** function S(st,se , sx,sy , ...) --Time, pos, lines --***************************************************************************** if arg.n <= 0 then return end -- Sanity Fn= CoRoutine_DispMsg Time,End , x,y= st,se , sx,sy for z= 1, arg.n do if not TextLines[z] then TextLines[z]= {} end TextLines[z]= arg[z] end i=i+1 end --ox --***************************************************************************** function B(bt,be , bx,by , bw,bh , bf,bb) -- Time, pos, pos2, colors --***************************************************************************** Fn= CoRoutine_DispBox Time,End , x,y= bt,be , bx,by BoxW,BoxH , Fill,Border= bw,bh , bf,bb i=i+1 end -- [A]uto -- Boxes and subtitles, wrapped in one. -- Calculates the box size for you! --***************************************************************************** function A(at,ae , ax,ay , bf,bb , ...) --Time, pos, BoxColors, SubLines --***************************************************************************** if arg.n <= 0 then return end -- Sanity Fn= CoRoutine_DispBox Fn[i+1]= CoRoutine_DispMsg Time[i ],End[i ] , x[i ],y[i ]= at,ae , ax-2,ay-1 Time[i+1],End[i+1] , x[i+1],y[i+1]= at,ae , ax ,ay local len= 0 for z= 1, arg.n do len= math.max(len, string.len(arg[z])) if not TextLines[z] then TextLines[z]= {} end TextLines[z][i+1]= arg[z] end BoxW= ax + len*4 BoxH= ay + arg.n*9-1 Fill, Border= bf, bb i=i+2 end local routine -- Executes co-routines. --***************************************************************************** local function RoutineJunk() --***************************************************************************** local TempCo= routine if routine then local tst, cmd= coroutine.resume(routine) if not tst then routine= nil else routine= cmd end end if FCEU then -- Avert minor glitch with the display when not showing text gui.drawpixel(0,0,"clear") end end -- Finds the correct index on state load or lua open -- Loads all text that should exist on stateload, with proper endpoints -- Will also kill previously existing subtitles --***************************************************************************** function FindIndex() --***************************************************************************** if routine then coroutine.resume(routine,"die") routine= nil end i= 1 local fc= movie.framecount() while Time and Time <= fc do if End > fc then local TempCo= routine routine= coroutine.create(Fn) coroutine.resume( routine , routine , TempCo , i ) end i= i+1 end end local fc, lastfc= 0, 9999999999 -- 10 billion sounds safe; A few years --***************************************************************************** function TypicalLoopOfSubbies() --***************************************************************************** --Pseudo rewind detector fc= movie.framecount() if (fc < lastfc) then FindIndex() end lastfc= fc -- Handle adding new co-routines. while Time and (Time <= movie.framecount()) do local TempCo= routine routine= coroutine.create(Fn) coroutine.resume(routine,routine,TempCo,i) -- Trigger initalize code i= i+1 end RoutineJunk() end emu.registerafter(TypicalLoopOfSubbies)[/code] I realized I had this hanging around in my computer. It is a linked list based code that allows for painting boxes, too. It still doesn't like it when you insert lines out of chronological order based on start times, maybe I should get a sort routine in there somehow... Your actual subtitles should go in a different file. Considering I'm letting the lua interpreter handle the syntax for me, this file needs to have a require("FileNameYouUsedForTheAboveCode") as its first line, followed by function calls to B and S. Load this new file you made from the emulator and have fun. EDIT: Added a function that creates boxed text, A().
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
jimsfriend and I discussed stuff on IRC. Effectively, our route looks something like this: * Begin with Mutant (M or F), Baby-D, Baby-D, Baby-D - Avoid practically every random encounter through run away or resets * Slay the BabyWyrm * Slay the Rhino, get meat * Pick a fight with a random encounter for Eagle meat * Slay Ashura powered by a Medusa StonGaze, get Explode on Mutant * Slay Phagocyt with Medusa StonGaze * Get an Elixier in the Mountain Cave * Slay Dunatis with Medua StonGaze, get Teleport on Mutant, try for an item drop * Glitch the MAGI count by trashcan bug * Glitch the Dragon Race by Teleporting to Venus Town * Sell the item drop from Dunatis and buy an Elixier * Enter Venus Sewers the "wrong way" and grab yet another Elixier * Go straight to Fenrir, do not pass GO, do not collect 200G - Drop the glitch-dragon outside the room. Step south when entering Fenrir's hall * Explode Fenrir dead. Let a Baby-D eat it * Use Elixier for another Explode, and destroy another Fenrir. Let other Baby-D eat it. * Fight Great-D for their meats (Explode) and turn our former Baby-Ds into Titianas * Fight Arsenal If all goes well, then we can win in just a few minutes right after we glitch the Dragon Race. Naturally, I'm going to check a bunch of things before I commit myself to a full run. I'm posting this partly so I have an online copy of the route, in case I forget. May as well show it to everyone. EDIT: Here's how some of these things work. Manipulating what ability I get is easy enough. By starting a round, I advance the RNG that tells me what ability I get, when the game decides turn order. Each time a damage number is needed, this RNG advances again. I can waste a few actions in battle to get this RNG where I need it, and even reset out of the battle if I find a need. This will be how I pick up Explode and Teleport. Manipulating that I get an ability is a little more troublesome, but still quite doable, and can be done without affecting the what. The act of entering a battle and attempting to run away advances the RNG. Skipping the battle by reset prevents the RNG from incrementing. So I can probably manipulate that I get an ability. The earliest I can glitch the MAGI counter is upon defeat of Dunatis. Perfect timing, I get Teleport then, too. Use the trashcan and the MAGI counter is used as the item ID, a Cure potion, and four uses gets rid of my Power MAGI and the game writes 0xFF to indicate an empty slot. With 255 MAGI, we glitch our way through all MAGI doors! Then the Dragon Race. Simple enough, walk in, get the fastest dragon, then Teleport out with dragon in tow. We now have a glitch-dragon with walk-through-walls to wander the worlds with. The Elixiers are needed so that I can restore my Mutant's Explode. Only one shot of Explode will not cut it for two Fenrir battles and two random battles that include Great-D. A box in the Mountain Cave takes 36 steps there and back, an item drop from Dunatis would get us enough money to buy one Elixier, then there's another box of Elixier sitting in the sewer not far off. Explode is like a Hyper Cannon: It instantly eradicates a random encounter. Fenrir, in spite of being a tough battle triggered by an object you walk up to and hit A, can be insta-killed by an Explode. Fenrir meat turns a Medusa into DarkRose (useless) and turns a Baby-D into Anubis (... Eh). Anubis can change into Titania with some sort of dragon meat, so that's why I'm thinking about picking on a few Great-Ds. jimsfriend said that two Titanias can probably beat the stuffing out of Arsenal, having done it with a Mazin, a Titiana, and two weaker monsters that contributed practically nothing. I will try to beat Arsenal with 2 Titianas, a Medusa (useless), and a Mutant (useless), before I try the full run. Dropping the glitch-dragon outside the Fenrir hall has a mysterious effect. For one thing, the Fenrir battle never disappears. For another, I get to keep my glitch-dragon! So I drop glitch-dragon outside, fight Fenrir twice, then fight Great-D on my glitch-dragon and then finally rush to Arsenal. So it looks pretty solid, right now. All that needs to be worked out is a few tests on the route as a whole and the RNG, and I do feel pretty optimistic I'll find some way to make it work there. EDIT2: Just testing to see if the final boss is possible with two Titiana. It certainly is. Now to make attempts at crunching through the random numbers to try and make it work smoothly.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
In case you're curious, I've put some of my notes here. I may want to eventually point out some useful RNG values to try out. Such as the fact Haniwa only shows its face at address C0AA == 0x26, 0x68, 0x72, 0xA9, 0xC5, 0xD4, 0xFB, or 0xFF. If we're grabbing the Seven Sword, then we're diving into Nasty Dungeon and grabbing the Hyper Cannon, as I don't believe there's any reasonable alternative to destroying Haniwa. I have checked literally every single RNG value for StonGaze versus Paladin. It is impossible for a Medusa to petrify the Paladin group. All 256 values are failures. Glitching the MAGI counter using their Ninja glove will require the Hyper Cannon or a really potent character from somewhere. No random encounters lua script (keeps the RNG at a no encounters state):
while true do
    memory.writebyte(0xC0A9,0x02)
    emu.frameadvance()
end
I don't have a clue on how to get any of the late fifth characters, simply because I haven't even completed half the game normally. I really should get around to beating it normally to get better ideas... I may have hacked the RNG, but it looks quite possible to mess around with all the stat boost potions we could want. It takes some time to set up, especially the fact I had to gather a pile of items including Hyper Cannon before this state, but this is one way to prepare for the final boss. But your monsters idea might be handy. I have no idea what sort of time this would take, or even where to begin fighting Fenrir (I already made it obvious that this isn't a game I halfway completed), but I know monsters are highly independent of items. A mutant and three monsters might be a possibility, assuming Fenrir can die quickly enough a few times, letting us skip the bulk of item gathering, but Fenrir doesn't look all that easy to fight.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I thought of the term "swordless challenge". Technically, going swordless by itself is a challenge, and would imply the word 'challenge' anyway, but explicitly inserting the word 'challenge' should hopefully imply that the run follows the nature of the challenge as what is commonly known, and not that the run is exclusively swordless and we found a way to win without a sword. Or I could be completely wrong about the term and I ended up producing what is effectively gibberish. I am one of the people who preferred ending the game by glitch, but I can see why the normal game ending is a desired stopping point. In any case, I really should try to watch this run at some point...
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I've created a movie, from start to glitching the Dragon Race, that should greatly assist in testing various item-gathering strategies we keep theorizing about. I guess the final run length will be less than 40 minutes. I hope that the process of destroying the final boss doesn't eat up 10 minutes in both preparation and the battle itself. Not much to say, other than I produced a movie file that goes through the whole glitching process "legitimately," so you can start testing any theories you want with much of the hassle gone.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I made a small attempt at running the game. Not much to show, really, but it's given me an idea on who we'll encounter. A little bit of memory hacking, and I made it much simpler to have Teleport handy for the Dragon Race, so that I have a way to experiment with stuff. With that in mind, here's the complete list of compulsory battles: 1) BabyWyrm 2) Rhino 3) Ashura 4) Phagocyt 5) Dunatis 6) Arsenal A Medusa is indeed a good idea to have. In my test, I got meat from the Rhino then got an Eagle Meat to top it off. Bam, Medusa. Manipulating Teleport from Dunatis appears to be a difficult task -- There's only 8 numbers out of 256 that will allow it. And that's assuming the game even selects an ability to reward you with. Address 0xC0A5 must roll to one of these numbers: 0x25, 0x46, 0x49, 0x52, 0x5B, 0x88, 0x9F, or 0xB4. It is used for other things, which I haven't checked, but I know address 0xC0A5 does determine what ability you get. Lots of stuff opens up once Dunatis becomes a fine piece of art. For one thing, you have 29 MAGI. Use Trash Can 4 times on anyone. Now you have 255. Go straight to Dragon Race. Teleport out of Dragon Race. Now you can go anywhere. I managed to go straight to Arsenal. Alas, I haven't made preparations... The fastest dragon takes 2 frames to travel one step, as opposed to our normal 16 frames per step. Throw in walk-through-walls for good measure. Getting to places should happen real fast. I was hoping the act of traveling over otherwise impassable terrain wouldn't increment the step counter for encounters, but I saw it go up just the same. Darn. One thing I want to try out: Can we win using a ridiculous-Strength Robot wielding a ChainSaw? In fact, let's not wonder about it, let's do it! I hacked in a set of Sun Swords and a ChainSaw for my Robot. Too hard to cut with ChainSaw... Okay, out with that idea. As for buffing the Robot's agility using Karate, I went ahead and hacked in the Karate item just to be sure. Sure enough, equipping and removing the Karate doesn't reduce its uses. So the "hands-free" agility boost for a Robot is highly cumbersome at best, since we need to use every one of its 40 uses the hard way. Now comes the question of what do we use to beat the final boss? Our party is best described as "pathetic" when coming out of the Dragon Race. It's absolutely certain we'll have a monster and a Mutant in our party by this point. What items do we pick up? If we attempt to use a strength weapon for our Robot, the need for agility will get in the way of high-damage attacks. An agility weapon like CatClaw, perhaps, but where do we get the best agility items? And how much can we boost agility? If we want humans and/or mutants to deal damage, the only logical choice is to pick up a Hyper Cannon, aim it at a group containing Paladins, and steal their Ninja Glove to glitch our MAGI counter. Then use infinite stat-boost items for all the strength and agility we could want. Maybe HP and Mana, too. Who knows... But glitching the MAGI counter requires 16 items in our inventory. Although we're picking up valuables along the way, I'm thinking we might need a little junk, too. Anyway, those are my thoughts. So much of the game skipped thanks to two relatively major glitches...
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
jimsfriend wrote:
Hyper is only available in the nasty dungeon. You should be able to gaze a paladin.
The Hyper being in Nasty Dungeon doesn't sound bad, actually. We might need it to insta-kill other specific random encounters anyway. If a status effect that hits the group were to be successful on something, does it always hit the entire group?
jimsfriend wrote:
Empty the uses of karate by: original amount 40. equip it's now at 20. unequip it's now at 10. equip it's now at 5. etc or something like that.
Every time I equipped a Punch, Kick, or Headbut on my Robot, the uses don't go down like they do for swords, shields, guns, and so forth. Are you saying the Karate is different from the Punches, Kicks, and Headbuts in this fashion?
jimsfriend wrote:
I have never used chainsaw. Getting 6 sun swords would be quite time consuming.
There's also the Glass sword, Xcalibr, and Gungnir. As far as I know, from reading those maps, there are 2 Sun swords, 1 Glass sword, 1 Xcalibr, and 1 Gungnir in nifty little boxes for us to crack open and snatch for ourselves. Already, that's 5 of the 6 we need.
jimsfriend wrote:
That website has a maps page. I have saved all the maps and put them in a .rar http://www.mediafire.com/?sna5oskewu812ym these maps tell you which items are available in chests and also is helpful for counting movement squares if it comes down to that.
Those maps are definitely helpful. Pointing them out actually made me take a closer look at them, thanks.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I'm wondering about how we can go about slaying a Paladin for his loot. Given the possible location I saw a Paladin from here, this does not look like a battle one can easily win. Where can we pick up a free Hyper cannon, out of curiosity? I don't think I can find one on my own, not without needless exploration. If we can slay a Paladin quick and steal their Ninja glove, then the optimal party might even be this: 0-1 Robots: They can get strong from equipment, but if we want to use the bug to permanently boost their Agility, how can we quickly empty out the 40 uses of each Karate? Is one even needed up until we defeat Dunatis? 0-2 Humans: I'm not exactly sure what they bring that a mutant can't, but they can be buffed to 99 (and beyond with a bit of equipment) when we glitch the MAGI count from a Paladin battle. We can completely unequip them so we have slightly less menu time in battles, at a slight cost of removing their junk first thing. 1-3 Mutants: It's clear we need one. Getting Teleport from Dunatis is probably the best idea. Beyond that, glitch up an infinite source of Power and Speed, then stroll over to the final boss. 1 Baby-D: Become Medusa. StonGaze. Win versus the first set of compulsive battles, until after Dunatis. Maybe turn the monster into something half-decent later. I think I'll TAS up a test run. Human, Mutant, Robot, Baby-D. The most "balanced" party might actually be the fastest. ... Yeah, I froze up at the names for FFL1 after all... EDIT: I just looked at the description for ChainSaw: Instant kill; cannot cut if Str < Def-9; or against O-Weapon if Str < 2*(Def-4) It can cut through the O-Weapon, assuming you have ridiculous strength. The final boss has 99 defense and a trait that effectively gives O-Weapon. So all we need is 2*(99-4) Strength, or 190, and we can get our insta-death. A Robot nails 192 Strength with six Sun swords, or with equivalent strength-boosters. I'm curious if we can cause an insta-death this way, filling up the seventh and final Robot slot with the ChainSaw. Or is there something I'm missing? Do we still need Agility in this case?
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Odd, the Samus I knew uses the Power Beam on her right hand. Just seeing all the distinct objects/characters takes some work. This appears to be a decent job.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
jimsfriend wrote:
http://www.shenafu.com/ffl2/weapon.php From that page it says power magi adds 22 attack strength to robots. Is this for each magi or is that a constant? If it's for each, you could 1 hit kill the final boss with 7-sword.
It's difficult to say. But I get the impression that the regular bonus, the 5+MAGIs bonus, is what is applied. Considering the fact the list also shows things like monster/mutant abilities giving Robot HP and stats, which can't be equipped on a Robot. But that's my guess. The MAGI isn't equipped like any other item, is it? It's worth testing, though -- A chance to one-shot the final boss would certainly be nice. It pays to do some testing to see if we can write an item into the MAGI counter! I'm looking at the possibility of giving our Mutant a number of stat-boost potions from the Trash Can itself. If we glitch the MAGI count, I'm hoping we can glitch a convenient set of stat-boost potions all the way out to maxed stats. The potential drops need to be as close as possible to the ID of the Power potion while still below it. I see a Paladin in the monster list carrying the Ninja glove, just 5 IDs below the Power Potion. How easy is it to fight one of those? And pick up just 5 MAGI from somewhere, and we get our 99 Strength Mutant ready to smash stuff. Another MAGI, and we boost the Agility to 99 so said smashing actually hits. The other possibilities... They don't look so nice. The Silver Helm from a Samurai is the next closest, and that's 16 IDs away. It gets worse from there... How useful are 99 stats on a Mutant or Human, out of curiosity? My unfamiliarity is pretty painful... I can look up stats, but I can't tell you if it's practical. For all I know, the Paladin is dummied out, or the most common thing around in the next world. I simply haven't seen one yet.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I broke a door. And the others. This is the infamous Trash Can glitch being used for a purpose besides Power and Speed potions. The game sets aside two bytes per item: The first byte identifies what the item is, and the second byte tells us how many uses it has. There's 16 item slots in your inventory set aside for this. The 17th slot, where the trash can is located, when you attempt to use it, will make the game think you're using the 17th item in your inventory. That spot is reserved for other things. The first byte, in this case, is your MAGI counter. The second byte is in two parts: The upper nybble tells us who is equipped with the Power MAGI, and the lower nybble tells us how many Power MAGI we have. We can equip the Power MAGI on our fourth character to maximize the number of uses on our trash can. If you leave everyone else unequipped of MAGI, try using the trash can exactly 16 times (with the right MAGI count that identifies a usable item). Suddenly, the Power MAGI we put on our fourth character is now on the third character. What the hey?! Keep reequipping the Power MAGI on the fourth character for a theoretical infinite use of whatever item the MAGI counter says it is. To minimize the number of uses, we keep the Power MAGI unequipped. Using up the trash can so that it has 0 uses left will set the MAGI counter to 255, a blank slot of a normal item. I've read from GameFAQs that if your main inventory is full, and you glitched your MAGI counter like this, then you can get a new item drop from a battle and overwrite the MAGI counter (and stuff relating to the Power MAGI). One use is so that we have an unusually high Power MAGI count. Up to 15, according to RAM watch, though this would be displayed as 5 in game. Another use is, as demonstrated in my little test, to simply walk through whatever MAGI-required door we wish, but picking up any MAGI might well trap us when that counter is reset to zero. If an item drop can overwrite this counter while it's glitched at 255, we can protect ourselves from this danger of being locked out, if it turns out we need to do it. One question I have: Is it possible to trigger the glitch any earlier? Probably not; You need 29 MAGI before you can start using the trashcan (All items with IDs 1~28 are various weapons and shields, none of which I think are usable outside of battle; 29 is the Cure potion). By miracle of timing, we can defeat Dunatis to get our 29th MAGI. Get our Teleport on a Mutant. Then dragon races immediately and glitch it. Another question I have: Are there any earlier plans I'm unaware of that already took this into account? If not, then how much would this affect the route? Yep, I'm just playing through the game normally, enjoying all the brokenness I'm causing to it. I may as well report my findings while I'm relaxing with the game I should have enjoyed years ago.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I'm no good at anagrams... Currently trying to get ideas on what sort of RNG to look for. This one seems alright, seeing as I get GAZE, Mana+5, P-BLAST, and TELEPOR, and I have 8 shots total from GAZE and P-BLAST to work with. All I need is to get rid of a chunk of that manipulation time. I wanted to see if the RNGs can work out before I clean up the messy manipulation. But I like this set of RNGs, mainly due to the fact I can move my main character once and still nail all three wanted abilities. I like the letters A, R, S, T, because we can spell RATS. As well as STAR, ARTS, ... Uh, you know. I'm never good at anagrams! And in hindsight, perhaps the main character shouldn't be R... ... I might get stuck on names, of all things...
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I spot a duplicate topic. Well, another one for the same game, anyway. More importantly, I've decided to look around a little for useful memory addresses. Just a glance, but 64 bytes starting from address 0xC0A0 look suspiciously like where the RNG stuff is placed. Also... 1) If running away was perfect, it's this fast. (Hacked a favorable RNG) 2) Fastest we can "dodge" an encounter by reset. 3) Going into battle just to manipulate the RNG by failing to run. The first case is fastest, but we need the right RNG, of course. The second case is slightly slower, but if we need to keep the RNGs for other things untouched, such as what enemy shows up next, this is definitely what we want. The third case increments a bunch of RNGs quickly while still resetting out of the battle. Slow, but theoretically would allow a different outcome for future bosses, or re-allow the faster run away. You can adjust the frame we reset on to change the number of RNG increments. Just popping in while taking a break from The Final Fantasy Legend. I felt like picking through this game a little while letting my head cool down from the planning I did for FFL1. I have practically no familiarity with FFL2. I have no plans for running FFL2, but maybe I'll try if I still have some sort of momentum after finishing FFL1.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
0xC30B              0xC36F              0xC343
  0x51 (GAZE)         0x5F (3)            0x59 (G)      Common
  0x51 (GAZE)         0x5F (3)            0x58 (F)      Rare
  0x51 (GAZE)         0x60 (2)            0x59 (G)      Rare

  0xF1 (P-BLAST)      0xFF (1)            0xF9 (GD)     Common
  0xF1 (P-BLAST)      0xFF (1)            0xF8 (CG)     Rare
  0xF1 (P-BLAST)      0x00 (2)            0xF9 (GD)     Rare

  0xF2 (P-BLAST)      0x00 (2)            0xFA (DG)     Common
  0xF2 (P-BLAST)      0x00 (2)            0xF9 (GD)     Rare
  0xF2 (P-BLAST)      0x01 (3)            0xFA (DG)     Rare

  0x58 (TELEPOR)      0x66 (1)            0x60 (FGG)    Common
  0x58 (TELEPOR)      0x66 (1)            0x5F (GFG)    Rare
  0x58 (TELEPOR)      0x67 (3)            0x60 (FGG)    Rare

  0x59 (TELEPOR)      0x67 (3)            0x61 (GGG)    Common
  0x59 (TELEPOR)      0x67 (3)            0x60 (FGG)    Rare
  0x59 (TELEPOR)      0x68 (3)            0x61 (GGG)    Rare

  0xE9 (TELEPOR)      0xF7 (1)            0xF1 (FGG)    Common
  0xE9 (TELEPOR)      0xF7 (1)            0xF0 (EFG)    Rare
  0xE9 (TELEPOR)      0xF8 (3)            0xF1 (FGG)    Rare

  0xEA (TELEPOR)      0xF8 (3)            0xF2 (GGF)    Common
  0xEA (TELEPOR)      0xF8 (3)            0xF1 (FGG)    Rare
  0xEA (TELEPOR)      0xF9 (1)            0xF2 (GGF)    Rare

  0xEB (TELEPOR)      0xF9 (1)            0xF3 (GFG)    Common
  0xEB (TELEPOR)      0xF9 (1)            0xF2 (GGF)    Rare
  0xEB (TELEPOR)      0xFA (4)            0xF3 (GFG)    Rare
This needs a little explaining, eh? The first column is about address C30B and its values. We would pick one of these values for one of these abilities. While C34B itself determines the abilities, it's always a fixed value away from C30B, so I can choose one or the other to represent this column, but I picked C30B. The second column is about C36F, which indicates what slot in our abilities list the desired ability will occupy. We get a little variance, but it doesn't appear to be a lot, however. It's still important to note that, while rare, it is possible to get GAZE in slot 2, P-BLAST in slot 3, and TELEPOR in slot 4. The third column is about C343. This dictates what encounters we meet up with. I indicate them as a string of letters. Since we'll be fighting one battle for GAZE, there's only one letter. We need two battles for P-BLAST, so there's two letters. We'll use three battles plus the P-FROG battle for TELEPOR, so I use three letters for the TELEPOR possibilities. Finally, the letters themselves refer to the encounter group we'll face, as follows:
W1 OpenLand    Forest       Bandit Cave
A: REDBULL     LIZARD       FLY     +SKELETON
B: SKELETON    REDBULL      LIZARD
C: ASIGARU     SKELETON     REDBULL
D: ALBATROS    ASIGARU      SKELETON
E: ZOMBIE      ALBATROS     ASIGARU
F: GOBLIN      ZOMBIE       ALBATROS
G: LIZARD      GOBLIN       ZOMBIE
Encountering a ZOMBIE is hazardous to our plans. Encountering a LIZARD before we get GAZE is also going to kill our run. To further add to all this, here's how the first three battles after a reset will play out: 1) Party1 acts, enemy hits Party1, everyone else acts 2) Party1 acts, enemy hits Party2, everyone else acts 3) Enemy hits Party2, everyone else acts If there's a way to manipulate this, without anything more than our starting SABER and the accompanying allies' HAMMERs and RAPIERs, I wish to hear of it. EDIT: Things happen differently from what I expect. Turn order is affected by something, could be Agl., but my main did attack first in the first battle when I placed her in slot 4. This does stuff to my plans. The following seems... Less solid. I'll shrink it down... Eh. In order to get GAZE on our starter, we must put her in slot 4. Enemy is guaranteed to hit our fodder once. In order to get P-BLAST, our starter must be in slot 3 (F2) or slot 4 (F1). Regardless of the choice, there's also a conveniently placed Mana+5 in the same respective slots for the first battle, so we're highly encouraged to sort our starter there first thing. The enemy is guaranteed to hit our fodder twice this way. Considering how flimsy our fodder is, we can only spare three hits on them before we start losing them. Getting GAZE and P-BLAST (and the Mana+5) will eat up all 3 spare hits we got. On the way to TELEPOR, there aren't any exciting bonuses along the way. We can put the GAZE & P-BLAST starter in slot 1 for the first two battles to one-shot the enemy before they do any attacks, and soak up a hit in slot 2 in the third battle. This won't work for the EB TELEPOR, thanks to the fact we're forced into learning the useless ARMOR at battle 1, most likely replacing a previously gained ability. Finally, there's the encounters themselves. Fighting GOBLIN, ASIGARU, or ALBATROS are all good, with their 20 HP. LIZARD, not so much, with 40 HP, but we can GAZE them dead once we get that. ZOMBIE is the real killer here, with 60 HP and immunity to GAZE. The ZOMBIE shouldn't be any trouble when getting GAZE or P-BLAST, since either we pick the OpenLand or Forest at will for GAZE, or the whole lack of encounter F in the forest for P-BLAST. The real trouble starts when we look at TELEPOR: The first two encounters will likely have us in the Forest, where encounter F kills our run with a ZOMBIE. As for the third encounter, there's a patch of OpenLand just prior to entering the Bandit Cave. Both F and G are fine at that point. If we actually enter the cave, G kills our run with a ZOMBIE encounter. Not good. Thanks to the long stretch of no-encounter steps following battle 3 of any of the 5 TELEPOR, it's possible to encounter something on OpenLand and go straight to the P-FROG without intervening battles. This is fine, since we want to reduce encounters in the long run. All this assumes that manipulating these abilities doesn't cost us a whole lot of manipulation time. I am quite aware that manipulation is costly, both in trying to TAS it up and in realtime as well. To the extent of my knowledge, the only viable time to be manipulating for abilities is right at the start, where we can freely have four mutants in our party to scroll through the bonuses much faster to get things like TELEPOR before P-FROG. GAZE is instant-win against P-FROG. we shouldn't need much in stats to win, hopefully. It's also instant-win versus KINGSWRD. Either that, or manipulate piles of Mana before either battle (P-BLAST), and I feel that would be a tad inconvenient. In effect, my plans are something like: - "Waste" around 6 steps going towards the Cave before resetting. - Manipulate for GAZE - Manipulate for P-BLAST - Manipulate for TELEPOR - Dust off World I with rampant abuse of our gained abilities RNG, be kind, please... Around 35 steps for GAZE, 8 for P-BLAST, and roughly 64 or 58 for 3 battles leading to TELEPOR (158 or 137 for the fourth battle). I haven't checked the steps until encounter closely.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Bobo the King wrote:
What I like about STONE is that it allows us to hedge our bets-- between STONE and SAW, one of the two is quite likely to connect.
Actually, it seems more like with a rather static RNG, that if we simply have a high enough chance, then we can always hit on the first shot. Otherwise, we always miss on the first shot (unless we fight another battle without a reset in between). Other actions that take place beforehand may adjust the chance. Whatever the case, if none of the right RNGs are pulled from any previous action since the last reset, then in order to connect with STONE, our Mana needs to be at least (enemy Mana) - 4. Any less, and insta-wins don't happen first thing after a reset. Anything less than 96 Mana on the final boss rush is practically suicide, since we can't get our STONE to work first thing. SAW seems to want around 75 Str. to hit right away, which if you only manipulate Strength from required battles at that point, will only happen around CREATOR.
Bobo the King wrote:
I don't think a monster would be worthwhile, since you'd have to fight more than three battles to pump it up. Compare three extra battles versus three turns fighting SEI-RYU and it's pretty clear he wouldn't save enough time.
Who says we must fight extra battles? While manipulating our mutants, it's possible we can pick up the right meats in the meantime. On the other hand, if we go 4 mutants first thing, we probably won't get the chance to get a BEETLE by SEI-RYU. Okay, so no SAW for SEI-RYU. That pretty much leaves a stack of HP as the last use of a monster, for use in one battle against three different monsters. To get a stack of HP, we could just bring a monster to SEI-RYU, forget eating anything but SEI-RYU (Since we aim for 0 meats up until SEI-RYU, this is zero manipulation needed), and get an instant pile of HP to use. Only useful in that one battle against 3 different monsters, though...
Bobo the King wrote:
Gorgeous luck manipulation on the roving monster in the Underwater Castle!
Heh, if we're aiming for fastest time, I thought I should see if I can manipulate the darn thing around. Seems I can, reasonably well.
Bobo the King wrote:
Once again, you've shamed me by demonstrating you can fly around the Hidden Town in World 3. Now why didn't I think of that?
There is also something I didn't check. One can go pretty far south in that hidden town. If there's anything silly we can find down there, like game-breaking glitches, then yay. Addresses CCC8 and CCC9 are your coordinates, in case you haven't tracked them.
Bobo the King wrote:
Are you sure it's faster to walk to the skyscraper rather than take the bike? It looks faster, but I'd just like to check that you tested it.
I didn't bother testing. I only counted the steps and made rough estimates. Each step is 16 frames, and each tile we bike on takes 8 frames, not counting the fact we increment the encounters all the while. Biking the way, at a glance, didn't make up for the trip to the bike, but we could look at this closer anyway.
Bobo the King wrote:
I noticed that you TELEPORted from So-Cho's grave. Did you get different results from me?
I didn't bother testing. I felt that our plans wouldn't be greatly affected before or after this point, so I thought I can always check later.
Bobo the King wrote:
I believe the fastest way to avoid battles is to luck manipulate out of them. Starting near C323 = 161, there's a nice, long pocket where the RNG won't cause any random battles (under most conditions) until it reaches 255. If we can manipulate luck so that the RNG is anywhere near there, it will be even faster than running.
It may take several frames to get the right point in the reset. Plus, there are several points where the encounter rate is higher (especially the "invincible" SU-ZAKU's encounter rate of 64 without the bike), but resets for the right RNG is usually a good idea.
Bobo the King wrote:
Finally, I have what is by far my most important contribution: naming. [...]
Nothing in particular comes to my mind, other than the letter I. "I won!!" I know that leaving our characters nameless is the fastest option, but this hurts the entertainment by never letting anyone know who's who. Single letter names will identify who's doing everything, and we can select a set of entertaining letters. Don't forget, we may end up having more than four characters total, thanks to the fact we may end up replacing dead bodies a few times. This gives opportunities for new letters to debut in our run!
Bobo the King wrote:
I'm not sure, but I think we might be ready to start planning for the real run. I don't know if a new test run would bring any new information, so it may be time to hammer out the details of the real thing.
Indeed, we should work out the details. I will start looking over the details we got. Give me a day or two and I'll work out a plan. Might end up being monsterless, even.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Microstorage seems to be down for the moment, so just take my word that I completed the test run with a time less than 40 minutes on the run. EDIT: Look! It's up! ASHURA was trouble. I found a way to win with SAW, but it involved re-ordering my party, equipping a BATTLE sword (0 damage! Yes!), and sacrificing my monster (800 damage against my 600 HP monster. One shot, one kill). But I managed to win in two rounds when SAW finally kicks in. GEN-BU2 went without a fuss -- SAW worked instantly after the mess known as ASHURA, mainly because I didn't need to reset between the battles. SEI-RYU2, BYAK-KO2, and SU-ZAKU2 looks more like fine pieces of art, what with the STONE spell being abused, and their curious lack of resistance to the Instant Art kit. CREATOR went down easily enough from SAW. I've taken the time to manipulate Strength gains for the MUTANT M from the previous boss battles, probably kicking the chances over the needed threshold for the first shot to connect. Basically, this run sacrificed 2 mutants, 2 humans, and 1 monster while winning with 2 mutants still alive (one's at 1 HP). Clearly, an optimal party is one that goes over the usual limit of 4 characters. In any case, it seems that an optimal party will get shuffled around a lot. The initial run through World I will likely consist of 4 mutants. 3 should mysteriously die along the way right after the remaining survivor gets the needed abilities. Prior to moving to World II, we're going to need at least one bodyguard, probably two. If the battles are going to be stuck with the same sequence of RNGs, we're going to lose someone at SEI-RYU, and the second battle in World III can't be cleared in one P-BLAST (maybe a monster bodyguard, the DRAGON 1 had nice HP). One more trip to the guild in World IV, as seen in my run (assuming someone can access it), would get us a MUTANT M who begins with 54 Strength. Since the MUTANT F we begin as starts with 4, this saves around 10 battles worth of Strength manipulation, since we'd hand the SAW to this MUTANT M instead, and the detour to the guild should save lots more time than 10 battles. Now that I have a nice beginning-to-end test run of my own, I will take a close look at just how much Mana I can avoid getting. Any battles I can shave off should only help us speed through better. I'll also take a look at the four forced battles to see what RNG values gives us the smallest number of monsters in the four forced battles where the numbers are randomized. Less "monster is dead" messages might be helpful. Address C353 will be getting a close look... And finally, SEI-RYU... That thing is still a wall. Max-damage P-BLASTs kill in 3 rounds, immune to GAZE (death), no book of STONE, and GAZE (stone) is impossible to pick up, thanks to the faulty RNG. We can get a BEETLE and attempt to SAW SEI-RYU like in my first test run, but now we have to manipulate the right monsters to drop their meat for us. But this means we won't need to manipulate like 90 Mana for high-damage P-BLASTs at SEI-RYU. We'll still need around 99 Mana at the boss rush after World IV, but if we get past SEI-RYU, we can manipulate for Mana in a longer time span. ... If there's any good battles along the way that doesn't waste too much time. Reducing the number of resets and battle encounters seems to be a key point in speeding up this run.
Post subject: Multitrack script for VBA. It... Uh, works... (16 KB code)
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
By the miracle of input.get, I got this thing working for VBA. ... Somehow, emu.registerafter allows instant reaction whereas other registers and boundary fails. Even emu.registerbefore fails. Additionally, the act of basing a decision for joypad.set using a value modified by joypad.get, directly or otherwise, forces a one-frame delay, killing sync-stability on stateload. I must admit, this is a very confusing lua set-up. There are problems (I can't update the display on stateloads; it does not pick up input from a movie on playback; joypad settings from the emulator is ignored), but at least there's basic multitrack functionality.
-- Multitrack for VBA by FatRatKnight
-- Using joypad.get ruins things, but input.get saves the day. ... HOW!?

local GBA= false

local btn, key, Xoff, Yoff
if GBA then
    btn={"left","up","right","down","A","B","L","R","start","select"}
    key={"left","up","right","down","K","J","H","L","I"    ,"U"     }
    Xoff= 170
    Yoff= 150  --Whoops, I didn't check a GBA ROM. These numbers need adjusting
else
    btn={"left","up","right","down","A","B","start","select"}
    key={"left","up","right","down","K","J","I"    ,"U"     }
    Xoff= 158
    Yoff= 138
end

-- Try to avoid changing btn. You may reorder btn's stuff if you don't
-- like the default order, however.
-- key is your only control into the script. This will override the joypad
-- settings in the emulator. Change that to fit your needs.

--Display
local ListSwitch=   "end"    -- Should the script use or ignore its own list?

local solid= "pageup"      -- Make the display less
local clear= "pagedown"    -- or more transparant.

local DispN= "numpad8"
local DispS= "numpad2"     -- For moving the
local DispE= "numpad6"     -- display around.
local DispW= "numpad4"

local MoreFutr= "numpad3"
local LessFutr= "numpad1"  -- These will determine
local MorePast= "numpad7"  -- how many frames you
local LessPast= "numpad9"  -- want to display.
local ResetFP=  "numpad5"


--Various colors I'm using. If you wish to bother, go ahead.
local shade= 0x00000080
local white= "#FFFFFFFF"
local red=   "#FF0000FF"
local green= 0x00FF00FF
local blue=  0x0040FFFF
local orange="#FFFF00FF"
local fadeRd="#FFC0C0FF"
local fadeGn="#C0FFC0FF"
--*****************************************************************************
--Please do not change the following, unless you plan to change the code:

local fc= movie.framecount()

local InputList= {}
local OptionUseList= true
local keys, lastkeys= {}, {}


--*****************************************************************************
function FBoxOld(x1, y1, x2, y2, color)
--*****************************************************************************
-- Gets around Snes9x's problem of double-painting the corners.
-- The double-paint is visible with non-opaque drawing.
-- It acts like the old-style border-only box.
-- Slightly messes up when x2 or y2 are less than their counterparts.

    if     (x1 == x2) and (y1 == y2) then
        gui.pixel(x1,y1,color)

    elseif (x1 == x2) or  (y1 == y2) then
        gui.line(x1,y1,x2,y2,color)

    else --(x1 ~= x2) and (y1 ~= y2)
        gui.line(x1  ,y1  ,x2-1,y1  ,color) -- top
        gui.line(x2  ,y1  ,x2  ,y2-1,color) -- right
        gui.line(x1+1,y2  ,x2  ,y2  ,color) -- bottom
        gui.line(x1  ,y1+1,x1  ,y2  ,color) -- left
    end
end


--*****************************************************************************
function FakeBox(x1, y1, x2, y2, Fill, Border)
--*****************************************************************************
-- Gets around Snes9x's problem of double-painting the corners.
-- It acts like the new-style fill-and-border box.

if not Border then   Border= Fill   end

    gui.box(x1,y1,x2,y2,Fill,0)
    FBoxOld(x1,y1,x2,y2,Border)
end


--*****************************************************************************
local Draw= {}   --Draw[button]( Left , Top , color )
--*****************************************************************************

function Draw.right(x,y,color)       --    ##
    gui.line(x  ,y  ,x+1,y  ,color)  --      #
    gui.line(x  ,y+2,x+1,y+2,color)  --    ##
    gui.pixel(x+2,y+1,color)
end

function Draw.left(x,y,color)        --     ##
    gui.line(x+1,y  ,x+2,y  ,color)  --    #
    gui.line(x+1,y+2,x+2,y+2,color)  --     ##
    gui.pixel(x  ,y+1,color)
end

function Draw.up(x,y,color)          --     #
    gui.line(x  ,y+1,x  ,y+2,color)  --    # #
    gui.line(x+2,y+1,x+2,y+2,color)  --    # #
    gui.pixel(x+1,y  ,color)
end

function Draw.down(x,y,color)        --    # #
    gui.line(x  ,y  ,x  ,y+1,color)  --    # #
    gui.line(x+2,y  ,x+2,y+1,color)  --     #
    gui.pixel(x+1,y+2,color)
end

function Draw.start(x,y,color)       --     #
    gui.line(x+1,y  ,x+1,y+2,color)  --    ###
    gui.pixel(x  ,y+1,color)         --     #
    gui.pixel(x+2,y+1,color)
end

function Draw.select(x,y,color)      --    ###
    FBoxOld(x  ,y  ,x+2,y+2,color)   --    # #
end                                  --    ###

function Draw.A(x,y,color)           --    ###
    FBoxOld(x  ,y  ,x+2,y+1,color)   --    ###
    gui.pixel(x  ,y+2,color)         --    # #
    gui.pixel(x+2,y+2,color)
end

function Draw.B(x,y,color)           --    # #
    gui.line(x  ,y  ,x  ,y+2,color)  --    ##
    gui.line(x+1,y+1,x+2,y+2,color)  --    # #
    gui.pixel(x+2,y  ,color)
end

function Draw.L(x,y,color)           --    #
   gui.line(x  ,y+2,x+2,y+2,color)   --    #
   gui.line(x  ,y  ,x  ,y+1,color)   --    ###
end

function Draw.R(x,y,color)
   gui.line(x  ,y  ,x  ,y+2,color)   --    ##
   gui.line(x+1,y  ,x+1,y+1,color)   --    ##
   gui.pixel(x+2,y+2,color)          --    # #
end


function Draw.D0(left, top, color)
    gui.line(left  ,top  ,left  ,top+4,color)
    gui.line(left+2,top  ,left+2,top+4,color)
    gui.pixel(left+1,top  ,color)
    gui.pixel(left+1,top+4,color)
end

function Draw.D1(left, top, color)
    gui.line(left  ,top+4,left+2,top+4,color)
    gui.line(left+1,top  ,left+1,top+3,color)
    gui.pixel(left  ,top+1,color)
end

function Draw.D2(left, top, color)
    gui.line(left  ,top  ,left+2,top  ,color)
    gui.line(left  ,top+3,left+2,top+1,color)
    gui.line(left  ,top+4,left+2,top+4,color)
    gui.pixel(left  ,top+2,color)
    gui.pixel(left+2,top+2,color)
end

function Draw.D3(left, top, color)
    gui.line(left  ,top  ,left+1,top  ,color)
    gui.line(left  ,top+2,left+1,top+2,color)
    gui.line(left  ,top+4,left+1,top+4,color)
    gui.line(left+2,top  ,left+2,top+4,color)
end

function Draw.D4(left, top, color)
    gui.line(left  ,top  ,left  ,top+2,color)
    gui.line(left+2,top  ,left+2,top+4,color)
    gui.pixel(left+1,top+2,color)
end

function Draw.D5(left, top, color)
    gui.line(left  ,top  ,left+2,top  ,color)
    gui.line(left  ,top+1,left+2,top+3,color)
    gui.line(left  ,top+4,left+2,top+4,color)
    gui.pixel(left  ,top+2,color)
    gui.pixel(left+2,top+2,color)
end

function Draw.D6(left, top, color)
    gui.line(left  ,top  ,left+2,top  ,color)
    gui.line(left  ,top+1,left  ,top+4,color)
    gui.line(left+2,top+2,left+2,top+4,color)
    gui.pixel(left+1,top+2,color)
    gui.pixel(left+1,top+4,color)
end

function Draw.D7(left, top, color)
    gui.line(left  ,top  ,left+1,top  ,color)
    gui.line(left+2,top  ,left+1,top+4,color)
end

function Draw.D8(left, top, color)
    gui.line(left  ,top  ,left  ,top+4,color)
    gui.line(left+2,top  ,left+2,top+4,color)
    gui.pixel(left+1,top  ,color)
    gui.pixel(left+1,top+2,color)
    gui.pixel(left+1,top+4,color)
end

function Draw.D9(left, top, color)
    gui.line(left  ,top  ,left  ,top+2,color)
    gui.line(left+2,top  ,left+2,top+3,color)
    gui.line(left  ,top+4,left+2,top+4,color)
    gui.pixel(left+1,top  ,color)
    gui.pixel(left+1,top+2,color)
    gui.pixel(left+2,top+3,color)
end


Draw[0],Draw[1],Draw[2],Draw[3],Draw[4]=Draw.D0,Draw.D1,Draw.D2,Draw.D3,Draw.D4
Draw[5],Draw[6],Draw[7],Draw[8],Draw[9]=Draw.D5,Draw.D6,Draw.D7,Draw.D8,Draw.D9
--*****************************************************************************
function DrawNum(right, top, Number, color, bkgnd)
--*****************************************************************************
-- Paints the input number as right-aligned.
-- Returns the x position where it would paint another digit.
-- It only works with integers. Rounds fractions toward zero.

    local Digit= {}
    local Negative= false
    if Number < 0 then
        Number= -Number
        Negative= true
    end

    Number= math.floor(Number)
    if not color then color= "white" end
    if not bkgnd then bkgnd= "clear" end

    local i= 0
    if Number < 1 then
        Digit[1]= 0
        i= 1
    end

    while (Number >= 1) do
        i= i+1
        Digit[i]= Number % 10
        Number= math.floor(Number/10)
    end

    if Negative then  i= i+1  end
    local left= right - i*4
    FakeBox(left+1, top-1, right+1, top+5,bkgnd,bkgnd)

    i= 1
    while Draw[Digit[i]] do
        Draw[Digit[i]](right-2,top,color)
        right= right-4
        i=i+1
    end

    if Negative then
        gui.line(right, top+2,right-2,top+2,color)
        right= right-4
    end
    return right
end


--*****************************************************************************
function limits( value , low , high )  -- Expects numbers
--*****************************************************************************
-- Returns value, low, or high. high is returned if value exceeds high,
-- and low is returned if value is beneath low.

    return math.max(math.min(value,high),low)
end


--*****************************************************************************
function within( value , low , high )  -- Expects numbers
--*****************************************************************************
-- Returns true if value is between low and high. False otherwise.

    return ( value >= low ) and ( value <= high )
end


--*****************************************************************************
function JoyToNum(Joys)  -- Expects a table containing joypad buttons
--*****************************************************************************
-- Returns a number from 0 to 4095, representing button presses.
-- These numbers are the primary storage for this version of this script.

    local joynum= 0

    for i= 1, #btn do
        if Joys[btn[i]] then
            joynum= bit.bor(joynum, bit.lshift(0x1,i))
        end
    end

    return joynum
end

--*****************************************************************************
function ReadJoynum(input, button)  -- Expects... Certain numbers!
--*****************************************************************************
-- Returns true or false. True if the indicated button is pressed
-- according to the input. False otherwise.

    return ( bit.band(input , bit.lshift( 0x1,button )) ~= 0 )
end


--*****************************************************************************
function ShowOnePlayer(x,y,color,button)
--*****************************************************************************
-- Displays an individual button.
-- Helper function for DisplayInput. Called as HighlightButton

    x= x + 4*button - 3
    Draw[btn[button]](x,y,color)
end

local DispX, DispY=  90, 60
local Past, Future= -12, 12
local Opaque= 1
--*****************************************************************************
function DisplayOptions()
--*****************************************************************************
-- Returns true if Opaque is 0, as a signal to don't bother painting.
-- Separated from DisplayInput to make it clear which half is doing what.

-- Change opacity?
    if keys[solid] then Opaque= Opaque + 1/8 end
    if keys[clear] then Opaque= Opaque - 1/8 end
    Opaque= limits(Opaque,0,1)

    gui.opacity(Opaque)
    if Opaque == 0 then  return true  end
    -- Don't bother processing display if there's none to see.

-- How many frames to show?
    if keys[LessFutr] then
        Future= Future-1
        if Future < Past then Past= Future end
    end
    if keys[MoreFutr] then
        Future= Future+1
        if Future > Past+33 then Past= Future-33 end
    end
    if keys[MorePast] then
        Past= Past-1
        if Past < Future-33 then Future= Past+33 end
    end
    if keys[LessPast] then
        Past= Past+1
        if Past > Future then Future= Past end
    end

    if keys[ResetFP] then Past= -12;  Future= 12   end


-- Move the display around?
    if keys[DispS] then DispY= DispY+1 end
    if keys[DispW] then DispX= DispX-1 end
    if keys[DispE] then DispX= DispX+1 end
    if keys[DispN] then DispY= DispY-1 end

    if keys["leftclick"] and lastkeys["leftclick"] then
        DispX= DispX + keys.xmouse - lastkeys.xmouse
        DispY= DispY + keys.ymouse - lastkeys.ymouse
    end

    DispX= limits(DispX,1,Xoff-#btn*4)
    DispY= limits(DispY,3-4*Past,Yoff-4*Future)

    return nil -- Signal to display the input
end


--*****************************************************************************
function DisplayInput()
--*****************************************************************************
-- Paints on the screen the current input stored within the script's list.
-- Rather a shoddy job at loadstate, however.

--Are we showing all players or just one?

--For both setting options and asking if we should bother displaying ourselves
    if DisplayOptions() then  return  end
    local width= #btn*4

--Display frame offsets we're looking at.
    local RtDigit= DispX + width + 22
    if RtDigit > 158 then  RtDigit= DispX - 4  end
    local TpDigit= DispY + 4*Past - 2
    DrawNum(RtDigit,TpDigit,Past,white,shade)

    if Future > Past+1 then
        TpDigit= DispY + 4*Future
        DrawNum(RtDigit,TpDigit,Future,white,shade)
    end

--Show cute little box around current frame
    if Past <= 0 and Future >= 0 then
        FBoxOld(DispX-1,DispY-2,DispX+width+1,DispY+4,green)
    end

--Shade the proper regions efficiently
    if Past < 0 then
        local Y1= DispY + 4*Past -3
        local Y2= DispY - 3
        if Future < -1 then  Y2= DispY + 4*Future +1  end
        FakeBox(DispX,Y1,DispX+width,Y2,shade,shade)
    end
    if Future > 0 then
        local Y1= DispY + 5
        local Y2= DispY + 4*Future+5
        if Past > 1 then  Y1= DispY + 4*Past +1  end
        FakeBox(DispX,Y1,DispX+width,Y2,shade,shade)
    end
    if  Past <= 0  and  Future >= 0  then
        FakeBox(DispX,DispY-1,DispX+width,DispY+3,shade,shade)
    end

--Finally, we get to show the actual buttons!
    for i= Past, Future do
        local Y= DispY + 4*i
        if     i < 0 then  Y=Y-2
        elseif i > 0 then  Y=Y+2 end
        local scanz= InputList[fc+i]
        for button= 1, #btn do

            local color
            if not scanz then
                color= white
            elseif ReadJoynum(scanz,button) then
                color= green
            else
                color= red
            end
            if (not OptionUseList) and i >= 0 then
                if     color == green then color= fadeGn
                elseif color == red   then color= fadeRd end
            end

            ShowOnePlayer(DispX,Y,color,button)
        end
    end
end


local ThisInput= {}
--*****************************************************************************
function MessWithInput()
--*****************************************************************************
-- Good grief, VBA manages to be frustrating me!
-- FCEUX, Snes9x, and DeSmuME didn't fuss like this. But man!

    fc= movie.framecount()-1
    lastkeys= keys
    keys= input.get()

    if movie.mode == "playback" then
        InputList[fc]= JoyToNum(joypad.get(1))
    else
        local temp= InputList[fc]
        for i= 1, #btn do
            ThisInput[btn[i]]= keys[key[i]]
            if OptionUseList and temp and ReadJoynum(temp,i) then
                ThisInput[btn[i]]= not ThisInput[btn[i]]
            end
            if ThisInput[btn[i]] == false  then  ThisInput[btn[i]]= nil  end
        end

        joypad.set(1, ThisInput)
        InputList[fc]= JoyToNum(ThisInput)
    end
    fc= fc+1
end

emu.registerafter(MessWithInput)


--*****************************************************************************
function ItIsYourTurn()
--*****************************************************************************
-- Rather stripped down from FCEUX version. Only has basic functionality.
-- Mainly just there to set options and controls now.

--Sets controller to pick either this script or the player.
    if keys[ListSwitch] then
        OptionUseList= not OptionUseList
    end

    collectgarbage("collect")
end
gui.register(DisplayInput)


emu.pause()
while true do
    ItIsYourTurn()
    emu.frameadvance()
end
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
It's good to know you're still around. When you get the chance, take a look at what I've been doing. I don't have a lot to say at the moment, though. World IV done I'm liking the book of STONE. Although, I'm wondering what to do by the time I hit ASHURA, if the RNG proves its difficulty of being manipulated.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
FatRatKnight made this run possible by creating Multitrack2.lua
Glad to hear that "advertising" my script to you has helped. You were quite literally composing music, and noted that you had difficulty in using TASEdit, so I thought you'd like a different tool to try. You certainly made use of it, and the results... Are here in this submission. And it's a beautiful composition you made. Every stage sounded quite nice, and I found myself wanting to hear the "rest" of the music when it was interrupted by the bosses. Thanks for the listening experience. Now I'm thinking over my script again. Joy.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I re-beat World II. My old time is still faster, but this run has 99 Mana to abuse GAZE, P-BLAST, and book of STONE. As nice as P-BLAST may be, my plans indicate I'll only be using it once more. My plans look kind of like this, right now:
GAZE     P-FROG
GAZE     KINGSWRD
P-BLAST  1-2 SKELETON + 0-2 ASIGARU
Attack!  STEWARD
Skip     GEN-BU

Hrm...   SEI-RYU

GAZE     1-3 MOSQUITO
P-BLAST  1-1 GARLIC   + 1-1 SABERCAT + 1-1 P-WORM
GAZE     1-3 SABERCAT
bSTONE   BYAK-KO

GAZE     1-3 ATOM ANT
GAZE     EVIL EYE
SAW      MACHINE
bSTONE   SU-ZAKU

SAW      ASHURA
SAW      GEN-BU2
bSTONE   SEI-RYU2
bSTONE   BYAK-KO2
bSTONE   SU-ZAKU2
SAW      CREATOR
I'm hoping for more input from Bobo the King right now, but I'll keep thinking more about my plans and see if I can't shave off a few battles (and hope that anything less than 99 Mana doesn't cripple my instant deaths). As for SAW, I plan to recruit a MUTANT M who starts with 54 Strength, which should save on many battles for Strength. I will ignore Agility gains.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
ntclark wrote:
FWIW, I'm really enjoying reading about the planning and watching the WIPs for this run. Can't wait for the final product!
Thanks! Another person waiting in eager anticipation of what we'll do! Among insta-deaths, I've been looking at petrifying the enemies. According to some FAQ on GameFAQs, most bosses are immune to the PARA element, which stops the death gaze, but not the STONE element, which would stop things like the STONE book. Sure, I saw GAZE (stone) in that Mutant Ability list. Problem is, I recall investigating each and every possible RNG value and came up empty for GAZE (stone). Upon further investigation, I can conclude it's completely impossible to even get GAZE (stone), or for that matter, oDAMAGE as well. No amount of soft-resetting will solve this problem. We can pick up a STONE book from a shop in World III. Slightly out of the way, but if it means we can insta-win versus BYAK-KO, SU-ZAKU, SEI-RYU2, BYAK-KO2, and SU-ZAKU2 without the unwieldy SAW, that might actually be worth the detour. With 99 Mana, we'd have a 21% chance to miss a few of these enemies. We shouldn't have trouble hitting. This also means my monster idea is now obsolete, if we prove the STONE book can cover our needs in insta-deaths. All this leaves are fights against multiple groups, SEI-RYU, MACHINE, ASHURA, GEN-BU2, and CREATOR. The SAW is available to insta-kill the latter four, P-BLAST for the multi-groups, leaving SEI-RYU as the one barrier in the way. A monster just doesn't seem like it would work out here, anymore. But before I start crunching down on a new RNG plan based on this book of STONE, I want to try out the spell first and see how it works. EDIT: I have a feeling that one would like to see the results. They're spectacular. Now, is there any doubt about the detour? On a side note, DRAGON armor will stop fire, ice, elec, and poison. It's also available in World III, in a different shop, in case we end up needing some resistance somewhere.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Bobo the King wrote:
Well, I was hoping to have a completed run for you, but I've run into a little snag. The game has lost its mind and won't let me enter the second tower.
Obviously, an NPC stole the game's mind! For whatever reason, it seems that a certain NPC must vanish from the town here before you can enter Tower2. I spoke with this NPC, then entered and left Tower1, so that I reenter the town with the NPC no longer there. Thus, I can enter Tower2. No need to fight GEN-BU!
Bobo the King wrote:
Do you think I should finish off this run? We can just subtract out the frames I spent wandering aimlessly.
We can subtract the "wandering aimlessly" part from the movie itself, now. And of course we should finish it! It will give us some idea on what to shoot for in the final climb.
Bobo the King wrote:
I have some notes on my run anyway and I think I've learned some good lessons here.
And they are all good. This is giving us more and more what to expect, so that we're not tripped at any points. So even with 99 Agility, you don't act first? This implies that Agility isn't used in the turn order algorithm. Just an implication, however, not actual proof. Also good to note that most late-game weapons are useless, other than the E-WHIP. And I've noticed your SAW missed several times even with a Strength just under 70. That thing must be highly inaccurate! And it's nice knowing how useful TELEPOR is. It doesn't seem to have any use in World IV or anything after that. And after World IV, it looks like it will be one big boss rush that involves repeated application of SAW, everything else we have is apparently useless.
Bobo the King wrote:
I have changed my preferred strategy yet again. I now think it's inefficient to load up on stat boosts for just one mutant when they won't be using them simultaneously.
You're either wiping out entire groups or slaying single baddies. Splitting up Agility and Mana into different mutants for this purpose doesn't seem productive in my eyes, since you're not going to use one or the other in many situations anyway. On the other hand, one mutant can only get one stat boost at a time. Two mutants have the potential to boost different stats from the same battle, hopefully a matter of finding the right spots in the RNG. And, of course, there's the fact that you can use both P-BLAST and SABER in the same turns and have both be high-powered. I see a possibility that it can help. A good chance. You're the one that made the near-full test run, your experience should tell you what my theory doesn't.
Bobo the King wrote:
I watched your latest run and I'm encouraged that these little pieces are starting to fall in place. It's good to know we can use TELEPOR early. Once again, your sloppy luck manipulation has bested my run by about 3,000 frames. I'm eager to see if you stay ahead of my pace.
I'm probably going to turn around, talk to that NPC while I'm still there, and pick up two more humanoid body shields- I mean, champions of justice. We'll see how far I get this time...
Bobo the King wrote:
I was just thinking about how you mentioned that you set the text speed to 1. [...]
It may save media time at the ending, or perhaps there's sneaky frames we're not normally aware of saved due to it. It's worth testing (and maybe we can set it without wasting time in an attempt at manipulating luck).