open-manifold / Open-Manifold

A free and open-source clone of Rhythm 'n' Face for PC.
Other
10 stars 1 forks source link

Add a level playlist/pack system #28

Closed SuperFromND closed 1 year ago

SuperFromND commented 1 year ago

Right now, Open Manifold's level list is quite simple: it indexes the folder path of every level in the levels folder, sorts it alphabetically, and... that's it!

This works fine enough, but I think it can be improved in a few different ways. I've created a couple different issues to lay out some improvement ideas I've had here and there.

Playlists/packs are common in other rhythm games like Clone Hero, and are essentially a metadata file containing a list of levels in a particular order. This gives authors the ability to sort their levels however they like, so they won't have to use workarounds like adding numeric prefixes to the folder names.

As for actually making them function as a playlist, that'd take a bit more effort to do, as you'd have to index all the levels in the playlist (probably as a vector similar to level_index), and then call a function at the end of every level to load up the data for the next one in the index.

SuperFromND commented 1 year ago

Jotting this down as a comment for my own future reference:

A possible way I've thought of implementing this without breaking the current level file structure (single levels folder, containg folders with datafiles in them) would be by adding support for files (JSON? INI?) within that single levels folder that would get scanned before any folders.

A quick and dirty mockup via JSON of what they might look like:

//  (yes i know JSON doesnt support comments but shh)

[
    {"name": "My Cool Playlist"}, // no author data since levels will likely contain it anyways
    {"levels": [
            "Happy Peace Smile", // using relative-to-assets/levels paths here, absolutes might cause problems @_@
            "Swan Song 2000", // so e.g. this would resolve to "assets/levels/Swan Song 2000/level.json"
            "Fat Tiger Blues", // (actually without the level.json part, thats just for clarity)
            "etc"
    ]}
]

The idea is to scan for these playlist files, check if the listed level paths they contain are valid, and if they are, add them in order to level_index. Then, once all the playlist files have been checked, then scan for folders and add them to level_index (adding a check to make sure they aren't already there from a playlist, of course). You'd probably have to make a temporary second vector for the not-in-playlist levels to run an std::sort on them, but that shouldn't be a problem since it'll only be ran once on startup in most cases.

image

This might cause conflicts with implementing different level sorting methods (see #26), that might need some figuring out if that ends up being implemented first.