rosu-pp
A standalone crate to calculate star ratings and performance points for all osu! gamemodes.
Conversions between gamemodes are generally not supported.
Async is supported through features, see below.
Usage
use std::fs::File;
use rosu_pp::{Beatmap, BeatmapExt};
let file = match File::open("/path/to/file.osu") {
Ok(file) => file,
Err(why) => panic!("Could not open file: {}", why),
};
// Parse the map yourself
let map = match Beatmap::parse(file) {
Ok(map) => map,
Err(why) => panic!("Error while parsing map: {}", why),
};
// If `BeatmapExt` is included, you can make use of
// some methods on `Beatmap` to make your life simpler.
// If the mode is known, it is recommended to use the
// mode's pp calculator, e.g. `TaikoPP`, manually.
let result = map.pp()
.mods(24) // HDHR
.combo(1234)
.misses(2)
.accuracy(99.2)
.calculate();
println!("PP: {}", result.pp());
// If you intend to reuse the current map-mod combination,
// make use of the previous result!
// If attributes are given, then stars & co don't have to be recalculated.
let next_result = map.pp()
.mods(24) // HDHR
.attributes(result) // recycle
.combo(543)
.misses(5)
.n50(3)
.passed_objects(600)
.accuracy(96.5)
.calculate();
println!("Next PP: {}", next_result.pp());
let stars = map.stars(16, None).stars(); // HR
let max_pp = map.max_pp(16).pp();
println!("Stars: {} | Max PP: {}", stars, max_pp);
With async
If either the async_tokio or async_std feature is enabled, beatmap parsing will be async.
use async_std::fs::File;
// use tokio::fs::File;
let file = match File::open("/path/to/file.osu").await {
Ok(file) => file,
Err(why) => panic!("Could not open file: {}", why),
};
// Parse the map asynchronously
let map = match Beatmap::parse(file).await {
Ok(map) => map,
Err(why) => panic!("Error while parsing map: {}", why),
};
// The rest stays the same
let result = map.pp()
.mods(24) // HDHR
.combo(1234)
.misses(2)
.accuracy(99.2)
.calculate();
println!("PP: {}", result.pp());
osu!standard versions
-
osu_precise: Both stack leniency & slider paths are considered so that the difficulty and pp calculation immitates osu! as close as possible. Pro: Very accurate values; Con: Less performant. -
osu_fast(i.e. oppai): Fully ignoring sliders aswell as the positional offset caused by stack leniency. This means the stacked position and travel distance of notes is completely omitted which results in notable inaccuracies but is also considerably faster thanosu_precise. -
Note: If the
fruitsfeature is enabled, sliders will be parsed regardless, resulting in a reduced performance advantage ofosu_fast. Hence, it is only recommended to useosu_fastiffruitsis not enabled.
Features
| Flag | Description |
|---|---|
default |
Enable all modes and choose the osu_precise version for osu!standard. |
taiko |
Enable osu!taiko. |
fruits |
Enable osu!ctb. |
mania |
Enable osu!mania. |
osu_fast |
When calculating difficulty attributes in osu!standard, ignore stack leniency and sliders. Great performance but less precision values. |
osu_precise |
When calculating difficulty attributes in osu!standard, consider both stack leniency and sliders. Great precision but significantly worse performance than osu_fast. |
async_tokio |
Beatmap parsing will be async through tokio |
async_std |
Beatmap parsing will be async through async-std |
Benchmarks (TODO, update w.r.t new feature flags)
Comparing the PP calculation speed between osu-perf (alternative rust pp calculculation crate), an oppai-ng rust binding, and rosu-pp's no_sliders_no_leniency:
Comparing the PP calculation speed between rosu-pp's all_included, no_leniency, and no_sliders_no_leniency versions:
Comparing the PP (in)accuracy between rosu-pp's all_included, no_leniency, and no_sliders_no_leniency versions:
Comparing the stars (in)accuracy between rosu-pp's all_included, no_leniency, and no_sliders_no_leniency versions: