A wise man once said,
making your vision clear ahead of time not only helps you stay on track but attracts potential users interested in what you’re going for, and early feedback is extremely important
Alright, it wasn’t a wise man, it was me, on Discord, last week. That’s all the more reason though to write up a clear statement of scope – what Playnote is and isn’t going to be. No more witty intros, let’s go.
Reliable and performant by default
Starting on the guts end of things – a big area where Playnote can improve over the competition is technical soundness. No crashes, no memory leaks, no stutters, no lock-ups regardless of how heavy an operation, clear error reporting when something goes wrong. Performance should be smooth on any reasonably modern device, the latencies (both audio and video) as low as the platform allows, and independent from rendering framerate. There’s no valid reason for a rhythm game to have to run at 480 FPS to feel responsive on a 120Hz display – that’s a waste of 75% of the frames. To this end, the code is written to be exception-safe from day one, and all failures tested to be handled as expected, including critical ones always triggering a clean shutdown.
Defaults have power. All this should require no upfront configuration; settings are good, but they should default to the most performant options, only to be changed to improve compatibility when the user encounters an issue.
As low-level as needed, but no lower
Paraphrasing a quote that Einstein may or may not have said, Playnote isn’t a slave to any particular level of abstraction, sometimes to the horror of fans of any particular one. A project that aims for technical excellence in a niche area is going to need to reinvent some wheels, but the majority of components can be off-the-shelf. The biggest challenge of any hobby project is finishing before you die, and any choice needs to have this in mind.
The unspoken value of libraries and abstractions is a reduction in the number of lines of my own code. Code I wrote has been used once (by me), while code others wrote has been used by thousands of people; so, the more of my own game has been written by someone else, the better it’s going to be. If in doubt, get data – seek benchmarks, or just go for it and then profile the outcome.
Fix the design of BMS invisibly
BMS is not a good format. It’s dragged down by decades of bad decisions and non-standard extensions, and this is much of the reason why BMS clients can be hard to work with. Playnote should go out of its way to hide as much of that as possible and pretend BMS is reliable and amazing, with whatever algorithms and heuristics it takes to achieve that. Text encodings are detected, typo’d header commands are fixed, oversized WAV samples are compressed. It should be up to the programmer to deal with these challenges, not up to the user.
Best-effort compatibility
There’s a lot of BMS files out there, and the older they are the more broken they tend to be, in ways I surely can’t even begin to imagine right now. hitkey‘s write-up lists some of the horrors he encountered. Playnote will strive to support all valid BMS files, at least initially. Some leniency is already baked into the parser, and any further fixes for compatibility with invalid BMS files will be done on a case-by-case basis. I would love to aim for 100% compatibility, but that can only be a goal once all more important things are done first. Please understand.
One aspect where compatibility must be maintained is with older BMS clients. When importing a song and converting it into a format that’s as quick to load as possible, it must use only formats that still work with LR2 and beatoraja. This is so that it’s possible to revert from Playnote to an older client, should one be unhappy with Playnote and decide to go back. With the currently planned design, a library is a collection of optimized zip files, which can be simply unpacked into old-school song folders.
Effortless user experience
As much I disagree with its gameplay design choices, osu! is a masterclass in UX. A single-exe installer that unpacks into %APPDATA%
, built-in song downloader, reasonably preconfigured for getting started right away; to get more songs, all you need to do is drag a downloaded song file onto the game window to import it. There are no technical reasons why a BMS client couldn’t be just as easy to use. Features that optimize the newcomer experience are first-class. BMS power users must of course be satisfied as well, but hiding away features that are useful less often into “Advanced” submenus will improve the UI flows for everyone.
Unique visual style
The game will stick with 2D graphics of course, but that’s no reason why it shouldn’t try to stand out – an attractive screenshot will always sell a game better than a list of features. I’m no traditional artist, but with strong past graphics programming experience, I can make something interesting from a tech art perspective. The current plan is for all graphics to be built out of SDFs, including text; this will allow for highly dynamic forms, with perfect analytical antialiasing at any scale. This concept has already been successfully attempted and used in production for editor tooling at Guerilla Games.
The visual style will be clean, minimal and stylish; taking inspiration from N++, NieR:Automata, and the work of The Designers Republic. I like to believe I have some sense of aesthetics, so it might take a lot of trial and error, but I should at least realize when I arrive at something visually pleasing. I’m dreading the process, but looking forward to the results.
Break bad traditions
This one might be controversial, but I believe that some parts of the BMS standard should be actively ignored and redesigned to better match how the modern audience plays rhythm games. For example, the #RANK
header allows a chart to decide between (typically) four sizes of judgment windows. This might’ve sounded like a good idea at the time, but rhythm games these days don’t tend to vary their timing between songs or between difficulties. Most recent BMS charts go for the easiest rank, which over time gave BMS the reputation of being loose and good for training physical speed. #RANK
will be ignored, but to respect BMS’s place, the windows will be slightly looser than in IIDX.
This is also the reason why Playnote will not allow importing scores from a previous BMS client, or connecting to an existing internet ranking service. LR2 and beatoraja already have different timing windows for the same rank (a fact that spawned the LR2oraja fork), and even identical values can feel different on different engines and with different latencies. There’s simply no way to make scores directly comparable in a way that would satisfy everyone. Even re-simulating a play with the same inputs would be questionable, since it doesn’t take into account the player’s mental state.
Another example is the #PLAYLEVEL
header, which specifies a difficulty number to be shown in song select. These are infamous for not being very useful, since the value is entirely at the chart creator’s discretion, and there’s no way to specify the scale (normal/insane/etc.) Third-party difficulty tables have been created to fix that by independently ranking charts’ difficulty, often via a community voting process. Playnote will ignore #PLAYLEVEL
entirely, displaying only its calculated average notes-per-second unless a table is available for the chart.
The little things are good!
BMS clients are full of minor features people love, and the lack of any one of them can be a dealbreaker for someone out there. 2-Player battle, lamps above Full Combo, practice mode, gauge auto-shift, etc. If it makes sense at all, it will be implemented.
Customization over skinning
Due to the planned nature of the renderer, skins would be very difficult to implement, and so are not part of the plans for the 1.0 release. Customization is part of the very soul of BMS though, so many pre-made layouts and components will be available to choose from, with arbitrary image display available as well for shareable areas like the result screen.
Afterword
That was a lot! Still, I think it’s important to have the general roadmap out there, even if just to keep myself accountable to it in the future. Please keep in mind that this is the vision for 1.0, and doesn’t mean the end of development. Other major features, like an internet ranking, online profile or a chart recommendation system, are not out of question, just out of scope for the initial release.
If you feel particularly strongly about any of these items, please let me know via a GitHub issue.