A vertical scrolling rhythm game mode with multiple key configurations
osu!mania is a vertical scrolling rhythm game mode (VSRG) where notes fall down columns and players press corresponding keys when notes reach the judgement line. The mode supports 1-18 keys across single or dual stages.
Simple objects requiring a single key press at the correct time.Source:osu.Game.Rulesets.Mania/Objects/Note.cs:12
/// <summary>/// Represents a hit object which has a single hit press./// </summary>public class Note : ManiaHitObject{ public override Judgement CreateJudgement() => new ManiaJudgement();}
Notes inherit column assignment from ManiaHitObject:
public int Column { get; set; } // Which lane the note appears in
Long notes (LNs) requiring sustained key press.Source:osu.Game.Rulesets.Mania/Objects/HoldNote.cs:19
/// <summary>/// Represents a hit object which requires pressing, holding, and releasing a key./// </summary>public class HoldNote : ManiaHitObject, IHasDuration{ public double Duration { get; set; } public double EndTime => StartTime + Duration; public HeadNote Head { get; protected set; } public TailNote Tail { get; protected set; } public HoldNoteBody Body { get; protected set; } public bool PlaySlidingSamples { get; init; }}
Hold Note Components:
Head: Initial press (judged on timing)
Body: Sustained hold (invisible judgement tracker)
public enum PlayfieldType{ /// <summary> /// Columns are grouped into a single stage. /// Number of columns lies at (item - Single). /// </summary> Single = 0, /// <summary> /// Columns are grouped into two stages. /// Overall number of columns lies at (item - Dual). /// </summary> Dual = 1000,}
Available Variants (ManiaRuleset.cs:330-339):
public override IEnumerable<int> AvailableVariants{ get { // Single stage: 1K through 10K for (int i = 1; i <= MAX_STAGE_KEYS; i++) yield return (int)PlayfieldType.Single + i; // Dual stage: 2K+2K through 10K+10K for (int i = 2; i <= MAX_STAGE_KEYS * 2; i += 2) yield return (int)PlayfieldType.Dual + i; }}
public override BeatmapDifficulty GetAdjustedDisplayDifficulty(IBeatmapInfo beatmapInfo, IReadOnlyCollection<Mod> mods){ BeatmapDifficulty adjustedDifficulty = base.GetAdjustedDisplayDifficulty(beatmapInfo, mods); // In mania, hit windows are independent of track playback rate // However, Hard Rock and Easy apply multipliers to hit window durations directly // rather than to OD itself double perfectHitWindow = IBeatmapDifficultyInfo.DifficultyRange( adjustedDifficulty.OverallDifficulty, ManiaHitWindows.PERFECT_WINDOW_RANGE); if (mods.Any(m => m is ManiaModHardRock)) perfectHitWindow /= ManiaModHardRock.HIT_WINDOW_DIFFICULTY_MULTIPLIER; else if (mods.Any(m => m is ManiaModEasy)) perfectHitWindow /= ManiaModEasy.HIT_WINDOW_DIFFICULTY_MULTIPLIER; adjustedDifficulty.OverallDifficulty = (float)IBeatmapDifficultyInfo.InverseDifficultyRange( perfectHitWindow, ManiaHitWindows.PERFECT_WINDOW_RANGE); return adjustedDifficulty;}
Unlike other modes, mania hit windows are not affected by rate-changing mods like Double Time. This is intentional to preserve difficulty.
Displayed as Circle Size but represents number of keys:
var originalDifficulty = new BeatmapDifficulty(beatmapInfo.Difficulty){ CircleSize = ManiaBeatmapConverter.GetColumnCount( LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(beatmapInfo), [])};var adjustedDifficulty = GetAdjustedDisplayDifficulty(beatmapInfo, mods);yield return new RulesetBeatmapAttribute("Key Count", @"KC", originalDifficulty.CircleSize, adjustedDifficulty.CircleSize, 18){ Description = "Affects the number of key columns on the playfield."};
Key conversion mods (1K-10K) change the key count:
Source:ManiaRuleset.cs:341-353Key bindings are generated based on variant:
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0){ switch (getPlayfieldType(variant)) { case PlayfieldType.Single: return new SingleStageVariantGenerator(variant).GenerateMappings(); case PlayfieldType.Dual: return new DualStageVariantGenerator(getDualStageKeyCount(variant)) .GenerateMappings(); } return Array.Empty<KeyBinding>();}
Common layouts:
4K: D, F, J, K
7K: S, D, F, Space, J, K, L
Dual 4K: D, F, J, K (left) + numpad keys (right)
Players often customize key bindings to match their finger positioning preferences.
new MultiMod( new ManiaModKey1(), new ManiaModKey2(), new ManiaModKey3(), new ManiaModKey4(), new ManiaModKey5(), new ManiaModKey6(), new ManiaModKey7(), new ManiaModKey8(), new ManiaModKey9(), new ManiaModKey10()),
These mods force a specific key count regardless of beatmap settings.