Skip to content
Hubert Maraszek edited this page Jun 18, 2025 · 1 revision

Principles

Playnote has these design goals in mind:

1. Performance at all costs

The code must be technically excellent. Performance includes not only framerate, but also pacing (lack of stutter), low latency, input responsiveness, and stability. The code should go as low-level as it needs to achieve this, but no lower. Performance should be maintained even with background tasks running. Favor methods like precomputation and caching to offload computation to loading time, and preferably import time.

2. Every released BMS is a test case

The player should work with every BMS file that it could be reasonably expected to work with, no matter how invalid. Users don't care about spec correctness; they want to play their charts. In this way, our job here is similar to that of a web browser.

3. Solve hard problems invisibly

BMS has many ambiguities and is notoriously difficult to parse and maintain, with some players taking entire minutes to refresh the song library. These difficulties are to be considered a programming challenge, and solved with detection algorithms, heuristics and cached prepasses. The frictions of BMS should be handled without the user's input, if at all possible.

4. Stay newbie-friendly

If there's one thing any rhythm gamer knows of BMS, is that it takes hours of setup to get started. This needs to go away. Even someone who knows nothing of rhythm games in general should be able to play a song immediately. Achieve this via sane defaults, device autodetection, input icons, bundled content, separating advanced features, etc.

5. Don't hesitate to drop bad ideas

The BMS format is very old; it was created at a time when many standard rhythm game practices have not yet been established. Due to this, it had made some choices that ended up unpopular over time, and most people don't consider them to add to the value of BMS. These should be intentionally unsupported to streamline the BMS experience.

Departures from tradition

Playnote intentionally ignores certain parts of the BMS specification and de-facto standard BMS player practice.

Timing windows

The #RANK command is not respected; instead, every chart has the same timing window. BMS timings are notoriously wide, since the majority of charts opt for EASY judge. Some don't, however, which creates a jarring experience. Other rhythm games have shown that stable timing windows are ultimately the better idea, and they help with making sure one's "earthpower" level doesn't become too unbalanced from their accuracy.

Gauges

The #TOTAL command is not respected; instead, every chart has the same gauge restoration speed. In other BMS players the TOTAL value affects the ratio of gauge restoration vs drain, which makes it easier or harder to survive at the same player performance level. There is no sensible reason why this should be different per chart, and various gauges already exist to adjust the difficulty of staying alive.

Difficulty

The #PLAYLEVEL command ("number" difficulty) is ignored and not surfaced in the UI; #DIFFICULTY (the B/N/H/A/I "name" difficulty) is still shown as background color. The difficulty number is set by the chart creator with no clear guidelines, so it's not very useful in practice. There's also no reliable indication if the chart creator is referring to normal or insane scale. Tables are supported, which are the typical way of achieving consistent difficulty numbering in BMS. For loose charts, players are advised to consult average and peak note density.

Clone this wiki locally