rosu-pp-js
Version:
Difficulty and performance calculation for osu!
946 lines (934 loc) • 25.1 kB
TypeScript
/* tslint:disable */
/* eslint-disable */
export enum GameMode {
Osu = 0,
Taiko = 1,
Catch = 2,
Mania = 3,
}
/**
* While generating remaining hitresults, decide how they should be distributed.
*/
export enum HitResultPriority {
/**
* Prioritize good hitresults over bad ones
*/
BestCase = 0,
/**
* Prioritize bad hitresults over good ones
*/
WorstCase = 1,
/**
* Prioritize fast hitresults generation
*/
Fastest = 2,
}
/**
* The content of a `.osu` file either as bytes or string.
*/
export type BeatmapContent = Uint8Array | string;
/**
* Arguments to provide the `BeatmapAttributesBuilder` constructor.
*/
export interface BeatmapAttributesArgs extends CommonArgs {
/**
* Specify a gamemode.
*/
mode?: GameMode;
/**
* Specify whether it's a converted map.
*/
isConvert?: boolean;
/**
* Start off with a beatmap's attributes, mode, and convert status.
*/
map?: Beatmap;
}
/**
* Common properties to extend other argument interfaces.
*/
export interface CommonArgs {
/**
* Specify mods.
*
* The type must be either
* - an integer for bitflags
* - a string for acronyms
* - a single mod object as described below
* - a sequence of types that deserialize into a single mod
*
* Types that deserialize into a single mod are
* - an integer for bitflags
* - a string for an acronym
* - a mod object
*
* A mod object must have an `acronym: string` property and an optional
* `settings?: Object` property.
*
* See <https://github.com/ppy/osu-api/wiki#mods>
*/
mods?: Object;
/**
* Adjust the clock rate used in the calculation.
*
* If none is specified, it will take the clock rate based on the mods
* i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
*
* | Minimum | Maximum |
* | :-----: | :-----: |
* | 0.01 | 100 |
*/
clockRate?: number;
/**
* Override a beatmap's set AR.
*
* Only relevant for osu! and osu!catch.
*
* | Minimum | Maximum |
* | :-----: | :-----: |
* | -20 | 20 |
*/
ar?: number;
/**
* Determines if the given AR value should be used before
* or after accounting for mods, e.g. on `true` the value will be
* used as is and on `false` it will be modified based on the mods.
*/
arWithMods?: boolean;
/**
* Override a beatmap's set CS.
*
* Only relevant for osu! and osu!catch.
*
* | Minimum | Maximum |
* | :-----: | :-----: |
* | -20 | 20 |
*/
cs?: number;
/**
* Determines if the given CS value should be used before
* or after accounting for mods, e.g. on `true` the value will be
* used as is and on `false` it will be modified based on the mods.
*/
csWithMods?: boolean;
/**
* Override a beatmap's set HP.
*
* | Minimum | Maximum |
* | :-----: | :-----: |
* | -20 | 20 |
*/
hp?: number;
/**
* Determines if the given HP value should be used before
* or after accounting for mods, e.g. on `true` the value will be
* used as is and on `false` it will be modified based on the mods.
*/
hpWithMods?: boolean;
/**
* Override a beatmap's set OD.
*
* | Minimum | Maximum |
* | :-----: | :-----: |
* | -20 | 20 |
*/
od?: number;
/**
* Determines if the given OD value should be used before
* or after accounting for mods, e.g. on `true` the value will be
* used as is and on `false` it will be modified based on the mods.
*/
odWithMods?: boolean;
}
/**
* Arguments to provide the `Difficulty` constructor.
*/
export interface DifficultyArgs extends CommonArgs {
/**
* Amount of passed objects for partial plays, e.g. a fail.
*
* If you want to calculate the difficulty after every few objects,
* instead of using `Difficulty` multiple times with different
* `passedObjects`, you should use `GradualDifficulty`.
*/
passedObjects?: number;
/**
* Adjust patterns as if the HR mod is enabled.
*
* Only relevant for osu!catch.
*/
hardrockOffsets?: boolean;
/**
* Whether the calculated attributes belong to an osu!lazer or osu!stable
* score.
*
* Defaults to `true`.
*/
lazer?: boolean;
}
/**
* Arguments to provide the `Performance` constructor.
*/
export interface PerformanceArgs extends DifficultyArgs {
/**
* Set the accuracy between `0.0` and `100.0`.
*/
accuracy?: number;
/**
* Specify the max combo of the play.
*
* Irrelevant for osu!mania.
*/
combo?: number;
/**
* The amount of "large tick" hits.
*
* Only relevant for osu!standard.
*
* The meaning depends on the kind of score:
* - if set on osu!stable, this value is irrelevant and can be `0`
* - if set on osu!lazer *without* `CL`, this value is the amount of hit
* slider ticks and repeats
* - if set on osu!lazer *with* `CL`, this value is the amount of hit
* slider heads, ticks, and repeats
*/
largeTickHits?: number;
/**
* The amount of "small tick" hits.
*
* These are essentially the slider end hits for lazer scores without
* slider accuracy.
*
* Only relevant for osu!standard.
*/
smallTickHits?: number;
/**
* The amount of slider end hits.
*
* Only relevant for osu!standard in lazer.
*/
sliderEndHits?: number;
/**
* Specify the amount of gekis of a play.
*
* Only relevant for osu!mania for which it repesents the amount of n320.
*/
nGeki?: number;
/**
* Specify the amount of katus of a play.
*
* Only relevant for osu!catch for which it represents the amount of tiny
* droplet misses and osu!mania for which it repesents the amount of n200.
*/
nKatu?: number;
/**
* Specify the amount of 300s of a play.
*/
n300?: number;
/**
* Specify the amount of 100s of a play.
*/
n100?: number;
/**
* Specify the amount of 50s of a play.
*
* Irrelevant for osu!taiko.
*/
n50?: number;
/**
* Specify the amount of misses of a play.
*/
misses?: number;
/**
* Specify how hitresults should be generated.
*
* Defaults to `HitResultPriority.BestCase`.
*/
hitresultPriority?: HitResultPriority;
}
/**
* Either previously calculated attributes or a beatmap.
*/
export type MapOrAttributes = DifficultyAttributes | PerformanceAttributes | Beatmap;
/**
* Arguments to provide the `Difficulty` constructor.
*/
export interface ScoreState {
/**
* Maximum combo that the score has had so far. **Not** the maximum
* possible combo of the map so far.
*
* Note that for osu!catch only fruits and droplets are considered for
* combo.
*
* Irrelevant for osu!mania.
*/
maxCombo?: number;
/**
* "Large tick" hits for osu!standard.
*
* The meaning depends on the kind of score:
* - if set on osu!stable, this field is irrelevant and can be `0`
* - if set on osu!lazer *without* `CL`, this field is the amount of hit
* slider ticks and repeats
* - if set on osu!lazer *with* `CL`, this field is the amount of hit
* slider heads, ticks, and repeats
*/
osuLargeTickHits?: number;
/**
* "Small tick" hits for osu!standard.
*
* These are essentially the slider end hits for lazer scores without
* slider accuracy.
*
* Only relevant for osu!lazer.
*/
osuSmallTickHits?: number;
/**
* Amount of successfully hit slider ends.
*
* Only relevant for osu!standard in lazer.
*/
sliderEndHits?: number;
/**
* Amount of current gekis (n320 for osu!mania).
*/
nGeki?: number;
/**
* Amount of current katus (tiny droplet misses for osu!catch / n200 for
* osu!mania).
*/
nKatu?: number;
/**
* Amount of current 300s (fruits for osu!catch).
*/
n300?: number;
/**
* Amount of current 100s (droplets for osu!catch).
*/
n100?: number;
/**
* Amount of current 50s (tiny droplets for osu!catch).
*/
n50?: number;
/**
* Amount of current misses (fruits + droplets for osu!catch).
*/
misses?: number;
}
/**
* All beatmap data that is relevant for difficulty and performance
* calculation.
*
* It is recommended to call the method `Beatmap.free` on instances that are
* no longer in use to avoid the risk of leaking memory.
*/
export class Beatmap {
free(): void;
/**
* Create a new beatmap instance by parsing an `.osu` file's content.
* @throws Throws an error if decoding the map failed
*/
constructor(args: BeatmapContent);
/**
* Convert a beatmap to a specific mode.
* @throws Throws an error if conversion fails or mods are invalid
*/
convert(mode: GameMode, mods?: Object | null): void;
/**
* Check whether hitobjects appear too suspicious for further calculation.
*
* Sometimes a beatmap isn't created for gameplay but rather to test
* the limits of osu! itself. Difficulty- and/or performance calculation
* should likely be avoided on these maps due to potential performance
* issues.
*/
isSuspicious(): boolean;
readonly bpm: number;
readonly mode: GameMode;
readonly nBreaks: number;
readonly nObjects: number;
readonly nCircles: number;
readonly nSliders: number;
readonly nSpinners: number;
readonly nHolds: number;
readonly version: number;
readonly isConvert: boolean;
readonly stackLeniency: number;
readonly ar: number;
readonly cs: number;
readonly hp: number;
readonly od: number;
readonly sliderMultiplier: number;
readonly sliderTickRate: number;
}
export class BeatmapAttributes {
private constructor();
/**
** Return copy of self without private attributes.
*/
toJSON(): Object;
/**
* Return stringified version of self.
*/
toString(): string;
free(): void;
/**
* The approach rate.
*/
readonly ar: number;
/**
* The overall difficulty.
*/
readonly od: number;
/**
* The circle size.
*/
readonly cs: number;
/**
* The health drain rate
*/
readonly hp: number;
/**
* The clock rate with respect to mods.
*/
readonly clockRate: number;
/**
* Hit window for approach rate i.e. TimePreempt in milliseconds.
*/
readonly arHitWindow: number;
/**
* Hit window for overall difficulty i.e. time to hit a 300 ("Great") in
* milliseconds.
*/
readonly odGreatHitWindow: number;
/**
* Hit window for overall difficulty i.e. time to hit a 100 ("Ok") in
* milliseconds.
*
* Not available for osu!mania.
*/
readonly odOkHitWindow: number | undefined;
/**
* Hit window for overall difficulty i.e. time to hit a 50 ("Meh") in
* milliseconds.
*
* Only available for osu!.
*/
readonly odMehHitWindow: number | undefined;
}
export class BeatmapAttributesBuilder {
free(): void;
/**
* Create a new `BeatmapAttributesBuilder`.
*/
constructor(args?: BeatmapAttributesArgs | null);
/**
* Calculate the `BeatmapAttributes`.
*/
build(): BeatmapAttributes;
set mods(value: Object | null | undefined);
set clockRate(value: number | null | undefined);
set ar(value: number | null | undefined);
set arWithMods(value: boolean | null | undefined);
set cs(value: number | null | undefined);
set csWithMods(value: boolean | null | undefined);
set hp(value: number | null | undefined);
set hpWithMods(value: boolean | null | undefined);
set od(value: number | null | undefined);
set odWithMods(value: boolean | null | undefined);
set mode(value: GameMode | null | undefined);
set isConvert(value: boolean | null | undefined);
set map(value: Beatmap | null | undefined);
}
/**
* Builder for a difficulty calculation.
*/
export class Difficulty {
free(): void;
/**
* Create a new difficulty calculator.
*/
constructor(args?: DifficultyArgs | null);
/**
* Perform the difficulty calculation.
*/
calculate(map: Beatmap): DifficultyAttributes;
/**
* Perform the difficulty calculation but instead of evaluating strain
* values, return them as is.
*
* Suitable to plot the difficulty over time.
*/
strains(map: Beatmap): Strains;
/**
* Returns a gradual difficulty calculator for the current difficulty settings.
*/
gradualDifficulty(map: Beatmap): GradualDifficulty;
/**
* Returns a gradual performance calculator for the current difficulty settings.
*/
gradualPerformance(map: Beatmap): GradualPerformance;
set mods(value: Object | null | undefined);
set lazer(value: boolean | null | undefined);
set clockRate(value: number | null | undefined);
set ar(value: number | null | undefined);
set arWithMods(value: boolean | null | undefined);
set cs(value: number | null | undefined);
set csWithMods(value: boolean | null | undefined);
set hp(value: number | null | undefined);
set hpWithMods(value: boolean | null | undefined);
set od(value: number | null | undefined);
set odWithMods(value: boolean | null | undefined);
set passedObjects(value: number | null | undefined);
set hardrockOffsets(value: boolean | null | undefined);
}
/**
* The result of a difficulty calculation.
*/
export class DifficultyAttributes {
private constructor();
/**
** Return copy of self without private attributes.
*/
toJSON(): Object;
/**
* Return stringified version of self.
*/
toString(): string;
free(): void;
/**
* The attributes' gamemode.
*/
readonly mode: GameMode;
/**
* The final star rating.
*/
readonly stars: number;
/**
* Whether the map was a convert i.e. an osu! map.
*/
readonly isConvert: boolean;
/**
* The difficulty of the aim skill.
*
* Only available for osu!.
*/
readonly aim: number | undefined;
/**
* The number of sliders weighted by difficulty.
*
* Only available for osu!.
*/
readonly aimDifficultSliderCount: number | undefined;
/**
* The difficulty of the speed skill.
*
* Only available for osu!.
*/
readonly speed: number | undefined;
/**
* The difficulty of the flashlight skill.
*
* Only available for osu!.
*/
readonly flashlight: number | undefined;
/**
* The ratio of the aim strain with and without considering sliders
*
* Only available for osu!.
*/
readonly sliderFactor: number | undefined;
/**
* The number of clickable objects weighted by difficulty.
*
* Only available for osu!.
*/
readonly speedNoteCount: number | undefined;
/**
* Weighted sum of aim strains.
*
* Only available for osu!.
*/
readonly aimDifficultStrainCount: number | undefined;
/**
* Weighted sum of speed strains.
*
* Only available for osu!.
*/
readonly speedDifficultStrainCount: number | undefined;
/**
* The health drain rate.
*
* Only available for osu!.
*/
readonly hp: number | undefined;
/**
* The amount of circles.
*
* Only available for osu!.
*/
readonly nCircles: number | undefined;
/**
* The amount of sliders.
*
* Only available for osu!.
*/
readonly nSliders: number | undefined;
/**
* The amount of "large ticks".
*
* The meaning depends on the kind of score:
* - if set on osu!stable, this value is irrelevant
* - if set on osu!lazer *with* slider accuracy, this value is the amount
* of hit slider ticks and repeats
* - if set on osu!lazer *without* slider accuracy, this value is the
* amount of hit slider heads, ticks, and repeats
*
* Only available for osu!.
*/
readonly nLargeTicks: number | undefined;
/**
* The amount of spinners.
*
* Only available for osu!.
*/
readonly nSpinners: number | undefined;
/**
* The difficulty of the stamina skill.
*
* Only available for osu!taiko.
*/
readonly stamina: number | undefined;
/**
* The difficulty of the rhythm skill.
*
* Only available for osu!taiko.
*/
readonly rhythm: number | undefined;
/**
* The difficulty of the color skill.
*
* Only available for osu!taiko.
*/
readonly color: number | undefined;
/**
* The difficulty of the reading skill.
*
* Only available for osu!taiko.
*/
readonly reading: number | undefined;
/**
* The amount of fruits.
*
* Only available for osu!catch.
*/
readonly nFruits: number | undefined;
/**
* The amount of droplets.
*
* Only available for osu!catch.
*/
readonly nDroplets: number | undefined;
/**
* The amount of tiny droplets.
*
* Only available for osu!catch.
*/
readonly nTinyDroplets: number | undefined;
/**
* The amount of hitobjects in the map.
*
* Only available for osu!mania.
*/
readonly nObjects: number | undefined;
/**
* The amount of hold notes in the map.
*
* Only available for osu!mania.
*/
readonly nHoldNotes: number | undefined;
/**
* The approach rate.
*
* Only available for osu! and osu!catch.
*/
readonly ar: number | undefined;
/**
* The perceived hit window for an n300 inclusive of rate-adjusting mods
* (DT/HT/etc)
*
* Only available for osu! and osu!taiko.
*/
readonly greatHitWindow: number | undefined;
/**
* The perceived hit window for an n100 inclusive of rate-adjusting mods
* (DT/HT/etc)
*
* Only available for osu! and osu!taiko.
*/
readonly okHitWindow: number | undefined;
/**
* The perceived hit window for an n50 inclusive of rate-adjusting mods
* (DT/HT/etc)
*
* Only available for osu!.
*/
readonly mehHitWindow: number | undefined;
/**
* The ratio of stamina difficulty from mono-color (single color) streams to total
* stamina difficulty.
*
* Only available for osu!taiko.
*/
readonly monoStaminaFactor: number | undefined;
/**
* Return the maximum combo.
*/
readonly maxCombo: number;
}
/**
* Gradually calculate difficulty attributes after each hitobject.
*/
export class GradualDifficulty {
free(): void;
constructor(difficulty: Difficulty, map: Beatmap);
/**
* Advances the iterator and returns the next attributes.
*/
next(): DifficultyAttributes | undefined;
/**
* Returns the `n`th attributes of the iterator.
*
* Note that the count starts from zero, so `nth(0)` returns the first
* value, `nth(1)` the second, and so on.
*/
nth(n: number): DifficultyAttributes | undefined;
/**
* Advances the iterator to the end to collect all remaining attributes
* into a list and return them.
*/
collect(): DifficultyAttributes[];
/**
* Returns the amount of remaining items.
*/
readonly nRemaining: number;
}
/**
* Gradually calculate performance attributes after each hitresult.
*/
export class GradualPerformance {
free(): void;
constructor(difficulty: Difficulty, map: Beatmap);
/**
* Process the next hit object and calculate the performance attributes
* for the resulting score state.
*/
next(state: ScoreState): PerformanceAttributes | undefined;
/**
* Process everything up to the next `n`th hitobject and calculate the
* performance attributes for the resulting score state.
*
* Note that the count is zero-indexed, so `n=0` will process 1 object,
* `n=1` will process 2, and so on.
*/
nth(state: ScoreState, n: number): PerformanceAttributes | undefined;
/**
* Returns the amount of remaining items.
*/
readonly nRemaining: number;
}
/**
* Builder for a performance calculation.
*/
export class Performance {
free(): void;
/**
* Create a new performance calculator.
*/
constructor(args?: PerformanceArgs | null);
/**
* Calculate performance attributes.
*
* If a beatmap is passed as argument, difficulty attributes will have to
* be calculated internally which is a comparably expensive task. Hence,
* passing previously calculated attributes should be prefered whenever
* available.
*
* However, be careful that the passed attributes have been calculated
* for the same difficulty settings like mods, clock rate, beatmap,
* custom ar, ... otherwise the final attributes will be incorrect.
*/
calculate(args: MapOrAttributes): PerformanceAttributes;
set mods(value: Object | null | undefined);
set lazer(value: boolean | null | undefined);
set clockRate(value: number | null | undefined);
set ar(value: number | null | undefined);
set arWithMods(value: boolean | null | undefined);
set cs(value: number | null | undefined);
set csWithMods(value: boolean | null | undefined);
set hp(value: number | null | undefined);
set hpWithMods(value: boolean | null | undefined);
set od(value: number | null | undefined);
set odWithMods(value: boolean | null | undefined);
set passedObjects(value: number | null | undefined);
set hardrockOffsets(value: boolean | null | undefined);
set accuracy(value: number | null | undefined);
set combo(value: number | null | undefined);
set largeTickHits(value: number | null | undefined);
set smallTickHits(value: number | null | undefined);
set sliderEndHits(value: number | null | undefined);
set nGeki(value: number | null | undefined);
set nKatu(value: number | null | undefined);
set n300(value: number | null | undefined);
set n100(value: number | null | undefined);
set n50(value: number | null | undefined);
set misses(value: number | null | undefined);
set hitresultPriority(value: HitResultPriority | null | undefined);
}
/**
* The result of a performance calculation.
*/
export class PerformanceAttributes {
private constructor();
/**
** Return copy of self without private attributes.
*/
toJSON(): Object;
/**
* Return stringified version of self.
*/
toString(): string;
free(): void;
/**
* The difficulty attributes.
*/
readonly difficulty: DifficultyAttributes;
/**
* The hitresult score state that was used for performance calculation.
*
* Only available if *not* created through gradual calculation.
*/
readonly state: ScoreState | undefined;
/**
* The final performance points.
*/
readonly pp: number;
/**
* The aim portion of the final pp.
*
* Only available for osu!.
*/
readonly ppAim: number | undefined;
/**
* The flashlight portion of the final pp.
*
* Only available for osu!.
*/
readonly ppFlashlight: number | undefined;
/**
* The speed portion of the final pp.
*
* Only available for osu!.
*/
readonly ppSpeed: number | undefined;
/**
* The accuracy portion of the final pp.
*
* Only available for osu! and osu!taiko.
*/
readonly ppAccuracy: number | undefined;
/**
* Scaled miss count based on total hits.
*
* Only available for osu! and osu!taiko.
*/
readonly effectiveMissCount: number | undefined;
/**
* Upper bound on the player's tap deviation.
*
* Only *optionally* available for osu!taiko.
*/
readonly estimatedUnstableRate: number | undefined;
/**
* Approximated unstable-rate
*
* Only *optionally* available for osu!.
*/
readonly speedDeviation: number | undefined;
/**
* The strain portion of the final pp.
*
* Only available for osu!taiko and osu!mania.
*/
readonly ppDifficulty: number | undefined;
}
/**
* The result of calculating the strains of a beatmap.
*
* Suitable to plot the difficulty over time.
*/
export class Strains {
private constructor();
/**
** Return copy of self without private attributes.
*/
toJSON(): Object;
/**
* Return stringified version of self.
*/
toString(): string;
free(): void;
/**
* The strains' gamemode.
*/
readonly mode: GameMode;
/**
* Time inbetween two strains in ms.
*/
readonly sectionLength: number;
/**
* Strain peaks of the aim skill in osu!.
*/
readonly aim: Float64Array | undefined;
/**
* Strain peaks of the aim skill without sliders in osu!.
*/
readonly aimNoSliders: Float64Array | undefined;
/**
* Strain peaks of the speed skill in osu!.
*/
readonly speed: Float64Array | undefined;
/**
* Strain peaks of the flashlight skill in osu!.
*/
readonly flashlight: Float64Array | undefined;
/**
* Strain peaks of the color skill in osu!taiko.
*/
readonly color: Float64Array | undefined;
/**
* Strain peaks of the reading skill in osu!taiko.
*/
readonly reading: Float64Array | undefined;
/**
* Strain peaks of the rhythm skill in osu!taiko.
*/
readonly rhythm: Float64Array | undefined;
/**
* Strain peaks of the stamina skill in osu!taiko.
*/
readonly stamina: Float64Array | undefined;
/**
* Strain peaks of the single color stamina skill in osu!taiko.
*/
readonly singleColorStamina: Float64Array | undefined;
/**
* Strain peaks of the movement skill in osu!catch.
*/
readonly movement: Float64Array | undefined;
/**
* Strain peaks of the strain skill in osu!mania.
*/
readonly strains: Float64Array | undefined;
}