[Genesis] Lemmings (Genesis Port) TAS (WIP)

Started by Gronkling, January 27, 2016, 04:59:09 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ccexplore

Quote from: Gronkling on January 29, 2016, 01:25:23 PMin fact doing this has removed all 4-cycles in the level

Out of curiosity, did you determine that through spot-checking (or maybe even an exhaustive bunch of framestepping?? :lem-mindblown:), or did you already have some sort of automated tool that can detect exactly where the 4-cycles are in a movie?

I'm thinking that having such a tool would be useful as I fear it may be very difficult to determine the exact conditions of 4-cycles without some sort of detailed understanding of the game hardware and software.  At least then we know exactly how many frames were wasted in a given solution due to 4-cycles; you might not be able to eliminate all of them but it'd give a target to strive towards, as well as yielding a minimum margin of improvement you need to definitively beat an existing solution (ie. if an existing solution has at most N "wasted" frames from 4-cycles and the new solution saves more than that).

I'm tempted to try my hand at creating such a tool, though I doubt I have the time.  I'd also need to explore the memory a little more, to find the right locations to watch in order to determine when the game does a physics update.

Gronkling

#31
I just frame-stepped through the whole thing :P It only took 2-3 minutes though. I have thought of automated tools but I don't know how to go about making one, there should be some good memory watches to find though which is what I'll work on next

EDIT: Well I found something that seems very promising
Value F54D is a counter that goes up by 1 every frame, looping every 3 frames. (1,2,3,1,2,3,1,2,3,...)
Physics updates everytime the value is 2. On a 4-cycle it hangs for 1 frame on 1. (1,1,2,3,1,1,2,3,...)
Freezing this address instantly crashes the game, so it's important.

EDIT2: 2byte value FFD8 is another interesting one, cycling like this (0,4,255,0,4,255,...)
On 4-cycles however it goes like this (0,63826,4,255,0,63826,4,255,...)
This is useful because 63826 is a big and eye-catching number, this value is a lot more unpredictable though.

EDIT3: I redid fun 5 so there's less screen scrolling etc removing 31 frames making the current record 1476F

ccexplore

#32
Ok, I've something ready to help with counting these lag frames.  It uses the LUA scripting feature in Bizhawk and F54D memory watch.  I'm new to this so there are some limits to what can be done with it at the moment.  How to use:

1) save the attached LUA script to the "Lua" subfolder under the main folder of Bizhawk.  (You can save it elsewhere too if you must.)
2) load a movie
3) pause the emulator (ie. pausing the emulation, not the game itself)
4) in the menu bar go to "Tools" -> "Lua Console".  This shows a "Lua Console" popup window.
5) in Lua Console's menu bar, go to  "Script" -> "Open Script...".  Find the script file from step #1, select it and open it.  It should now be listed in the Lua Console with an icon next to it at the left that looks like a "play" triangle, indicating script is active.
6) resume emulator and let the movie play out.  Once it gets to the actual level you'd start seeing a "lag frame counter" displayed near the bottom of the emulator window.

Due to how the script works and how the emulator apparently works, note the following:

A) Whenever a level is loaded and user is at its preview screen (the one that tells you the title, save requirement, etc. of the level you're about to go into and play) , it appears to clear the memory at F54D to 0, a value never seen while actually playing a level.  I catch this condition as an indication to "reset" and hide the lag frame counter.

B) The script starts tracking lag frames and show the counter at the moment F54D first goes from 0 -> 1, which happens shortly after you press START to actually start playing the level.  Fun fact: from testing so far, apparently at the beginning it will always do 0->1, then 1->1, and then finally the regular 1-2-3 cadence.  So apparently there is always a lag frame at the very start.  I'm assuming this is unavoidable so I've adjusted the script to basically ignore that one when reporting the lag frame count.

C) The script is set up to have the emulator call it on each frame update, then it checks and see what happens with F54D.  It can handle the frame counter going up by 1 or down by 1, so normal speed,  turbo speed, and framestepping forward and reverse all works as expected for the lag counter, whether in movie mode or actual play mode.  Anything else that cause the frame counter to change by other amounts will break the tracking.  The script will detect that and report this condition, along with freezing the reported lag count value to the most recent one (until the whole thing is reset again by reloading the level or reloading the script, a la A above).

D) Savestates do not work with this.  It looks like the scripting feature does provide a way to load and save custom data into savestates, which would be required in order for the script to properly handle savestates.  Currently loading a savestate will likely trigger the "stop tracking" behavior mentioned in C.  I'll make another post if I ever get the script updated to work with savestates.

E) It seems that the emulator will disable the script whenever you select another movie to play, or tell it to replay movie from beginning.  You can tell this happened in the Lua Console by seeing the icon next to the script's name changed from a play icon to a red paused icon.  In those cases you'd have to re-open the script in the Lua Console to re-enable it after such actions.  You can do this quickly by going to the Lua Console's menu and do "File" -> "Recent Scripts" and re-pick the script from there, instead of browsing for it all over again.

F) I've tested and found that the script still works when you pause the game (ie. not the emulator itself); F54D's value continues to cycle the same way (and can lag as well if you do scrolling or other such intensive actions) whether game is paused or not.

G) Currently the script lacks a way to detect that you have exited the level.  Once you exit the level, apparently F54D's value will be stuck at whatever value it most recently has, which will confuse the script into thinking it's lagging forever at this point.   So you'll see the lag counter constantly going up alongside the frame counter at that point.  Once you load a new level and go to the preview screen, that will finally reset F54D's value to 0 which will reset everything (as explained in A above).  I'll fix this bug once we figure out what memory we can watch for to determine whether you have exited the level or not.

H) I mentioned in previous post I intend to also output the exact frame counter values for which each lag have occurred.  This is not yet currently done, but the lag counter itself should be enough for now to help you out in this regard, even if it means you may have to framestep forward and backwards to do so.

Anyway, let me know if you have any questions or problems with using this.

================

From my script, the lag counts for the solutions you've uploaded so far:

Fun 1 835F: 4
Fun 2 978F: 0
Fun 3 1008F: 7 (all of them occurred after you press A+start so currently not part of the frames you are counting; the question is if there's some way to eliminate these, would you be able to press A+start sooner?)
Fun 4 1844F: 2
Fun 5 1507F: 55 (49 of which occurred before A+start)
Fun 6 1111F: 1

Gronkling

#33
Oh wow, thanks a lot! This will be useful
However I'm having trouble running this script, it crashes the emulator and throws this error
[fixed]
Maybe it's because of different emulator settings? I've attached my settings (config.ini) to this post.

I fixed the problem nvm :D

With fun 3, those lag frames can be removed by decreasing the release rate, they don't allow A+Start to be done earlier but they do make the fade out at the end go faster by 7 frames which will affect the total TAS time so should be removed.
This issue points out a flaw in what I've been doing so from now on I will count frames from when the level finishes loading to when the results screen starts loading. The other values will be changed to reflect this.

Fun 1 835F -> 890F
Fun 2 978F -> 1033F
Fun 3 1008F -> 1063F (including removing lag frames)
Fun 4 1844F -> 1896F
Fun 5 1476F -> 1528F
Fun 6 1111F -> 1166F

EDIT: Got the 1 lag frame out of fun 6, making new solution 1165F

Gronkling

#34
...removing the 2 lag frames just using screen scrolling from Fun 4 made the solution longer :XD:
Removing both resulted in an extra frame
Removing just one resulted in 2 extra frames
Adding one to make 3 total lag frames resulted in 4 extra frames
I'm not sure why but it might be something to do with win conditions only being checked 1/3 frames like a lot of other things, and having extra frames makes the cycle sync up better or something... I added movies to this post so you can see for yourselves

EDIT: Caused by a silly mistake on my behalf, ignore it

Gronkling

Fun 7 done, this one was annoying :sick:

Builders will help you here in 2012 frames (~40s)
https://youtu.be/nCk9ykm7TOw
This level is a real pain to optimise due to the genesis's limited controls, so I'm sure there'll be more frames knocked off in the future. Not much special to say about it

ccexplore

Quote from: Gronkling on January 30, 2016, 03:40:06 PM...removing the 2 lag frames just using screen scrolling from Fun 4 made the solution longer :XD:

I finally got around to playing the movies, but I am not seeing what you are reporting? ???  In the 2LF version, frame counter 772 is first frame where the level starts becoming visible, 2649 is where the post-level screen starts becoming visible, and 2659 is when the fade-in completes.  In the 0LF version, it's 772, 2647, and 2657, exactly 2 frames less.

Gronkling

#37
Ah, looking back over the two solutions I see that there isn't any strangeness happening, the 0LF version is indeed 2 frames shorter , there's just a small quirk with the TAS editor that can make it seem like that's the case in certain situations which I now know how to avoid, so yeah disregard that post :-[:lix-ashamed: Checked other solutions for same errors, fun 5 had one meaning real time so far was 1531F rather than 1528, every other one had no errors.




EDIT: Might as well get this mega easy level out the way
Not as Complicated as it Looks in 1486 Frames (~30s)
https://youtu.be/Vlt-Zn1Lb48
Nothing interesting here, just a blocker and your done. You don't even have to do anything to reduce lag frames.

EDIT2: Already obsoleted, got a builder under the entrance which reduced falling time, so new solution is 1478F and may be optimised further, this level is no longer 'mega easy' :P

Gronkling

As Long as You Try Your Best in 1733F (~35s)
https://youtu.be/rH1DpB74q70

2 solutions here, both the same length.
1st one is the trivial solution, just two bashers through the middle pole.
2nd one places a builder under the entrance to reduce falling times. This one has more potential but I couldn't get it better than the trivial solution.

I'll use the first solution if I can't improve the 2nd one later on.

Also going to update the youtube videos.

Simon

Reading your 2nd solution, I've imagined something quite different from what you did in the video.

I thought you would build under the hatch with a lem that has just landed. After building 1 or 2 steps, bash or mine to cut off. Again build with a fresh lander, cut off. Do it a 3rd or 4th time, if necessary.

Doing this 3 times shortens the fall by 1 frame (lems fall 3 pixels per frame), and you rescue all the builders, because you cut off the stairs.

This hinges on keeping the right end of the builder construction nicely sloped downwards.

-- Simon

Gronkling

#40
Unfortunately doing that results in this, the builder doesn't reach back enough

EDIT: Another error, it does work.

Gronkling

5 Miles (aka Smile) if you Love Lemmings in 631 Frames (~12s)
https://youtu.be/hy0i5mog0ao

Quite simple (so far).. Blocker and floaters to solve the level as normal, the miner at the top shortens the falling by a few frames.

Shortest level yet :D

ccexplore

Quote from: Gronkling on January 31, 2016, 10:02:44 PMUnfortunately doing that results in this, the builder doesn't reach back enough

No, you just didn't do it right, it is possible to build right on the landing spot.  I think you need to press C slightly before you actually see the lemming land.  See attached emulator movie.

ccexplore

I've updated the lag-frame counting LUA script (just replace the file with the attached version to use) as follows:

- It can now detect end-of-level condition and avoids the false detection of lag frames past that point.  I'm using the byte at memory location F9E2, which from observation appears to be 1 while in-level and 0 otherwise.  Note that at that point the post-level screen is not at all visible yet, but it is the memory location I found that changed early enough to avoid any false detection of lag frames (it is basically at the exact point where the screen resolution changes going from in-level to post-level).

- It now outputs the frame counter values of each lag frame detected, in the "Output" section of the Lua Console window.  Specifically, whenever time moves forward and a lag frame is detected, a line is written there showing the frame counter value for which the lag frame was detected.  Also, upon detecting the end-of-level condition per first point above, it will output a whole summary section describing when (frame counter value) it detected end-of-level, and the full list of all lag frames' times (ie. the frame counter values each occurred at).

The output can get a little noisy especially if you start framestepping backwards and forwards, potentially causing the same lag frame to be outputted multiple times (don't worry, it won't double-count anything).  The script does clear the entire output whenever you reload the script, and you can also clear the Output section at any time by right-clicking it and select "clear" from the context menu.

Savestates still not supported yet.

Gronkling

Thanks for the update, I'll use it lots.
And oops another stupid mistake from me :'( not sure how I missed that; but unfortunately this technique still hasn't managed cut frames, Fun 9 is very sensitive to lag frames for whatever reason and all the building/bashing causes enough of them that it negates any benefits (if they didn't exist, it would be faster) I often ran into upwards of 100 lag frames.