Posts for FatRatKnight

Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Hmm... One thing I failed to mention is simply this: The function must be BELOW where local i is defined. It is above local i, and therefore doesn't see it. It picks a global i and uses that instead. Solution: Move either the function down, or local i up. Either way, this function needs to be below local i or else it won't see it. As for why I didn't originally stick local i up with the rest of the variables... Er, good question... Second, just looking at the original while loops I put in there, once the last subtitle is displayed, it exits the while t do loop and starts running the next loop indefinitely, regardless of state-loads. So loading states after the last subtitle will fail here. Solution: See that while true do loop? Change that to while not t do. Additionally, insert a while true do just before the while t do loop and add an extra end at the end of file. That should help. Never really cared about making it state-load stable before now, as it worked well enough for my needs when creating my subtitles for E.V.O. . But a few fixes here, and things should work out fine for you. EDIT: ... Well then, something happened while I was making my post. Hunh...
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
ObadiahtheSlim wrote:
I couldn't get this to sync. It kept desyncing right when you attacked the guys who split in half. Any ideas why?
That sounds exactly the spot where left+right or up+down is used for the first time. Is that disabled on your emulator? Enable it if possible! It is one of the listed options in my submission text. If that doesn't work, then I'm out of ideas.
klmz wrote:
However, I still wonder whether it can be faster by manipulating more flashing meat when you fought tyrosauruses to get the warted body earlier.
That's a good point. However, the reasons I didn't: - The last two Tyrosaurus' meat comes practically free in terms of time. Before those, I would have to spend a second or two of waiting. - The extra strength after the Tyrosaurus would only be of benefit at the Mammoth Brothers. They have 75 HP each, so 12 Strength would save a total of three hits. About 1 second. - The RNG was uncooperative. Look at how long I delayed at the last Tyrosaurus before the last hit! THAT was for one last flashing meat. Incidentally, I was thinking about increasing my size for Bolbox, to maximize my strength at 18. But I didn't have the EVO.P for it... I'm not sure if it would save more time than it eats up, but manipulating flashing meat from both of the last two Tyrosaurus is a start.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Didn't wait long after I gave my permission, eh? A good start, though. Ah, so you added duration. However, why did you add a j variable? Oh, because things are out of sync with what you did, so you used an extra variable to make up for that. Turning MsgDuration into a table is fine. Though, now looking over my old code prior to your changes, I see a few things I could fix up a little...
function NewMsg(Index)

    MsgTmr= MsgDuration[Index]
    Line[1]= L1[Index]
    Line[2]= L2[Index]
    Line[3]= L3[Index]
    MY= y[Index]
end


function DispMsg()
    if MsgTmr > 0 then
        MsgTmr= MsgTmr - 1
        for n= 1, 3 do
            if Line[n] then
                gui.text(MX,MY+9*(n-1),Line[n])
            end
        end
    end
end



while t[i] do
    if t[i] <= movie.framecount() then
        NewMsg(i)
        i= i+1
    end
    DispMsg()
    snes9x.frameadvance()
end
Just find the proper spot for these to replace older code, get rid of all the j variables, and you'll be on your way. Additionally, defining empty strings are now optional. In any case, it's slightly less messy and a little easier to make future changes if any are needed. I haven't been following any progress here, due to the fact it would involve tracking down the ROM, but seeing these subtitles makes me want to see what's going on now. Perhaps I should add a little something to make it load-state stable... Stick this somewhere before all the text, and hopefully it'll work.
function FindIndex()
    MsgTmr= 0
    i= 1
    while t[i] and (t[i] < movie.framecount()) do
        i= i+1
    end
end

savestate.registerload(FindIndex)
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Priam wrote:
The caption script was helpful [...]
Nightwatch wrote:
I definitely endorse the subtitles, [...]
Nicos wrote:
the subs are more than recomended if this run is published.
zidanax wrote:
Awesome, and I agree that the subs should be in the final encode. [...]
Clearly, there's a lot of positive feedback here. There's not much I need to say here, pointing these out should let you know how I feel.
Nicos wrote:
also, i'm surprised that you didn't upgrade jaws even once in the run as they should add str (if i remember corectly ?) and could have shortened amphibian / fish boses (did the evo animation took too much time ?)
It's actually a combination of reasons. See how fast I knock the bosses around? King Kuraselache has 75 HP, and with 6 Strength, it takes 13 tackles to finish him off. Adding a single point of Strength would allow 11 tackles to do the job, which might save a second, but the evolution time and hunting for EVO.P would swamp out that saving. Note how I reach each early boss with 0 EVO.P, so I would have to hunt for more. Additionally, jaws don't affect Strength at all, unless you're a Mammal. Probably the big reason why I didn't touch the jaws at all.
Nicos wrote:
also too bad you didn't take the dragon form :/
The detour to the dragon... Is simply long. Very long. I didn't see any way that the 30 damage bites and 25 damage horn would make up for that. On the other hand, I didn't actually test it -- I merely checked the length of time to get through the clouds and back for the dragon. It was something like a minute or so detour. Domain of Tyrosaurus takes less than a minute even without the high damage.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Priam wrote:
Yes vote from me (though I do wish you'd put the emulator version number in the description of the movie).
Oh, shoot... That is kind of important. I'll update the submission text! Thanks for letting me know your thoughts, everyone!
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Lua-scripted subtitles. Instructions for viewing: - Copy entire code block into a simple text editor, like Notepad. - Save as filename.lua, though replace "filename" with whatever you want. Be sure to set "Save as type" to "all files". Now bring up your Snes9x emulator, load the right ROM, run the movie, then run the script. Just look in the File pull-down menu for a "Run Lua Script..." option. Words should appear on occasion in the emulator window.
--Subtitles for EVO

local MX= 2  -- If not using latest revision of Snes9x, set to 0
local MY= 2
local MsgDuration= 300
local t, y, L1, L2= {}, {}, {}, {}
local MsgTmr= MsgDuration
local Line= {}
Line[1]=""
Line[2]=""

-- Sets message and resets timer. Can also set y position
function NewMsg(Line1, Line2, yt)  -- y is optional

    MsgTmr= 0
    Line[1]= Line1
    Line[2]= Line2
    if yt then
        MY= yt
    end
end


-- Displays text
function DispMsg()

    if MsgTmr < MsgDuration then
        MsgTmr= MsgTmr + 1
        gui.text(MX,MY  ,Line[1])
        gui.text(MX,MY+9,Line[2])
    end
end

local i= 1
-- Shrinks file size
function S(st,sy,sL1,sL2) --Time, Y-pos, Lines 1&2
  t[i],y[i],L1[i],L2[i]= st,sy,sL1,sL2
  i=i+1
end

--*****************************************************************************
-- Begin text

S(    60, 2,"This run aims for speed"         ,"")
S(   500, 2,"Yes, this intro is unskippable." ,"")
S(  1840, 2,"This run has more evolutions"    ,"than a Pokemon TAS!")
S(  2300, 2,"I'll let you know my stats..."   ,"Stats: str= 1  agi= 4  jump= 1")
S(  2630, 2,"str for damage, agi for speed."  ,"jump affects... Jumps... Joy")

S(  2960,30,"There are other stats."          ,"They're all useless in this TAS.")
S(  3340,30,"The first Jellyfish you come to" ,"will always tell you this stuff.")
S(  3700,30,"Original Dorsal Fin: +1str +1agi","Stats: str= 2  agi= 5  jump= 1")
S(  3990,30,"Also boosts HP. Unimportant in"  ,"this run, so I don't care.")
S(  4300,30,"Jumping is the fastest form of"  ,"travel. Why else would I do it?")

S(  5400,30,"... If I can just avoid going up","for one frame...")
S(  6250,30,"Quick exit due to R button."     ,"")
S(  6870,30,"The cave where much luck is"     ,"manipulated in my favor.")
S(  7430,30,"1/16 chance for each flashy meat","and done rather stylish, too.")
S(  7700,30,"Different enemies have different","chances, however.")

S(  8080,30,"Eel is very fast. Though this"   ,"can randomly pick a slow manta.")
S(  8500,30,"Oh, right. The Eel's stats..."   ,"Stats: str= 3  agi=12  jump= 6")
S(  8890,30,"50 enemies must spawn. This is"  ,"why I swim at this spot.")
S(  9210,30,"Address 7E0766 is useful here."  ,"It is an enemy counter.")
S(  9600, 2,"Time limit for crystal forms"    ,"is 32 seconds (1920 frames)")

S( 10580,30,"Evil RNG... Poor jellyfish takes","a tackle thanks to it...")
S( 10980,30,"And this is why I want the RNG"  ,"to behave: Flashy meat.")
S( 12410,30,"Quick pause to manipulate luck." ,"Blame the evil RNG, man!")
S( 13200,30,"Stuff in the following cave have","1/32 chance of flashing meat")
S( 13600,30,"Tackled here to maintain Eel"    ,"speed for a short while.")

S( 14020,30,"Kuraselache's Tail: +4 agi +4jmp","Stats: str= 2  agi= 9  jump= 5")
S( 14330,30,"More HP, too. But again, HP is"  ,"not imporant in this run.")
S( 14700,30,"Tackle Fin: +3 agi, +2 str"      ,"Stats: str= 4  agi=12  jump= 5")
S( 15260,30,"Kuraselache's Dorsal Fin."       ,"Stats: str= 6  agi=14  jump= 5")
S( 15820,30,"Heads-up! Our heroic fishy will" ,"make silly faces!")

S( 16550,30,"Again, nothing is faster than"   ,"jumps. There's more, trust me.")
S( 17800,30,"Guess who's tackle will win out!","Imagine the perfect snapshot!")
S( 18750,30,"A message would pop up here."    ,"Naturally, it is skipped.")
S( 19800,30,"Oh, crud! I lost my fish stats!" ,"Stats: str= 1  agi= 4  jump= 1")


--Chapter 2
S( 21500, 2,"A few hundred million years"     ,"pass in less than 10 minutes.")
S( 22950,30,"Wazzat?! A Yellow crystal?  It"  ,"summons Dialogue: Time Waster!")
S( 23280, 2,"Detour. It's long, but the time" ,"it saves makes up for it.")
S( 24450,30,"And there's the reason for the"  ,"detour: Green Crystal!")
S( 24950, 2,"Ah, yes... Recall the fish..."   ,"Stats: str= 6  agi=14  jump= 5")

S( 25800,30,"Oh, silly me. I skipped another" ,"dialogue! Impossible w/o fish.")
S( 26600,30,"As a fish, I can't bounce on"    ,"enemies. So I bite instead.")
S( 27000,30,"Bites can stun enemies long"     ,"enough for me to jump away.")
S( 28080, 2,"Alas, it's many, many more jumps","from here on out.")
S( 30000,30,"It's silly how quick this battle","goes.")

S( 31500,30,"I make a short delay here, to"   ,"get rid of fish frames.")
S( 32700,30,"You can't bounce as a fish."     ,"But as an amphibian... Boing!")
S( 33040,30,"Gulping air in order to keep"    ,"bouncing. Maintains fish speed.")
S( 33350,30,"Keril: +4 agility"               ,"Stats: str= 1  agi= 8  jump= 1")
S( 34540, 2,"Those amphibians aren't foes."   ,"They're still good for bounces!")

S( 35500,30,"Look! I'm an amphibian! These"   ,"things are known for jumps!")
S( 36000,30,"10 minutes have passed"          ,"About 25% done with input file!")
S( 36600,30,"Eating stuff delays death."      ,"Still, less stuff to lag with.")
S( 37000,30,"Jumping Dorsal fin: +3s +5a +4j" ,"Stats: str= 4  agi=13  jump= 5")
S( 37400,30,"1/32 chance for flashing meat."  ,"I don't need them all to flash.")

S( 37900,30,"The boss won't show until ALL"   ,"the enemies and meat are gone.")
S( 38750,30,"Spring Tail:+2 str +2 agi +7 jmp","Stats: str= 6  agi=15  jump=12")
S( 39200,30,"Actually, I'm done evolving as"  ,"the Amphibian. No need for food")
S( 41190,30,"Another green crystal..."        ,"I'll make use of it!")
S( 42390,30,"I jump once. Fun how releasing"  ,"control coasts me through.")

S( 44400,30,"Biting Megausu gets him off the" ,"screen sooner.")
S( 45200,30,"Shorter tackles because I let"   ,"Queen Bee off the ground.")
S( 46130,30,"Oh, dear... Not again! NO!"      ,"Stats: str= 1  agi= 4  jump= 1")


--Chapter 3
S( 47900, 2,"I hear this is a bad time to be.","I mean, the meteors and all...")
S( 49050,30,"Ugh... No wimpy dino... Oh, my"  ,"Green Crystal! I'll use it!")
S( 49400,30,"Remember the amphy's stats?"     ,"Stats: str= 6  agi=15  jump=12")
S( 50900,30,"There will be a chain of stages" ,"where I simply jump through...")
S( 51780,30,"Eh? Don't want it? Oh joy! I'll" ,"take it off your hands, then!")

S( 53700,30,"Ah, another new creature to jump","on! Imagine the plot unfolding!")
S( 54700,30,"These yell when attacked. That"  ,"noise can deal damage to you.")
S( 57950,30,"Wait, did I see 'reptile' in"    ,"there? I'm not one, am I? Uh...")
S( 58150,30,"Gah! No reptile! NO! Must use"   ,"my other Green Crystal!")
S( 58550,30,"Seriously, 1 damage a hit?"      ,"6/hit takes a while as is!")

S( 59500,30,"Detour: Going to become a bird." ,"It's freakin' fast, man!")
S( 60700,30,"Sweet! A plot twist! We get to"  ,"jump to the LEFT now! Awesome!")
S( 61700,30,"Note, I never got any EVO.P as"  ,"a Reptile...")
S( 62500,30,"Ah, Mt. Brave. Amphibians like"  ,"me can jump up easily!")
S( 63460,30,"Reptile...?"                     ,"")

S( 63560,30,"Reptile...?  REPTILE!?"          ,"")
S( 63660,30,"Reptile...?  REPTILE!?"          ,"NO! Not that again! So weak!")
S( 63860,30,"I'm... Doomed... No more..."     ,"Bye world... I'm jumping off!")
S( 64180,30,"But wait!! What's that?! Joy!"   ,"I'm a bird! My savior!")
S( 64810, 2,"Bird stats start decent, though.","Stats: str= 1  agi= 9  jump= 4")

S( 65400,30,"But I need a little more stats." ,"One side trip here, and...")
S( 65800,30,"This thing has a 1/128 chance"   ,"to drop flashing meat.")
S( 66200,30,"Pronesaurus Dorsal Fin"          ,"Stats: str= 4  agi=11  jump= 6")
S( 66400,30,"Ptenodons Crest"                 ,"Stats: str= 5  agi=13  jump= 8")
S( 66850, 2,"The detour finally ends..."      ,"We're on our way through now!")

S( 67300,30,"Still smilin'. That meat was"    ,"THAT good, I tell ya!")
S( 68500,30,"Caution: Glitch ahead. I zip,"   ,"causing a mess with the sky.")
S( 69700,30,"Boss battle: Defeat 10 of these" ,"silly things.")
S( 70050,30,"They have a 1/64 chance of"      ,"forking over flashing meat.")
S( 70500,30,"The pre-emptive evolution helps.","5 damage instead of 1!")

S( 70950,30,"Mmm... Luck-manipulated meat..." ,"Part of a balanced diet!")
S( 71350,30,"Longtail birds Tail"             ,"Stats: str=10  agi=20  jump=11")
S( 72000,30,"20 minutes have passed"          ,"I'm just chugging along.")
S( 72500,30,"I hate lag. Avoiding it made it" ,"less epic than my test run.")
S( 74400, 2,"Ominous Green Crystal..."        ,"Floating like it's nothin'...")

S( 75000, 2,"Extreme dodgeball! Looks like"   ,"The Dinos are losing this one!")


--Chapter 4
S( 77400, 2,"This is the coolest chapter!"    ,"... I don't mean figuratively.")
S( 78650,30,"Non-mammals can't walk on ice"   ,"all that well...")
S( 79000,30,"I can always jump! Somehow, air" ,"has more traction than ice.")
S( 79400,30,"Tackles work well, too."         ,"Silly ice...")
S( 79750,30,"This is where you'd become a"    ,"mammal. I'll stay a bird...")

S( 81000,30,"Yes, I need to visit in order"   ,"to continue...")
S( 82300,30,"Now we can jump in a cave!"      ,"All the places we can jump!")
S( 83000,30,"There's actually an alternate"   ,"path. But this one's faster.")
S( 84050, 2,"Wonder how my bird manages with" ,"that cold air...")
S( 84650,30,"Now what did I just say? Now"    ,"it's not cold at all!")

S( 85600,30,"A more impressive zip glitch"    ,"takes place here.")
S( 85940,30,"I have indeed touched the sky."  ,"It's kind of red and stuff.")
S( 87280, 2,"Classic wraparound effect."      ,"I head south to North Pole!")
S( 87700,30,"Must be the off-screen teleport" ,"that I always heard about.")
S( 88650,30,"Another boss battle."            ,"Result is predictable.")

S( 89000,30,"Note how useful those downward"  ,"tackles are. Bird only")
S( 90750, 2,"Okay, this wraparound is silly." ,"Don't think too hard on it.")
S( 91720,30,"Warted Body: +2 strength"        ,"Stats: str=12  agi=20  jump=11")
S( 92100,30,"Notably, flying up this pillar"  ,"lets me get grabbed faster.")
S( 93100,30,"Ah, my favorite scene! Look at"  ,"how I bounce through!")

S( 93900,30,"Bird flight speeds up this place","dramatically. So neat!")
S( 94270,30,"Yes, this is a teleporter maze." ,"It's quick enough, anyway.")
S( 94800,30,"Here's why Birdy speeds things:" ,"Going up. Yay for flight!")
S( 96400,30,"I take my time eating these."    ,"I must wait a fixed time!")
S( 97200, 2,"Dramatic escape sequence! ...Oh?","I'm already out?! Yay!")

S( 98000,30,"There would be this ice barrier.","A boom miles away took it out.")
S( 99100,30,"This tackle sequence is used to" ,"prevent me from taking damage")
S(100600,30,"You can tell she's female by the","teal eye shadow she wears.")
S(101100,30,"Same attack pattern to avoid"    ,"the same sort of damage.")
S(101700,30,"That time I needed to eat quick" ,"to trigger the next scene.")

S(102500,30,"Oh? About that 3800 EVO.P?"      ,"You'll find out later.")


--Chapter 5
S(104600, 2,"Never thought history would be"  ,"anything like this.")
S(105800,30,"My goodness! We're jumping to"   ,"the left again! Madness!")
S(106850,30,"You can become human. It is"     ,"disappointingly weak...")
S(107165,30,"Human form is only for mammals." ,"Like I care for this run...")
S(107670,30,"Water causes evolution. I fly"   ,"to avoid that mess.")

S(108000, 2,"30 minutes have passed"          ,"Are we there yet? NO!")
S(108700,30,"Rather conveniently placed"      ,"foe, would you say?")
S(109400,30,"Odd, but the Y button allows me" ,"to bounce off them...")
S(111850,30,"I tried. I really did. I just"   ,"can't manipulate them...")
S(114150,30,"Dialogue skip! No monkey shall"  ,"tell me to use elevators!")

S(114550,30,"Yes, repeated tackles is faster" ,"than straight flying...")
S(114870,30,"But only at a high enough"       ,"agility.")
S(115350,30,"This boss has an unusually short","stun time. Tough thing...")
S(115680,30,"However, short stun times are"   ,"good things for a TASer!")
S(116800,30,"If you think about it, this"     ,"place is insane...")

S(117400,30,"First, we have a bird underwater","")
S(118100,30,"And quite suddenly, there's ice.","")
S(118600,30,"And a fish riding another fish." ,"  With a gun, too.")
S(119100,30,"I manipulate their patrol so my" ,"dashes aren't interrupted.")
S(120500,30,"Then we meet a spell-casting"    ,"boss. Now there's magic?")

S(121600,30,"Top it all off with a throne"    ,"room.")
S(121920,30,"Complete with royalty, curtains,","red carpet... Underwater?")
S(122800,30,"Yeah... Back to the land for me!","I'm outta here!")
S(124000,30,"They talk about that flying fort","over in Chapter 4.")
S(125000,30,"I could use that zip glitch, but","low ceiling made it useless")

S(126050,30,"Alright, Cro-Maine, I'm-a go"    ,"and bury you!!")
S(126500,30,"Well, uh... What do you know?"   ,"I DID bury him! What the hey?")
S(127500,30,"Ah, the final place. You can"    ,"tell from the music.")
S(128100,30,"Elevator glitch. I can jump and" ,"still trigger it.")
S(128420,30,"Generally good for getting a"    ,"better position.")

S(130100,30,"Bolbox... A boss that takes"     ,"forever to die.")
S(131390,30,"Armor Body"                      ,"Stats: str=14  agi=18  jump=11")
S(131630,30,"Horned Helmet"                   ,"Stats: str=16  agi=16  jump= 9")
S(132000,30,"Agility has little meaning now." ,"So, strength all the way!")
S(132650,30,"I can attack Bolbox, but no"     ,"progress 'til minion is dead.")

S(133080,30,"Must eat as well. " ,"enemy won't show!")
S(133550,30,"Just killing time. May as well"  ,"act out while waiting.")
S(134000,30,"My test run used 12 damage hits.","")
S(134600,30,"Ulch... Avoiding lag made this"  ,"dance so much less appealing.")
S(135500,30,"If I hit again before eating,"   ,"Bolbox would recover 80 HP.")

S(137400,30,"That white ball transforms into" ,"a cute harmless amphibian!")
S(137900,30,"Finding actions to entertain"    ,"you during waits ain't easy.")
S(138470,30,"Static noise? Seems it tried to" ,"attack. I didn't let it.")
S(139100,30,"It's nearly over... Just one"    ,"more orb after this one...")
S(140250,30,"Uh, oh... Bolbox's last resort"  ,"is coming! Here it comes!")

S(140625,30,"It's almost here! It's... It is-","")
S(140705,30,"It's almost here! It's... It is-","... A hunk of meat?!")
S(141200,30,"Alas, Bolbox's last ditch effort","to bribe me ends in failure.")
S(144000, 2,"40 minutes have passed"          ,"Enjoying the ending?")

--End text
--*****************************************************************************


i= 1
while t[i] and (t[i] < movie.framecount()) do  i= i+1  end

while t[i] do
    if t[i] <= movie.framecount() then
        NewMsg(L1[i],L2[i],y[i])
        i= i+1
    end
    DispMsg()
    snes9x.frameadvance()
end

local timer= 0
while true do  -- Idle loop. Prevents pre-lua pause state
    DispMsg()  -- To get that last message...
    timer= timer+1
    snes9x.frameadvance()

    if timer >= 72000 then
        gui.text(0,200,"Um, sir... You have an active script...")
    end
    if timer >=216000 then
        gui.text(0,210,"If you want hidden messages, open the darn script!")
    end
end
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Done! I saved a bunch of seconds against the final boss! Slower in the next room due to having 16 Agility instead of 20. Now to figure out the submission text... Again, I'd like to know about these subtitles (updated)! (EDIT: Link removed) Admittedly, I'm not sure if I allowed access to it before, with how it was set up. Uncompressed, the file is 15 KB. One thing I'd like to know is if it's alright to post the whole darn thing and load down the TASVideos server with it.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Hmm... How about a bot that will be a challenge even for a TASer to win against? THAT would be quite the accomplishment, no? A TASer will use frame advance, save states, and any possible errors in the bot itself. Theoretically, a TASer can save and load states repeatedly in order to kill my current bot. Make a single match so the timers don't expire simultaneously, then just abuse the exploit that my bot is simply no good against state saves. And of course, luck manipulation. It's likely possible one can change what cookies will show up, so all one needs to do is read what the game does with the RNG. Okay, this would be tricky... Even trickier would be to find a reason to delay a few frames for a more optimal cookie placement. Something deviously tricky would be, if you can manipulate the enemy's cookies, do so to minimize their ability to match cookies quickly. And of course, planning. Should the bot clear lines as fast as possible? Or maybe get Yoshi cookies and use 'em when luck says so. Something that can beat a TASer who doesn't take decent time optimizing their strats. I shall tell you that I will make an attempt at creating such a bot. I may or may not finish, but it will be attempted anyway. I've thought of a new design I could use which won't leave the bot as vulnerable to save states, and make it easier to change the bot. If I do manage, against all odds, finish the bot, or a decent prototype, I'll let you know.
Post subject: Yoshi's Cookie
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Honestly, I'm not sure if these forums has to be about specifically TASing the game or if I can simply plunk down a lua bot, but in any case, someone (t3h Icy?) on IRC wanted to create a LuaBot for this game. I got interested in creating my own bot due to that, and here's the result: .fm2 of me getting wiped by my own creation. As for the bot itself... Nothing extravagant. The idea is that we find which cookie appears the most, find a line which has the most of them, then move cookies into place. Said idea was mentioned in IRC... No attempt was made at checking to see if lining up those special cookies would end up smacking oneself with a -7 or panic. Also, No attempt was made at making more than one line at once. Could also be cleaned up a bit...
local grid= {{},{},{},{},{}}

local C_Count= {}
local C_Row=    {}
local C_Column= {}
local Ri,Ci,tx,ty,cx,cy,Type,ToX,ToY


--*****
function count()
--*****
-- Everything's fine if it returns false.

-- (re-)initialize arrays
    for i= 1, 5 do
        C_Count[i]= 0
        C_Row[i]= 0
        C_Column[i]= 0
    end
    C_Count[6]= 0

    for x=1,5 do
        for y=1,5 do
            grid[x][y] = memory.readbyte(0x026A + 0x02*x + 0x14*y)/2 -7
            if grid[x][y] > 6  or  grid[x][y] < 1  or  grid[x][y] ~= math.floor(grid[x][y]) then
                return true  -- Error: Unusual value
            end
            C_Count[grid[x][y]]= C_Count[grid[x][y]]+1
        end
    end
    return false
end

--*****
function CursorGoTo(TargetX,TargetY)
--*****
-- Eats 0 to 4 frames to reach destination
    local zx = memory.readbyte(0x03E5); zx = (zx+ 2)/ 2
    local zy = memory.readbyte(0x03E4); zy = (zy+ 2)/ 2
    local up,dn,lf,rt= {},{},{},{}
    up["up"]= true; dn["down"]= true; lf["left"]= true; rt["right"]= true

    zx= (zx-TargetX+2)%5-2  -- range of output is -2 ~ +2
    zy= (zy-TargetY+2)%5-2

    if zy == -2 or zy == 2 then
        if zy == 2 then
            joypad.set(2,up)
            zy= zy-1
        else
            joypad.set(2,dn)
            zy= zy+1
        end
        FCEU.frameadvance()
        if zx == 0 then
            FCEU.frameadvance() -- Idle, holding the button won't help.
        end
    end

    if zx ~= 0 then
        if zx > 0 then
            joypad.set(2,lf)
            zx= zx-1
        else
            joypad.set(2,rt)
            zx= zx+1
        end
        FCEU.frameadvance()
        if zy == 0 and zx ~= 0 then
            FCEU.frameadvance() -- Idle, holding the button won't help.
        end
    end

    if zy ~= 0 then
        if zy > 0 then
            joypad.set(2,up)
        else
            joypad.set(2,dn)
        end
        FCEU.frameadvance()
    end
    if zx ~= 0 then
        if zx > 0 then
            joypad.set(2,lf)
        else
            joypad.set(2,rt)
        end
        FCEU.frameadvance()
    end
end

--*****
function MoveCookie(dir)
--*****
local pad= {}

    pad["A"]= true
    pad[dir]= true
    joypad.set(2,pad)
    for i= 1, 8 do
        FCEU.frameadvance()
    end
end

gui.register(DispCookieVal)
FCEU.pause()
--*****
while true do

    local Dot= 0
    while count() do    -- grid[][] and CookieCount[] are refreshed
        Dot= (Dot+1)%30
        gui.drawbox(10+Dot,10,11+Dot,11,"green")  -- Gogo dancing dot!
        FCEU.frameadvance() -- If something's wrong, do not act.
    end
    gui.drawpixel(0,10,"clear") -- For some reason, the gui "sticks"...

-- Find the greatest cookie count
    Type= 1
    for i= 2, 6 do
        if C_Count[i] > C_Count[Type] then
            Type= i
        end
    end

-- Count up the right cookies in rows/columns
    for x=1,5 do
        for y=1,5 do
            if grid[x][y] == Type then
                C_Row[y]= C_Row[y]+1
                C_Column[x]= C_Column[x]+1
            end
        end
    end

-- Compare rows and columns
    Ri, Ci= 1, 1
    for i=2,5 do
        if C_Row[i] > C_Row[Ri] then
            Ri= i
        end
        if C_Column[i] > C_Column[Ci] then
            Ci= i
        end
    end
    local Var= "Row"
    if C_Column[Ci] > C_Row[Ri] then
        Var= "Column"
    end

-- Find a spot where we need to put a cookie!
    FCEU.frameadvance()
    tx,ty= 0,0
    for i= 1, 5 do
        local x,y= Ci, Ri
        if Var == "Row" then
            x= i
        else
            y= i
        end
        if grid[x][y] ~= Type then
            tx, ty= x, y
            break
        end
    end

   if tx ~= 0 then -- Did not find a target location? Stop now.
-- Find a cookie to move to the spot!
    cx,cy= 0,0
    local SmarTarg= { 0, 1,-1, 2,-2} -- What direction should we scan?
    for x=1, 5 do
        local found= false
        for y=1, 5 do
            local Xx= ((tx+SmarTarg[x]-1)%5)+1
            local Yy= ((ty+SmarTarg[y]-1)%5)+1
            if (Var=="Row" and y==1) or (Var=="Column" and x==1) then
                -- Uh, sir... We're looking at our own target line...
            elseif grid[Xx][Yy] == Type then
                found= true
                cx,cy= Xx,Yy
                break
            end
        end
        if found then break  end
    end

-- Move cursor to target location
    ToX,ToY= 0,0
    if Var == "Row" then
        ToX,ToY= tx,cy
    else
        ToX,ToY= cx,ty
    end
    CursorGoTo(ToX,ToY)

    if Var == "Row" then
        while (tx ~= cx) do
            if (tx-cx+2)%5-2 < 0 then
                MoveCookie("left")
                cx= (cx-2)%5 +1
            else
                MoveCookie("right")
                cx= (cx  )%5 +1
            end
        end
    end
    while (ty ~= cy) do
        if (ty-cy+2)%5-2 < 0 then
            MoveCookie("up")
            cy= (cy-2)%5 +1
        else
            MoveCookie("down")
            cy= (cy  )%5 +1
        end
    end
    while (tx ~= cx) do           -- If it's column, we didn't move x yet
        if (tx-cx+2)%5-2 < 0 then -- If it's row, we're already there
            MoveCookie("left")
            cx= (cx-2)%5 +1
        else
            MoveCookie("right")
            cx= (cx  )%5 +1
        end
    end
   end
end
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Here's some lua-scripted subtitles. EDIT: Link removed. I intended for it to be temporary, (I don't want to abuse my access to the site's bandwidth) and besides, you should have access to the subtitles from the submission's forum topic, if you need it. Also, here's a few frame counts for the moments I pound Bolbox to dispense the next enemy: 131828 - You've seen this, most likely. A big fish. 133138 - Debustega clone 134391 - Silly sword-wielding bird 135620 - Big Profasu. That giant cockroach. One thing I don't like is lag getting in the way of my dancing... Progress feels slower than usual, so I think I should let you know how I'm doing so far.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Genesis Golden Axe: You have a part 2 without the matching part 1. If you did upload a part 1, it's not set up for anyone else to view. Nothing else I can really add. So now we have an Official TASVideos' YouTube account. Should make a few things convenient.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Almost at the end. You can see I've started on the final battle now. Now, how to fill in the fillers entertainingly... Alas, I tried that zipping glitch on that most obvious spot. You know, perilous cliffs below, just before the Entrance to Eden. Full of Tyrasaurus. That place. The glitch worked as expected, but the low ceiling prevents good use out of it. So I don't glitch there. In return, I did find another glitch. You can see I jump on an elevator as I make it go down. Due to giving myself a better position on both elevators I must use, I save a little time. It's also possible to lock yourself in place forever if you jump away from the elevator after sending it down. I'm thinking about subtitles. Probably going to lua script up some. Then there's the submission text as well. I foresee plenty of typing.
 1-*  Final Step to Evolve     108958 -> 105781 start  (-3177)
______________________________ 109231 -> 106056 Finish (-3175)
 2-*  Domain of Sincerous      109923 -> 106749 start  (-3174)
______________________________ 110202 -> 107034 Finish (-3168)
 3-*  Domain of Fish of Prey   110876 -> 107707 start  (-3169)
______________________________ 111151 -> 107963 Finish (-3188)
 4-*  Domain of Sea Otter      111757 -> 108570 start  (-3187)
______________________________ 111936 -> 108748 Finish (-3188)
 5-*  Domain of Alligator      112541 -> 109353 start  (-3188)
______________________________ 112755 -> 109535 Finish (-3220) Odd use of Y button
 6-*  Domain of Grizzly        113398 -> 110178 start  (-3220)
______________________________ 113691 -> 110447 Finish (-3244)
 7-*  Domain Eohip             114335 -> 111092 start  (-3243)
______________________________ 114523 -> 111264 Finish (-3259)
 8-*  Domain of Saber Tiger    115150 -> 111890 start  (-3260)
______________________________ 115320 -> 112066 Finish (-3254)
 9-*  Domain of Condor         115981 -> 112725 start  (-3256)
______________________________ 116116 -> 112861 Finish (-3255)
10-1  Cave of Monkey Human     116790 -> 113535 start  (-3255)
______________________________ 117008 -> 113752 Finish (-3256)
10-2    Monkey buisiness       117289 -> 114033 start  (-3256)
______________________________ 118352 -> 114898 Finish (-3454)
10-3    Returning chimp        118613 -> 115160 start  (-3453) Apply convenient
______________________________ 119530 -> 116072 Finish (-3458) hammer for that pun.
11-1  Final Ocean              120208 -> 116750 start  (-3458)
______________________________ 120521 -> 117118 Finish (-3403) More efficient dive
11-2    A bird underwater...   120806 -> 117403 start  (-3403)
______________________________ 121391 -> 117862 Finish (-3529)
11-3    ...And ice appears...  121701 -> 118172 start  (-3529)
______________________________ 121901 -> 118370 Finish (-3531)
11-4    ...Fish-riding fish?!  122166 -> 118635 start  (-3531) Rounded the corners
______________________________ 123378 -> 119822 Finish (-3556)
11-5    ...Then magic fish...  123663 -> 120107 start  (-3556) Imagine that pillar
______________________________ 125168 -> 121401 Finish (-3767) censors my brutality...
11-6    ...And a throne room.  125449 -> 121682 start  (-3767)
______________________________ 126572 -> 122803 Finish (-3769)
11-1r   Clearly, I'm insane    126852 -> 123082 start  (-3770)
______________________________ 126853 -> 123083 Finish (-3770)
12-*  Domain of Ditryma        127467 -> 123697 start  (-3770)
______________________________ 128024 -> 124250 Finish (-3774)
13-*  Domain of Tyrasaurus     128668 -> 124984 start  (-3774)
______________________________ 128979 -> 125189 Finish (-3790)
14-1  Entrance of Eden         129586 -> 125795 start  (-3791)
______________________________ 130888 -> 127084 Finish (-3804)
14-2    They love mazes. Why?  131185 -> 127381 start  (-3804)
______________________________ 133697 -> 129819 Finish (-3878)
14-3    Final battle.          133974 -> 130096 start  (-3878)
______________________________ 146969 ->        Finish (     )
14-4    If you die here...     147249 ->        start  (     )
______________________________ 147397 ->        Finish (     )
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Chapter 4, v2 Not a lot of new stuff happened. Just skipping dialogue that I should have avoided, a second application of that upward zip glitch, and evolving the Warted Body. That, and I have 3800 EVO.P to use. I plan to use 3500 of them.
 #-#  Place                    Old       New           Change
 1-*  Iced Coast                80801 ->  78682 start  (-2119)
______________________________  80913 ->  78790 Finish (-2123)
 2-1  Cave of Judgement         81537 ->  79414 start  (-2123)
______________________________  81626 ->  79470 Finish (-2156)
 2-2    Eek! Ghosts! Run!       81894 ->  79738 start  (-2156)
______________________________  82493 ->  79755 Finish (-2738) Dialogue skip
 2-1r   Seems pointless, eh?    82760 ->  80023 start  (-2737)
______________________________  82761 ->  80024 Finish (-2737)
 3-1  Cave of Deltadium         83408 ->  80671 start  (-2737)
______________________________  83497 ->  80727 Finish (-2770)
 3-2    This is NOT my home!    83761 ->  80991 start  (-2770)
______________________________  83796 ->  81008 Finish (-2788)
 3-1r   Another quick leave.    84063 ->  81276 start  (-2787)
______________________________  84064 ->  81277 Finish (-2787)
 4-1  Door to Mt. Snow          84670 ->  81883 start  (-2787)
______________________________  84848 ->  82042 Finish (-2806)
 4-2    Entered big mountain    85116 ->  82310 start  (-2806)
______________________________  85344 ->  82530 Finish (-2814)
 4-3    You seem familiar...    85613 ->  82799 start  (-2814)
______________________________  85899 ->  83087 Finish (-2812)
 4-4    One deep cave           86168 ->  83356 start  (-2812)
______________________________  86380 ->  83556 Finish (-2824)
 4-5    Exit of Mt. Snow        86661 ->  83837 start  (-2824)
______________________________  86816 ->  83989 Finish (-2827)
 5-*  Land of Survival          87497 ->  84670 start  (-2827)
______________________________  87850 ->  85015 Finish (-2835)
 6-*  Land of Survival          88467 ->  85632 start  (-2835)
______________________________  88859 ->  86020 Finish (-2839)
 7-*  Domain of Balrium         89572 ->  86733 start  (-2839)
______________________________  89822 ->  86983 Finish (-2839)
 8-*  The North Pole            90594 ->  87755 start  (-2839)
______________________________  90859 ->  88014 Finish (-2845)
 9-*  Domain of Mammoth         91472 ->  88631 start  (-2841)
______________________________  93370 ->  90525 Finish (-2845)
10-*  ?                         94498 ->  91653 start  (-2845)
______________________________  95147 ->  92530 Finish (-2617) Gah! Warts!
11-1  Fort Bird-man             95706 ->  93089 start  (-2617)
______________________________  96304 ->  93651 Finish (-2653)
11-2    Inside Fort             96564 ->  93911 start  (-2653)
______________________________  96935 ->  94250 Finish (-2685)
11-2r   Teleporter maze         97178 ->  94493 start  (-2685)
______________________________  97190 ->  94504 Finish (-2686)
11-2R   Yay for Bird flight!    97432 ->  94747 start  (-2685)
______________________________  97644 ->  94959 Finish (-2685)
11-3    Boss: Weak to Players   97900 ->  95216 start  (-2684)
______________________________  99692 ->  96942 Finish (-2750) +2 Warts of STR!
12-1  Domain of Hynodon        100634 ->  97885 start  (-2749)
______________________________ 100780 ->  98028 Finish (-2752)
12-2    Now that's just cold!  101059 ->  98306 start  (-2752)
______________________________ 106674 -> 103495 Finish (-3179)
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Chapter 3, v2 I stopped this attempt when I found out I didn't deal the last hit before that other attempt. Alright, so I was focusing on things like the Multi-track recording script. I hope you don't mind that as an excuse for why this took a few days.
 #-#  Place                    Old      New          Change
 1-*  Door to Dina Continent   49892 -> 49085 start  (- 807)
______________________________ 51071 -> 50242 Finish (- 829)
 2-*  Domain of Tecodonto      51679 -> 50850 start  (- 829)
______________________________ 51944 -> 51095 Finish (- 849)
 3-*  Domain of Polsaurus      52580 -> 51732 start  (- 848)
______________________________ 52944 -> 52092 Finish (- 852)
 4-*  Domain of Syrocosaurus   53559 -> 52707 start  (- 852)
______________________________ 53830 -> 52976 Finish (- 854)
 5-*  Domain of Brosasaurus    54498 -> 53644 start  (- 854)
______________________________ 54843 -> 53990 Finish (- 853)
 6-*  Domain of Prasauro       55490 -> 54637 start  (- 853)
______________________________ 55726 -> 54872 Finish (- 854)
 7-*  Domain of Segosaurus     56383 -> 55529 start  (- 854)
______________________________ 56604 -> 55751 Finish (- 853)
 8-*  Domain of Prime Frog     57285 -> 56432 start  (- 853)
______________________________ 57859 -> 57005 Finish (- 854)
 8-*r Domain of Prime Frog     58431 -> 57577 start  (- 854)
______________________________ 59864 -> 59175 Finish (- 689)
 9-*  Domain of Tritops        61722 -> 59809 start  (-1913) New route
______________________________ 61969 -> 60056 Finish (-1913)
10-1  Ocean of Plesusaurus     62575 -> 60662 start  (-1913)
______________________________ 62624 -> 60712 Finish (-1912)
10-2    Smallest ocean ever    62915 -> 61002 start  (-1913)
______________________________ 63692 -> 61776 Finish (-1916)
11-1  Mt. Brave                64284 -> 62368 start  (-1916)
______________________________ 64660 -> 62746 Finish (-1914)
11-2    Suicidal leap          64941 -> 63027 start  (-1914)
______________________________ 66406 -> 64467 Finish (-1939)
11-1r   Look! I sprout wings   66683 -> 64744 start  (-1939)
______________________________ 66684 -> 64745 Finish (-1939)
10-1r Ocean of Plesusaurus     = = = -> 65339 start  (= = =) Side path
______________________________ = = = -> 65401 Finish (= = =)
10-2r   Mmm... Fast Food...    = = = -> 65691 start  (= = =) +2000 EVO.P
______________________________ = = = -> 66526 Finish (= = =) Yes, it does help.
12-*  Domain of Pronesaurus    60577 -> 67345 start  (+6768)
______________________________ 60958 -> 67839 Finish (+6881)
13-*  Domain of Omosaurus      67628 -> 68512 start  (+ 884)
______________________________ 68359 -> 69082 Finish (+ 723)
14-*  Domain of Tyrosaurus     68949 -> 69672 start  (+ 723)
______________________________ 75384 -> 73243 Finish (-2141)

EDIT: Changed the end. Slightly faster.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Good to know I'm making decent progress so far. As for credit, I'm not sure exactly who to give it to, right now. You're the one who added it, so I'm crediting you until someone adds in another reason. Had a sort of inspiration to work on the frame insertion and deletion I was thinking about. Never knew just how exhausting working hard on it, insisting I don't stop until I'm done could be. But at least it's coded in now. I'll rest for now... As for the desync I saw, I've tried more stress tests, making sure to set all buttons to "list" and disabling all input for the emulator itself so that the keyboard error won't happen again. However, all tests were successful, even in the more complex patterns. No desyncs spotted. I'm guessing what I saw was user error on my part. Eheh... In any case, the rewind appears to be working perfectly now.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
    rewindCount = math.max(rewindCount + 1,saveMax);
According to this line, we pick rewindCount+1 or saveMax, whichever is higher. Something tells me that you don't want rewindCount to be stuck at the maximum or above said maximum. Something tells me you'd rather keep it somewhere between 0 and max. So, just change the instance of math.max to math.min, and things might look better.
         savestate.load(saveArray[saveCount-1]);
         saveCount = saveCount-1;
         rewindCount = rewindCount-1;
         if saveCount==0 then      
            saveCount = saveMax;
         end;
This block can potentially attempt to load from location 0. You never store anything at 0 later in your code. As it stands, this may load states from 0 ~ saveMax-1, while it may save states to 1 ~ saveMax. Something's off by 1... savestate.load(saveArray[saveCount-1]); . That -1 can go. We don't need that -1. Hopefully, these changes makes it work, instead of almost working. ... Wait, I forgot one last change!
-- Multi-track rerecording for FCEUX
-- To make up for the lack of an internal multi-track rerecording in FCEUX.
-- It may get obsolete when TASEdit comes around.
--FatRatKnight
-- Rewind added by DarkKobold
Cant miss that, can we? EDIT: As for what I think of the rewind... It's very practical here. Do stuff with one player, rewind a bit, then stuff with other player. Heck, even just playing through at normal speed instead of frame-by-frame, it's fun watching your little player dance around forwards and backwards through time without first going into read-only. I like your addition. I've started messing around with the script a bit more, now that I see some activity with it. Mostly just making things work cleaner and look more organized.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Bird was proven to be faster than the dino, in spite of the 2 or so minutes detour. Mainly due to the fact that the bird gets higher stats and a better way to bash things. The flight isn't a huge bonus, but it does allow a better way to tackle, provides a shortcut for me in Fort Birdman, and a few random things that jumping alone can't do. Aside from that, flight is still much slower than jumping.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
adelikat wrote:
Ok, just now getting around to trying this script. [...]
Glad to know you find it useful. Go ahead and include it as part of the package, if you like. By the way, here's your face. How did it get dislodged from your head?! I would prefer a few things cleaned up first, but I don't know what direction to head, so someone else would need to put in a request or some edits. Then again, that's not a good enough reason to restrict this script, especially since restricting it would slow any progress that I would like done to it, extending the length of time that cleanliness reason sticks around. Here's hoping that future multiplayer runs and even a few single-player runs get easier to handle from here on. ... The silence was just starting to get at me. I was very near to asking several questions in order to provoke a response. In fact, I dropped by to do just that, and what do I see? I am quite glad to see a response now.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
juef wrote:
Nice find for the "terrain zipping". What's the criteria for a terrain to qualify as strange enough to zip? And, couldn't abusing that be the cause of the sky's colors?
Playing around with the Wall of Crazy. Note, in the movie, I jump on the platforms around the wall. Note how I can't walk into the wall from the platform. Also note how I bash an enemy to the wall, but the poor critter doesn't go through it. Note how jumping around the wall lets me go through it just fine, and that walking on the low ground lets me around it as well. This kind of wall is the particular kind that lets me zip upwards. Then note that, while dashing into a jump, I bite the air, then enter the wall and hit B inside the wall. Instant zip. And by moving so rapidly upwards in a glitchy fashion, the game fails to load the proper sky graphics. Usually, when landing, you don't go up. Therefore, you see that band of red messy gunk up there. I still don't know all the physics of this wall, but I've got enough of an idea as to what's going on now that I can likely abuse it in later levels. I haven't tried that other wall to the left, but I suspect similar stuff can happen to it. EDIT: Why didn't I try it until after this post anyway? Yes, it does work on that other wall, alright. I only asked that "what happened?!" question in order to point out the strange glitch spot.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Most of Ch3 done, just trying out various routes right now. But... What happened to the sky after 68850?! Awesome! I can now claim that this run abuses programming errors. There is certain terrain that can act as walls when you're standing on the nearby platforms. Apparently, by holding B while in a jump, said terrain start working like walls and sends you zipping straight to the top of the solid barrier. It does provide a more useful height to jump from, thankfully. Alas, there aren't many of these situational walls to take advantage of... If I recall correctly, this is the first of the strange terrain, and there aren't a lot more of them to look forward to. On a side note, the ideas I'm trying are as follows: - Get 2000 EVO.P from that big crawlie. I show this route above. - Get Green Crystal like in the test run and use the Amphibian once more. - Ignore the damage boosts and deal with chopping down 75 HP with 1 Str on the first foe(s). It takes over 1600 frames to snatch up the big crawlie meat, but I come evolved with two of the parts I need. So some of the 1600 has two evolutions built-in, meaning that it would spend less time evolving the remaining parts.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Chapter 2, v2 Sure took me a while to remember this run. Guess I'm back into it.
 #-#  Place                    Old      New          Change
 1-*  Coast of Pange           22984 -> 22690 start  (-294)
______________________________ 23320 -> 23026 Finish (-294)
 2-*  Empty Land               23938 -> 23644 start  (-294)
______________________________ 25178 -> 24880 Finish (-298)
 3-*  Ocean of Pange           25884 -> 25586 start  (-298)
______________________________ 26417 -> 26118 Finish (-299)
 4-*  Land of timid Ikustega   27055 -> 26755 start  (-300)
______________________________ 27369 -> 27075 Finish (-294)
 5-*  Land of bull Ikustega    27993 -> 27700 start  (-293)
______________________________ 28308 -> 28017 Finish (-291)
 6-*  Land of Amphibians       28950 -> 28660 start  (-290)
______________________________ 29346 -> 29052 Finish (-294)
 7-*  Land of Boss Ikustega    29967 -> 29673 start  (-294)
______________________________ 31912 -> 31635 Finish (-277)
 8-*  Domain of Profasu        32908 -> 32631 start  (-277)
______________________________ 33571 -> 33387 Finish (-184) Evolved Keril now
 9-*  Domain of Giant Bee      34194 -> 34010 start  (-184)
______________________________ 34885 -> 34496 Finish (-389)
10-*  Land of Insect           35530 -> 35141 start  (-389)
______________________________ 35973 -> 35578 Finish (-395)
11-1  Cave of King Bee         36549 -> 36155 start  (-394)
______________________________ 37560 -> 37161 Finish (-399)
11-2    Battle w/ King Bee     37822 -> 37423 start  (-399)
______________________________ 39906 -> 39487 Finish (-419)
11-3    Megausu's speech       40175 -> 39756 start  (-419)
______________________________ 40679 -> 40260 Finish (-419)
12-*  Desert of Sand Eater     41319 -> 40899 start  (-420)
______________________________ 41916 -> 41473 Finish (-443)
13-*  Desert of Edosaurus      42701 -> 42259 start  (-442)
______________________________ 43051 -> 42607 Finish (-444)
14-*  Desert of Mosuchop       43683 -> 43239 start  (-444)
______________________________ 43928 -> 43483 Finish (-445)
15-*  Desert Time Trans        44581 -> 44135 start  (-446)
______________________________ 47789 -> 46983 Finish (-806) Didn't evolve horn
Lua scripted subtitles here. Didn't care about making it elegant...
--Subtitles for EVO

if movie.framecount() then -- Please start my movie before starting this...

local tm, t1, t2= {}, {}, {}
local cutoff= 300 -- 5 seconds
local x,y= 0,29

tm[  1], t1[  1], t2[  1]=     60, "This run aims for speed"         ,""
tm[  2], t1[  2], t2[  2]=    500, "Yes, this intro is unskippable." ,""
tm[  3], t1[  3], t2[  3]=   1840, "This run has more evolutions"    ,"than a Pokemon TAS!"
tm[  4], t1[  4], t2[  4]=   2740, "Map screen."                     ,"We'll see more of it later."
tm[  5], t1[  5], t2[  5]=   3340, "The first Jellyfish you come to" ,"will always tell you this stuff."
tm[  6], t1[  6], t2[  6]=   3700, "My first evolution! That D-fin I","got gives +1 str and +1 agi"
tm[  7], t1[  7], t2[  7]=   4200, "Jumping is the fastest form of"  ,"travel. Why else would I do it?"
tm[  8], t1[  8], t2[  8]=   5400, "... If I can just avoid going up","for one frame..."
tm[  9], t1[  9], t2[  9]=   6250, "Quick exit due to R button."     ,""
tm[ 10], t1[ 10], t2[ 10]=   7430, "Decent luck manipulation here."  ,""
tm[ 11], t1[ 11], t2[ 11]=   8000, "Eel is very fast. Though this"   ,"can randomly pick a slow manta."
tm[ 12], t1[ 12], t2[ 12]=   8890, "50 enemies must appear. This is" ,"why I swim at this spot!"
tm[ 13], t1[ 13], t2[ 13]=   9210, "Address 7E0766 is useful here."  ,"It's an enemy counter."
tm[ 14], t1[ 14], t2[ 14]=  10980, "Useful manipulation stuffs."     ,""
tm[ 15], t1[ 15], t2[ 15]=  12410, "Quick pause to manipulate luck." ,"Ouch..."
tm[ 16], t1[ 16], t2[ 16]=  13600, "Tackled here to maintain Eel"    ,"speed for a short while."
tm[ 17], t1[ 17], t2[ 17]=  14020, "Kuras- Tail: +4 agility."        ,"Other stats aren't important."
tm[ 18], t1[ 18], t2[ 18]=  14700, "Tackle Fin: +3 agi, +2 str"      ,"Currently: str=4, agi=12"
tm[ 19], t1[ 19], t2[ 19]=  15260, "Kuras- D-Fin: +2 agi, +2 str"    ,"Currently: str=6, agi=14"
tm[ 20], t1[ 20], t2[ 20]=  15820, "Heads-up! Our heroic fishy will" ,"make silly faces!"
tm[ 21], t1[ 21], t2[ 21]=  17800, "Guess who's tackle will win out!",""
tm[ 22], t1[ 22], t2[ 22]=  18750, "A message would pop up here."    ,"Naturally, it is skipped."
tm[ 23], t1[ 23], t2[ 23]=  19800, "Oh, crud! I lost my fish stats!" ,"... Back to 4 agi... Aw man!"
tm[ 24], t1[ 24], t2[ 24]=  21400, "A few hundred million years"     ,"passed in less than 10 minutes."
tm[ 25], t1[ 25], t2[ 25]=  23280, "I take a detour. Lets me regain" ,"fish stats temporarily."
tm[ 26], t1[ 26], t2[ 26]=  24950, "Yes, the fish will make up for"  ,"all this wait."
tm[ 27], t1[ 27], t2[ 27]=  25800, "Oh, silly me. I skipped another" ,"dialogue! Impossible w/o fish."
tm[ 28], t1[ 28], t2[ 28]=  27000, "Bites are made to stun enemies." ,"That way, I avoid getting hit."
tm[ 29], t1[ 29], t2[ 29]=  30200, "It's silly how quick this battle","goes."
tm[ 30], t1[ 30], t2[ 30]=  31500, "I make a short delay here. To"   ,"get rid of fish frames."
tm[ 31], t1[ 31], t2[ 31]=  32700, "You can't bounce as a fish."     ,"But as an amphibian... Boing!"
tm[ 32], t1[ 32], t2[ 32]=  33040, "Gulping air in order to keep"    ,"bouncing. Maintains fish speed."
tm[ 33], t1[ 33], t2[ 33]=  33400, "Keril: +4 agility"               ,"At 8 agility now. Still slow..."
tm[ 34], t1[ 34], t2[ 34]=  37000, "Jumping D-fin: +5 agi, +3 str"   ,"Currently: str=4, agi=13"
tm[ 35], t1[ 35], t2[ 35]=  37900, "The boss won't show until ALL"   ,"the enemies and meat are gone."
tm[ 36], t1[ 36], t2[ 36]=  38750, "Spring Tail: +2 agi, +2 str"     ,"Currently: str=6, agi=15"
tm[ 37], t1[ 37], t2[ 37]=  39350, "This particular battle is slower","than my test run... Eh..."
tm[ 38], t1[ 38], t2[ 38]=  41190, "Another green crystal... These"  ,"let me revert to an earlier form"
tm[ 39], t1[ 39], t2[ 39]=  44400, "Biting Megausu gets him off the" ,"screen sooner."
tm[ 40], t1[ 40], t2[ 40]=  45200, "Shorter tackles because I let"   ,"Queen Bee off the ground."

local i= 1
while tm[i] < movie.framecount() do
    i= i+1
end

while tm[i] do
    if tm[i] <= movie.framecount() then
        for j= 1, cutoff do
            gui.text(x,y   ,t1[i])
            gui.text(x,y+10,t2[i])
            snes9x.frameadvance()
        end
        i= i+1
    end
    snes9x.frameadvance()
end
end
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Alright, now I'm actually trying my script seriously. No more simple tests that lead nowhere, I'm field testing it on my Salamander run. ... Geez, things are vastly more convenient with this script! But aside from admiring my own silly stuff, on to random tidbits that I saw with my own code... Your usual emulator controls are intact. Your individual player buttons you set up for your emulator will still work. I had never intended any compatibility with player input via standard emulator set-up, but it seems quite compatible anyhow. However, while it can set buttons for my script to pick up, they can't unset the button the script has recorded. If it's important to keep resetting the input, use the "Off" or "You" settings so it stops reading from the script's stored input, and thus allow you to unset a button without script keys, by simply never loading the input from the script. There's quite an interference with "Script", however, as I fear the bug I saw involving setting false instead of nil for joypad.set. The script can pick up input from a movie on playback. I did mention my stress test already, and it was quite successful. Just load my script and let your movie run on read-only, and you'll surely fill up my script's input table. It will fail to record the first frame you activate or reload the script, but after the start-up, it'll record fine, even on a state-load (there are cases where it will fail on a state-load). You can edit stuff in the middle of the movie without killing whatever input you have set up for later, since this script can hold your dear progress. You can catch the last bit of input of your movie to continue the multi-track recording without too much worry. Stuff like that. Though, thinking on this, if you do make an edit to a movie that turns out to be faster, I might want to add a feature to insert or delete frames. Although things like lag or luck might get in the way, insertion or deletion might still be desired. I have made attempts, but am giving up for the time being. The names... The friggin' names... I can't come up with anything better! "Toggle" is highly misleading, but I can't think of anything better than that! I may as well use "Apple", "Sky", "Holy cow!", and "But sir, that's not an option!" for my names. Seriously, what am I to do with names? I. Can't. Name. At all... Please, any suggestions? ... Okay, I made it more dramatic than it really is, but I wanted to get the point across. The controls and display makes sense to me. I designed the darn thing myself, so it should be comfortable with me. I haven't noticed anything seriously wrong on my end. Unfortunately, I have no idea how comfortable it is with anyone else. Again, I want feedback on this. Or modify the script yourself if you want. In fact, any feedback is good. I tend to assume the worst when I get silence. Insults are more welcome than silence, because at least I'd get the idea I'm doing something wrong. I hate insults, sure, but it leaves less room for doubt. In any case, I'm out of ideas. If anyone here thinks I wish to keep "control" over the script, that's not the case. Use it, change it, whatever. As far as I'm concerned, this is the final release from me. I'm not going to make changes until someone tells me to do so. I've done my goal: Multi-track rerecording. I can work on my Salamander run more easily now, and I can't find a reason to go beyond that. I'm not going to add anything more to that, unless again, someone specifically asks. However, I will be around in case anyone needs help breaking down my code. I don't want it to fall into the abyss after putting some effort into it. I believe I know every detail with my script, so I should be able to answer any question, and I want to make sure anyone else can continue where I left off without too much difficulty. By the way, I edited my last post. That's my final script.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Hmm, I adjusted the code a bit. Prototype Mk II is here now. I'll leave the earlier version intact just in case something went horribly wrong in the process. The differences: - Changed input display. It's now a bunch of small boxes. I dropped the text, as I'm not sure where to fit the darn thing. - In addition to that input display, I also let you adjust the opacity on the fly. Page Up and Page Down are the default keys. - Added a few comments, which I hope points out distinct parts of my code. I find it somewhat easier to navigate now. - Removed movie limitation. Now it will run out outside of movies. - The current input frame will no longer smear itself into undefined frames. - Holding down a script keyed input will re-press the button when advancing the frame. Or loading a save state, now that I think about it. I still haven't worked out any issues involving actual input from the player to emulator, rather than input through script buttons. Then again, are there issues about it in the first place? I don't really know even that. I still could do with a little renaming of a few things, too. It's cleaner now, that much is certain, but I still feel more can be done. EDIT: Small update. Basically my attempt at highlighting functions and added the ability to move the input display, albeit slowly. I can't figure out much else I can do, so if you need anything done, you might need to do it yourself, or ask me specifically about some point. I am lost without a direction now. EDIT2: Renamed the button options. Took me this long to realize better names. Added an ability to use the mouse to move the input display. Also put hard limits on where the input display goes. Apparently, ideas are still coming, but slowly. ... Though, what's going on when the movie is on "playback" and you attempt to drag the input display with the mouse? -------- EDIT3: Removed the white blot. Less bytes to transfer this way. Latest is now in the thread-starting post. I'm also keeping a copy of what was once here, just in case. ... Just pretend there was a more-awesome piece of lua scripting here, but not quite as awesome as the latest stuff I put up at the top.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
First, the script needs its own buttons defined from within its script, but you probably know that already. If not... Now you know. Second, for the fact it accepts stuff one frame at a time... That's actually one of its inconveniences that you went and discovered and I didn't. You have to keep pushing the button... Every. Single. Frame. So basically, tap, advance, tap, advance... It works on a tap, not by holding. You're probably well used to holding buttons on frame advance by now, I take it? Since I'm able to detect when you advance a frame, I could make the key act as though it is re-pressed, by clearing the lastkeys table. I probably should see if I can't add in a "hold" or "invert" option in there too, in case you can't hold down that many buttons, and that you need them over multiple frames anyway. Clearly, my options aren't descriptive enough, or is misleading. But I'll try to explain what they do, regardless of the silly names I've given them. "Toggle" will load input stored in the script and allow you, through the script's buttons, to change said input. "You" will throw away the input stored in the script. It will accept your input through the script's buttons. "Script" will load the input that it has stored, but prevent changes from you accidentally pressing the script buttons. "Off" will simply plunk in no input at all for that controller button. Maybe if you want to erase the stored input and let it run for a few seconds... I suggest leaving it on "Toggle" and never change it. Try that for a bit and see how it feels. They really could take a renaming... Any suggestions? One thing my script does, is it catches the input the emulation actually gets and stores it. I don't assume the script itself is perfect at keeping track of the input, and who knows? Maybe you're running the movie on playback or something. I haven't tried the emulation's own input into this, other than playback mode. Basically, you use the actual keys assigned by the emulator, separate from the script. The script should still pick up on it, since it is catching whatever input the emulator itself says it gets. But, as for loading and saving states... You should be able to back up without many problems, but if it was on "You" or "Off" at the time, it won't load the first frame of the state (as well as the later ones, if you advance some frames). The input, thankfully, is still in there, unless you already advanced a frame, but it still can be inconvenient when you have to switch it to "Script" or "Toggle" and reload the state again. ... In theory, anyway. Make that reload a state at least two frames away from the one you want to load, then reload the desired state. It can't detect state-loads if they happen on the same frame. EDIT: Spotting bugs by reading my code now. Apparently, when a frame has yet to be defined, I forget to clear the current input table. As a result, keys just prior to the undefined frames may stick while creating room for the new frames. I intended it to reset after every frame, but it does something different when an undefined frame is coming up. Whoops.
Editor, Experienced Forum User, Published Author, Skilled player (1174)
Joined: 9/27/2008
Posts: 1085
Actually, in theory, this already has the possibility to support infinite players. All you need to do is adjust that little number somewhere in there...
--**********************************************
local players= 2

local selectplayer = "tab"   -- For selecting which player
local recordingtype= "space" -- For selecting how to record
local key = {"right", "left", "down", "up",   "L",      "O",   "J", "K"}
local btn = {"right", "left", "down", "up", "start", "select", "B", "A"}
-- Don't change btn, unless it's to adjust the spacing to keep it neat.
--**********************************************
In fact, everything in between the lines of asterisks, except maybe btn, can be changed if needed. I try to keep most of the stuff that have good reasons to be changed in a convenient spot. Please do try it out for a while, and let me know what should be changed. Having to display the input somewhere in the middle of all the action isn't what I call a wonderful display, as a likely example of what should be changed. I wanted the main thing done, the multi-track rerecording, and well... That much works. You consider it awesome enough to include it as part of the lua package? You may go ahead and include it, once the coding and display is cleaned up, and possibly the controls. I did create it with the intention that it gets used after all. Primarily for myself, since my Salamander run is largely on hold while I worked things out in lua, but hopefully others can enjoy my work as well.