(Link to video)
We follow our hero, Earthworm Jim, as he attempts to foil the evil Psycrows' plan to steal away the beautiful Princess What's-Her-Name
  • Emulator used: BizHawk 1.9.1
  • Aims for fastest time
  • Manipulates luck to save time
  • Takes Damage to save time
  • Abuses programming errors to save time
  • Played on easiest difficulty to avoid unnecesary puppy love rounds

Comments

Jumping from Gens 11b to BizHawk to make this movie was somewhat of a nightmare. I had previously completed this TAS on Gens months prior and importing the movie over, cause an immediate desync. Thankfully, re-doing the entire thing allowed me to find more time saves everywhere, so I see it as a blessing in disguise. As such, the re-record count on the BizHawk file is small. Combined with all the old movies and this one, I am well over 21K re-records

Background on this TAS

I originally started working on a TAS for Jim 2 back in 2013, but quickly lost interest after only finishing the first level, Anything but tangerines. Fast forward 2 years, and I got hit with a sudden drive to complete it and I completed it shortly after. Fast forward again, I get in contact with Athens, a known Jim speedrunner on twitch, and he and Falasion, another user on twitch, and I made new discoveries on both Jim 1 and 2. Later on, I completely re-do my old TAS and brought the time down more with new tricks and optimizations. The jump to Bizhawk allowed us to find more skips and clips, along with more optimizations, and brought down the time even more.

Tricks

Double Jump

When Jim is jumping, if you initiate a snot swing, the game thinks Jim is standing on the floor and sets his value to 0 for a short amount of frames. Pressing jump again, allows you to jump again. Depending on what kind of floor you are standing, timing for getting the double jump has either a tight timing or lenient window

Snot Swing

Initiating a snot swing while jumping, changes Jim's hitbox and allows him to go through certain walls and platforms

Manta Shield

Gives Jim invincibility for a certain amount of time but keeps him in a static position

Pressing B in Flying King

Orders you a large pepperoni pizza

The Whip

Allows you to kill enemies faster than shooting and getting rid of obstacles without stopping

Randomly Jumping

While it seems like I'm just jumping for no reason, if Jim is walking up steps or slopes, he takes longer to get to the top. Jumping up steps or slopes saves frames over just running

Easy/Difficult differences

  • Three rounds of Puppy Love over Five rounds
  • Less damage inflicted, 5% on Easy and 15% on Difficult
  • Pedro requires 12 hits (including hit to start the fight) on Easy and 42 on Difficult
  • If swallowed, Pedro deals 40% of damage on Difficult, 10% on Easy
  • The cheese of the pizza on Flaming Yawn, sinks you quickly on Difficult, it doesn't do this at all on Easy
  • Psycrows' speed on See Jim Run is about half your top speed, he's almost 1/1 to Jim on Difficult

Levels

Anything but Tangerines

The very first thing you see, is Jim snot swinging from a snot trail up above. This is not normally possible as Jim's jump height isn't enough to reach up there. Using a double jump gives you enough height to reach up there. Another double jump is used to skip grabbing a pig to get rid of Bob and Number Four. There is one frame when Jim is falling off while falling from a hanging state, where he can jump, thus allowing a snot swing to save time. At the end of the level, you notice that Jim stops before Bob's fight scene, this is due to what we call, the Bob Despawn. Found by Athens by complete accident, having two squids on screen and shooting at the same time, causes Bob to not spawn when entering his cutscene trigger and ends the level immediately.

Lorenzo's Soil

The soil has weird properties in this game. You can jump through them, ledge grab, land on certain clumps even though it seems like you can't, and can even soft lock you by trapping you in unshootable dirt. With shooting the dirt on the right side of the screen and a well placed jump, you can avoid going down the opening and having to shoot away soil to get back up. Here's our first clip, using the snot swing, allows you to grab onto soil from below and skip going around. On Genesis, it's sometimes faster to mash shoot the dirt to avoid lag from occurring, which is big help during certain sections. Using another double jump, allows us to grab the chip butty faster and doing a snot swing ledge grab, skips shooting soil. The next ledge grab is what we call, the hard jump, due to being very easy to miss. If you jump and try to grab onto the ledge, it doesn't work. You have to be in a falling state for a ledge grab to occur. Another snot swing ledge grab, more double jumping, and we are at Pedro, the boss of this level. This is the hardest thing to do on difficult, due to how much damage Pedro can do and how shooting his larva is a task on it's own

Puppy Love 1

Round 1 always has set patterns, you save time by dropping the flag and the first two puppies. Round 2 is where the randomness begins. Depending on where Jim stands and what he does with the puppies will determine what patterns you get. Taking damage from Peter saves time as opposed to catching all the puppies. The next round is just RNG manipulation to get the best patterns possible.

Villi People / Jim is now a blind salamander

The first thing you see is Jim floating around while waiting for the floating sheep, which we dub granny due to the noise they make when they pop. Manipulating the sheep to follow Jim over to the wall, allows Jim to clip into the wall and skip the entire level. Manipulating the next set of sheep to clip again, allows us to skip the quiz and make our way to the end of the level.

Flying King

Manipulating the balloon to go where you want it go is a lot harder than it looks. At the end of the level, Major Mucus is defeated at a certain frame to give better odds for good puppy patterns on Puppy Love 2

Puppy Love 2

This puppy love is the worst when it comes to manipulation. Everything I do is for a reason, even though it seems like I'm just standing still or diving for nothing

Udderly Abducted

The first thing you notice, is that I do not pick up the cow as intended and go in a completely different path. Doing two double jumps in the section above, where the worm flag is, allows Jim to go past the barrier of the first milking barn, which extends really high up. Doing so, allows Jim to skip collecting all the cows and walk to the end of the level. Because you do not collect the first cow, the game does not load the next cow, which is needed for the barn gate to be lowered.

Inflated Head

If Jim hit any light bulb when his animation is bouncing upwards, he gets an extra boost up. Being on Easy, taking extra damage for boosts is basically the way to go. If you finsih the level without collecting any worms, the game will give you two worms for Hammer Head, thus, it's faster to collect only one worm.

Iso 9000

This level is completely broken. Originally, you have to collect two hamster wheels to power up incinerators so that Jim can go to the next section. Doing a somewhat precise jump, allows Jim to clip into the paper and fall under to the next section. Another jump towards the wall of paper to get somewhat out of bounds, lets Jim fall to the final section and to the exit. Door chase is pretty straight forward, nothing really noteworthy here. Doing a double jump saves you from having to ledge grab to the top platform

Puppy Love 3

This puppy love was a nightmare to manipulate, but nothing like round 2. Dropping puppies and taking a beating from Peter saves time, nothing else to explain

Level Ate

Pretty straight forward level, just get to the end without dying. By whipping the off switch and snot swinging at certain times, lets Jim land on the final grills without needing to turn them off. Shooting and walking over the middle pepperoni, manipulates Flaming Yawn to stay in the middle and come down immediately, instead of attacking first.

See Jim Run, Run Jim Run

The final level, Jim must race Psycrow to the alter to save Princess What's-Her-Name. Jumping after shooting the plasma gun, allows us to pass the fan blades from hitting Jim. One section of fan blades is spinning clockwise, which sends Jim right at a high rate of speed, letting him skip the falling walls or destroy them before they fall down. Because of weird hitboxes, you can jump in and out of the final fan blades without being damaged, using a snot-chute gives Jim enough distance to land on the end of the fan to avoid damage. Using a snot-chute to catch the falling 'J' was the fastest way, by frames, to win the race and once again, Psycrow has been thwarted so hard, he doesn't even make it to the altar to take a plasma shot to the face

Possible Improvements

In Tangerines, if you can somehow get enough height from a double jump, it's theoretically possible to skip the entire level. All three Puppy Loves are improvable if you can get consistent fast starts. Fast starts are when the game lags enough and psycrows feathers come out in a certain way after being hit with the bomb. If this happens, the next round text will show immediately and the next round begins. Every single round, aside from the first, has the possibility of this happening, but we haven't figured out how to make it consistent. If you can somehow despawn the first cow in Udderly or go past the first gate without having the need to go from above, that would save a bit of time.

Level Comparisons

LevelEasyDifficultTime saved in sec/mins
Anything but Tangerines405040520.033
Lorenzo's Soil5048586813.68
Puppy Love 120497282311:55.74
Villi People41644113-0.81
Flying King23392272-1.117
Puppy Love 212091220722:46.38
Udderly Abducted369036930.048
Inflated Head435944251.1
Iso 900021442136-0.13
Puppy Love 312457221402:41.4
Level Ate730673140.132
See Jim Run, Run Jim Run434043600.36

Reasons for time loss

  • Bad granny movement in Villi People
  • Bad movement in Flying King and Iso 9000

Special thanks to

  • Falasion - for helping figure out how stuff works, giving inspiration to the clips on Villi People, and being around in the middle of the night to bounce ideas off of
  • Athens - for figuring out certain strats and accidentally finding the Bob despawn
  • To the rest of the crew on Annelids with Attitude, you know who you are
  • To everyone who supported me while I beat my head against the wall during my TAS streams
I hope you enjoy this run as much as I had while making it.

Suggested Screenshots


Truncated: Guess I'll take this one instead then

Truncated: Easy is definitely the best choice for this game. Good run, accepting for publication.
feos: Yay!

TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 14744
Location: 127.0.0.1
This topic is for the purpose of discussing #4907: YamiAmarillo's Genesis Earthworm Jim 2 in 21:15.06
Player (96)
Joined: 11/2/2010
Posts: 22
Location: Orange, Ca
Now with less Puppy Loves and even faster rounds!
Cat Gets Money
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11245
Location: RU
YamiAmarillo wrote:
Now with less Puppy Loves and even faster rounds!
Could you post time per level comparisons?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11245
Location: RU
Preliminary script. No idea if it will be any useful, but it shows some stuff. REMOVED, SEE BELOW 7a - end of batch 64 - psycrow goes up 63 - psycrow goes down 30, 31 - puppy 03 - randomly jump forward 0e (followed by 08) - randomly jump back 62 - bomb As we can see, it goes back and forth through the config table, using rng for jump offset. There's a fixed number of bombs in the table, so it should be possible to manipulate it to load config address closest to the bomb. Will dump bomb addresses later. Puppy speed that affects the amount of bounces they will take can be (and is) predicted, but I'll look into how it can be affected by randomness, if possible. In any case, if we know what outcome we want to get out of manipulation, it should become easier to succeed and improve.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Player (96)
Joined: 11/2/2010
Posts: 22
Location: Orange, Ca
feos wrote:
Could you post time per level comparisons?
Added time table for time comparisons. I notice now, that I lost small time on three stages, but I'm kinda burned out from TAS'ing. I'll go back at a later date and re-do this run. I'll check the script you made and see if it can help out further for later
Cat Gets Money
Warepire
He/Him
Editor
Joined: 3/2/2010
Posts: 2174
Location: A little to the left of nowhere (Sweden)
Finally, an Earthworm Jim 2 TAS. Well done as well, I was quite entertained. Voted yes.
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11245
Location: RU
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11245
Location: RU
Check this out!!! Download Jim2bizhawk.lua
Language: lua

-- feos, 2015 --== Globals ==-- lastcfg = 0 dcfg = 0 rngcount = 0 rngcolor = "white" rngobject = 0 rngroutine = 0 MsgTime = 16 MsgStep = 256/MsgTime MsgTable = {} --== Shortcuts ==-- local rb = memory.read_u8 local rbs = memory.read_s8 local rw = memory.read_u16_be local rws = memory.read_s16_be local rl = memory.read_u32_be local box = gui.drawBox local text = gui.pixelText local line = gui.drawLine local AND = bit.band local SHIFT= bit.lshift function Configs() local rng = rl(0xa1d4) text(120,0,string.format("rng: %08X:%d",rng,rngcount),rngcolor) local cfg0 = rl(0xfc2a) if cfg0==0 then return end local cfg1 = rl(0xfc9a) text(220,0,string.format("cfg old: %X\ncfg step: %d",cfg1,dcfg)) if lastcfg~=cfg0 then dcfg = cfg0-lastcfg end lastcfg = cfg0 local h = 7 for i=0,20 do local config = rl(0xfc2a)+i local action = rb(config,"MD CART") local newaction = memory.readbyte(config+1,"MD CART") if action==0x62 or (action==0xe and newaction==8) or action==8 or action==3 then color = "red" elseif action>=0x63 and action<=0x64 then color = "orange" elseif action>=0x30 and action<=0x32 then color = 0xff00ff00 elseif action>=0x65 and action<=0x70 then color = 0xff00cc00 elseif action==0x7a then color = "white" else color = 0xffaaaaaa end text(270,i*h+42,string.format("%X:%02X",config,action),color) if i>0 and action==0x7a or action==0x2b or action==0x2d then break end end Bounce() Seek() end function Seek() bytes = 0 waves = 0 steps = 0 local ret = "" for bytes=0,10000 do local cfg = rl(0xfc2a)+bytes local action = rb(cfg, "MD CART") local newaction = rb(cfg+1, "MD CART") if action==0x7a then waves=waves+1 steps=steps+1 end if action==0x63 or action==0x64 or (action==0 and newaction==0) then steps=steps+1 end if action>=0x30 and action<=0x32 then if newaction==0x70 then steps=steps+1 elseif newaction==0x62 then ret = string.format("BOMB in %d waves %d steps",waves,steps,bytes) break end elseif action==3 then ret = string.format("Forth in %d waves %d steps",waves,steps,bytes) break elseif action==0xe and newaction==8 then ret = string.format("Back in %d waves %d steps",waves,steps,bytes) break end end text(120,7,ret) end function Clamp(v1,v2,v3) if v1<v2 then v1=v2 elseif v1>v3 then v1=v3 end return v1 end function Bounce() if rb(0xa515)==0x60 then offset = 8 else offset = 0 end local counter = rb(0xfc87) local a0 = 0xfc88 local d0 = SHIFT(rb(a0+counter),5)+offset local vel = rw(0x25d482+d0, "MD CART") if vel == 0x200 then bounce = 3 elseif vel == 0x3e0 then bounce = 1 else bounce = 2 end text(60,0,string.format("bounce: %X",bounce)) end function Objects() local base0 = 0xa2ea for i=0,0x32 do local base = base0+i*0x6e local id = rb(base) if id>0 and id~=0x82 then local hp = rbs(base+1) local x = rw(base+2)-4096-camx local y = rw(base+4)-4096-camy --x = Clamp(x,0,300) --y = Clamp(y,8,210) local dx = rws(base+0x18) local dy = rws(base+0x1a) local hitboxbase = rl(base+0x14) if hitboxbase<0x300000 then local x1 = rb(hitboxbase+2,"MD CART") local x2 = rb(hitboxbase+4,"MD CART") local y1 = rb(hitboxbase+3,"MD CART") local y2 = rb(hitboxbase+5,"MD CART") local of = 124 if x1>0 and x2>0 and y1>0 and y2>0 then x1 = x1+x-of x2 = x2+x-of y1 = y1+y-of y2 = y2+y-of box(x1,y1,x2,y2,0xff00ff00,0) end end --text(x,y,string.format("%X",id),"yellow") if hp~=0 then text(x,y+6,hp,0xff00ff00) end PostRngRoll(base,x,y) end end end function PostRngRoll(object,x,y) for i = 1, #MsgTable do if (MsgTable[i]) then if object==MsgTable[i].object_ then local color = 0x00ff0000+SHIFT((MsgTable[i].timer_-emu.framecount())*MsgStep,24) line(130,7*i+8,x,y,color) text(120,7*i+8,string.format("%X",MsgTable[i].routine_),color) end if (MsgTable[i].timer_<emu.framecount()) then MsgTable[i] = nil end end end end event.onframestart(function() rngcount = 0 rngcolor = "white" rngobject = 0 end) event.onmemorywrite(function() rngcount = rngcount+1 rngcolor = "red" rngobject = emu.getregister("M68K A1") rngroutine = emu.getregister("M68K A0") for i = 1, 30 do if MsgTable[i] == nil then MsgTable[i] = { timer_ = MsgTime + emu.framecount(), object_ = rngobject-0xff0000, routine_ = rngroutine } break end end end, 0xffa1d4) while true do mult = client.getwindowsize() camx = rw(0xa172) camy = rw(0xa174) Objects() Configs() emu.frameadvance() end
It shows who calls RNG routine and how man times per frame. It tells you when is the next bomb/jump back/jump forward in config table, how many waves and steps are left. It shows the address it jumped from, which it will return to later on, and how long was the last jump, and what direction is was in. So you can apply your manipulation and see how far forward it allowed you to get in the table, which means, how many waves you skipped. Didn't investigate 100% of cases what calls RNG roll, but it's no hard to do, once needed. All in all, you guys can now know what the game is doing. I was going to try this manipulation myself once I finish, but it looks so tedious that I may prefer to delay it until the new version is done.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Player (96)
Joined: 12/12/2013
Posts: 376
Location: Russia
Much more better in my opinion: https://gist.github.com/realmonster/83a7b48c3ad0abd1d17c Warning, script for gens! Also, there is human readable dumps of scripts. All that is random based is rndcall. "Randoms left:" counter shows how many calls to rndcall left. Middle section - main script. Right section subscript, that was called from main script by rndcall. Main script terminated by command stop, but subscript termnated by command ret, and continuing execution in main script. More about commands: save - stores line in script where you restore if you die. text - shows text on screen. inc - increasing timer marked on screen "Timeout:" dec - decreasing timer marked on screen "Timeout:" def - sets value to "Timeout:" p0 p1 p2 - position where next puppy/bonus/bomb will drop puppy, bonus, bomb - drop appropriate thing. Bonus replaced by puppy if "Bonus: no" shown by script clr - makes "Bonus: yes" down - Psycrow moves down up - Psycrow moves up upp - Psycrow moves up but in some different way (idk) smt - set max of "Something:" incs - increase "Something:" idk - interesting thing, it changes chance that throwed bomb by Peter will deflect Psycrow house, and start falling on ground, so you will need to bounce it :D Zero value means never deflect. It set to non zero only in Puppy Love part 3 table - sets table of possible subscripts for rndcall diff jmp - if difficulty equal to first operand, it will jump on address set by second operand. Easy = 0, Normal = 1, Difficult = 2 round jmp - if round < value of first operand, it will jump on address set by second operand end - waiting when all puppies/bonuses are lost/done, so actually end command is awaiting end of wave. wait - like "no operation" but "-" in front of it means that it will wait unitl "Timeout:" reach zero. All commands where "-" in front of it, means that it is waiting when "Timeout:" reach zero. Suffix "x5" means that command is repeated in script 5 times in row. Tables in the end of dump - subscripts chosen by rndcall. For each round there are several of them, appropriate chosen by RNG. Didn't test waves, steps thing made by feos, because I simply don't understand them. Maybe I'm too stupid... Also "next bounces" works kinda awkward to me. You can say about next position by looking for next p0/p1/p2 in script. All timing thing based on timer shown as "Timeout:" Beware, some code increasing current value of it by 1, or even for big values. For example text command increasing current timeout often that current exceeds max (default). This script showing only script behavior. It would be nice if someone would also made investigation about timings in frames of all that stuff. I don't wanna do that, also, I guess it's very hard. -_-
Player (96)
Joined: 11/2/2010
Posts: 22
Location: Orange, Ca
Thanks guys for the lua scripts, I'll put them to good use when I do more testing
Cat Gets Money
Editor, Experienced player, Reviewer (966)
Joined: 4/17/2004
Posts: 3107
Location: Sweden
YamiAmarillo wrote:
Thanks guys for the lua scripts, I'll put them to good use when I do more testing
Is this testing going to happen in the near future (so you'll cancel/update this run) or some time later (so I should judge this run now)?
Player (96)
Joined: 11/2/2010
Posts: 22
Location: Orange, Ca
Truncated wrote:
Is this testing going to happen in the near future (so you'll cancel/update this run) or some time later (so I should judge this run now)?
Testing is not going to happen for a while. I'll do more testing after the new year when I have more free time. So please, go ahead and judge this run
Cat Gets Money
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11245
Location: RU
Regarding improvement, it would look like this: manipulate rng, and make the game branch only to the shortest subscripts. Thankfully there's only a few of them for each round, so all can be tested for how long they last. But in-level possibilities for this manipulation are limited by the amount of puppies one can drop and by places to drop them at. Additionally, rng can be rolled in a previous level during the boss fight and so, making it even more tedious to manipulate far away events. So I'd say it should be left for the new version of this run, and this one just accepted. And then, I'm going to publish it.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Post subject: Movie published
TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 14744
Location: 127.0.0.1
This movie has been published. The posts before this message apply to the submission, and posts after this message apply to the published movie. ---- [3012] Genesis Earthworm Jim 2 by YamiAmarillo in 21:15.06