crates.io docs

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

```rust 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. // However, to calculate specific pp values, it is recommended // to match on the map's mode yourself and modify 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 nextresult = map.pp() .mods(24) // HDHR .attributes(result) // recycle .combo(543) .misses(5) .n50(3) .passedobjects(600) .accuracy(96.5) .calculate();

println!("Next PP: {}", next_result.pp());

let stars = map.stars(16, None).stars(); // HR let maxpp = map.maxpp(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.

```rust 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

Note: If the fruits feature is enabled, sliders will be parsed regardless, resulting in a reduced performance advantage of no_sliders_no_leniency.

Features

| Flag | Description | |-----|-----| | default | Enable all modes and choose the no_leniency version for osu!standard. | | taiko | Enable osu!taiko. | | fruits | Enable osu!ctb. | | mania | Enable osu!mania. | | osu | Enable osu!standard. Requires to also enable exactly one of the features no_leniency, no_sliders_no_leniency, or all_included. | | no_leniency | When calculating difficulty attributes in osu!standard, ignore stack leniency but consider sliders. Solid middleground between performance and precision, hence the default version. |
| no_sliders_no_leniency | When calculating difficulty attributes in osu!standard, ignore stack leniency and sliders. Best performance but slightly less precision than no_leniency. | | all_included | When calculating difficulty attributes in osu!standard, consider both stack leniency and sliders. Best precision but significantly worse performance than no_leniency. | | async_tokio | Beatmap parsing will be async through a tokio runtime | | async_std | Beatmap parsing will be async through an async-std runtime |

Benchmarks

Comparing the PP calculation speed between osu-perf, 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:

Roadmap