[SUG] Playback Mode (auto-play multiple replays)

Started by LJLPM, May 04, 2024, 10:15:45 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LJLPM

Hi,

Recently, I thought about a feature that I would find "useful" : I would be interested in having a "Screensaver Mode".

- when selecting the "Screensaver mode" , SuperLemmix would just play random replays indefinitely, until one quits this mode.
(with the possibility to have 100% no sound while the "Screensaver mode" is active, of course.)

Sounds interesting or not ?

Thanks! :)

PS: for the Screensaver/Replay mode, I would like to load random replays for SuperLemmix among ALL the available replays found on the computer (in any level pack thus, mixing Classic Lemmings levels and fan-made levels)

WillLem

#1
This one seems very similar to this idea, which seemed to have a good amount of support from multiple users. Namida also seemed to think that the codebase would support it in all but auto-scrolling the screen according to the user's mouse movements.

As of 2.7, SuperLemmix now has .nxrp file association - i.e. if you right-click a .nxrp file in Windows and associate it with SuperLemmix.exe, then double click the .nxrp, it will open SuperLemmix and auto-load both the level and the replay (albeit to Preview screen rather than opening the level directly - this is so that the user can make sure that the correct level has been loaded). There is also the Mass Replay Checker, which already auto-plays replays, it just doesn't render them.

In theory, we could harness these capabilities to play multiple replay files back-to-back. We'd generate and store a list of replays from a specific directory, and then auto-load each one in turn, always bypassing the Preview/Postview screens (or, perhaps, displaying them for 5 seconds or so between levels).

Not out of the question, and we may even be able to address the issue of screen movement not being saved in the replay - it seems like this would almost be a must for this feature anyway. At the very least, auto-loading replays shouldn't be too difficult even if we can't also record screen movement. We just generate a list, then iterate through the list matching each replay to a level file, load the level, load the replay, move on to the next one. It'd probably be best to skip any cases of "level not found" as well.

With that in mind - as of 2.8, SuperLemmix will have the ability to write a replay's Mass Replay Check result to the filename (I'll see if it's also possible to write the result to the replay file itself), that way we could have the proposed auto-play/"screensaver" feature only play successful replays.

Then, it would be up to the user whether they wanted to load only replays for a specific pack, or for a random selection of levels. The button would open a file browser, and you'd select which folder of replays you wanted to play.

I've added this one to the wish list.

LJLPM

#2
Hi,
Thank you for your detailed reply and for adding my request to the wish list :)

WillLem

#3
Made a surprising amount of progress with this today. We now have a Playback Mode button in the Level Select Menu:



As well as looking pretty, this button opens up a dialog from which a folder of replays can be selected. Once chosen, SLX will then iterate over each replay in the folder, matching it up with a level from within the currently-active pack (note: at this point, it only looks in the currently-active pack for matches - this could be expanded to it searching the entire levels directory, but this may make loading slower). The "currently-active pack", in this case, is the parent pack of whichever level is currently selected in the Level Select treeview.

Each replay is then played back automatically, one after the other (the preview and postview screens are briefly seen in between each level). If a level has multiple replays associated with it, each one will be played back as and when the replay appears in the Playback list.

Playback Mode can be cancelled by simply cancelling the replay as normal (I might give this a dedicated hotkey if people think it's worth it - it's possible that users might cancel the replay by accident, and also users might want to do something within the current level, but then go ahead with playback again for the next level, which is currently possible if we don't cancel Playback Mode along with a normal replay cancel).

Some issues:

1) The preview screen always shows the first level in the list's info, even though the correct level is loaded when playback itself starts
2) The music is always that of the first level in the list - this is likely part of the same problem, but I'm not sure exactly what's going wrong
3) If a replay doesn't have a definite "end" point (so, if the original player pressed [Esc] rather than nuking at the end of Tailor-made For Blockers, for example), the level will continue to play indefinitely - not sure exactly what to do about this at the moment, but ideas will come
4) Not an issue as such, but randomizing the playback currently isn't possible by any other means than manually mixing up the replay files so they're not in logical order. Let's get the other issues sorted first and get the feature nice and tight, then we can look at expanding functionality to randomization of playback, etc.

If you're interested, check out commit 80da87c02 to see implementation so far. If you can see possible improvements or ways to fix the above bugs, input would be most welcome.

Otherwise, just watch this space!

WillLem

#4
OK, I think I know what the problem is.

In SLX, a level exists as 3 different things:

1) The file itself
2) A TNeoLevelEntry, which stores the basic level information (title, levelID, etc)
3) A TLevel, which stores the more complex information (skillset, talismans, plus whether or not the level was successfully passed, etc)

I need to find a way to create a TNeoLevelEntry from the file. I can do that for the purposes of playing back the replay, but not loading the actual information. It's baffling, but nothing I haven't encountered from this codebase many times before. I'll get around to it.

A Rount Tuit

WillLem

#5
Fixed the incorrect Preview screen & music loading bug. The important thing was to first update the CurrentLevel in GameParams, and get all subsequent levels having correctly loaded that one (or, more specifically, that one's parent group).

What this does mean is that, at least for now, we won't be able to search the entire level file directory if a match isn't found in the currently-active-pack. I plan to update that in the future if at all possible, but for now it's good to have this feature working solidly.

Commit 6f6ed62bf implements this fix.

WillLem

#6
We now have a fully-implemented and working Playback Mode, with options to play back by Replay, by Level, or in Random order!

It's fairly rudimentary, but works well. No camera movement unfortunately, but simply having auto-play functionality is a huge advantage by itself. Here's a video demo:



EDIT: Incidentally, Playback Mode works just fine when Classic Mode is active, but Replay Insert mode is unavailable (as per the parameters of Classic Mode) - so, despite what I said in the video, Playback Mode probably won't activate Replay Insert mode by default.

I'll get a better demo video out soon :P

Implemented in Commits 80da87c02 - 98d4abdfc (not squashing at present to make it easier to rollback features in case of issues, the commit number may change before the feature goes stable)

WillLem

Ran into a particularly nasty bug with this today. If the level has preview screen text, when the level loads, it takes on all of the user input from the previous level (pause, fast-forward, etc). So, for example:

Level 1 is loaded, user fast-forwards through the level and then presses pause. They then exit the level.
Level 2 is loaded, and it has preview text. Once the level actually begins, it loads to some distance into the level and is paused :lem-mindblown:

I can barely explain it, let alone find a cause.

It might be that we'll just have to not show preview screen text (and, probably then postview screen text) when Playback Mode is active if I'm unable to figure out what's going wrong here.

WillLem

OK, some clues:

What's happening is that the level with the Preview text is skipping to whatever Current Iteration the previous level finished at.

So:

Level 1 finished at CI = 1279
Level 2 starts at CI = 1279, regardless of user input. The game is always paused and must be unpaused.




Some tests:

Level 1 has ONLY postview text, began at CI = 0 (normal speed), finished at CI = 826
Level 2 has ONLY preview text, began at CI = 0 (paused), finished at CI = 1851
Level 3 has BOTH preview and postview text, began at CI = 1282 (speed unknown), finished immediately at CI = 1282

Level 1 has BOTH preview and postview text, began at CI = 0 (normal speed), finished at CI = 1282
Level 2 has ONLY postview text, began at CI = 0 (normal speed), finished at CI = 826
Level 3 has ONLY preview text, began at CI = 0 (paused), finished at CI = 1851

Level 1 has ONLY preview text, began at CI = 0 (normal speed), finished at CI = 1851
Level 2 has BOTH preview and postview text, began at CI = 1282 (speed unknown), finished immediately at CI = 1282
Level 3 has ONLY postview text, began at CI = 0 (normal speed), finished at CI = 826




Possible conclusions:

Preview text causes one of the following:

i) a forwards skip to the finishing iteration of the previous level, and paused game speed, if the previous level also had preview text
ii) paused game speed at CI = 0 if the previous level had no preview text.

WillLem

OK, this one's a tail-chaser. I'm calling it here: for now, we don't get Preview/Postview text when in Playback Mode.

Hopefully I can find a fix at some point, but I don't want this to hold up the feature for now. Commit 070cb3a implements the band aid.

WillLem

Happy to report that I've fixed the pre/post text bugs, so text screens can be shown in Playback Mode!

The code to call text screens is now much more straightforward:

Previously, the text screen was always called, regardless of whether or not the level had pre/post text. Since the engine mostly relied on knowing what the "next" screen was going to be, this is what was causing most of the bugs when trying to do more complex things with the various game screens (such as auto-skip them).

Now, we check whether a level has pre/post text before deciding which screen to show, and I've added a variable to track what the current screen is, both of which make handling the various game screens much more comprehensive in general.

Furthermore, Playback Mode has been completely re-written. Now that I've had a chance to test it out and see what the potential flaws are, I've come up with a better way of implementing it; the Playback List is now completely constructed and verified before entering Playback Mode, meaning that all we then need to do is play each item in the list consecutively (previously, the list was constructed on-the-fly during playback). This causes a slight delay between starting the mode and the first level being loaded, but from there on it's much snappier and, importantly, far easier to handle code-side. It also opens up the possibility of skipping back and forth through the list, something which wouldn't have been possible with the previous implementation.

Commit 8daf9607f is therefore a happy one, following the extensive refactoring of Playback Mode in f9a4d0ff0 :lemcat: