Skip to main content

What are Rulesets?

Rulesets are osu!‘s architecture for creating custom gameplay modes. They allow developers to harness the power of the osu! beatmap library, game engine, and UI framework to create entirely new styles of gameplay. Each ruleset defines:
  • How beatmaps are converted and interpreted
  • What hit objects exist and how they’re displayed
  • Input handling and player interaction
  • Scoring and judgement systems
  • Difficulty and performance calculation
  • Available mods and their effects

Core Architecture

Every custom ruleset must inherit from the Ruleset base class and implement its abstract methods:
public abstract class Ruleset
{
    // Identity
    public abstract string Description { get; }
    public abstract string ShortName { get; }
    
    // Core gameplay components
    public abstract DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod>? mods = null);
    public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap);
    public abstract DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap);
    
    // Mod system
    public abstract IEnumerable<Mod> GetModsFor(ModType type);
}
Set RulesetAPIVersionSupported to CURRENT_RULESET_API_VERSION to ensure compatibility:
public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;

Ruleset Components

1. DrawableRuleset

The visual gameplay implementation that renders hit objects and manages playfield interaction. Location: osu.Game.Rulesets.UI.DrawableRuleset<TObject> Responsibilities:
  • Manages the playfield and its components
  • Handles frame stability and timing
  • Processes input through the input manager
  • Coordinates with the scoring system

2. HitObjects

Define the elements players interact with during gameplay. Base class: osu.Game.Rulesets.Objects.HitObject Key properties:
  • StartTime - When the object appears
  • Samples - Audio samples to play
  • Implement interfaces like IHasPosition, IHasDuration for additional behavior

3. BeatmapConverter

Converts standard osu! beatmaps into ruleset-specific hit objects. Base class: osu.Game.Beatmaps.BeatmapConverter<T> Methods:
  • CanConvert() - Check if beatmap is compatible
  • ConvertHitObject() - Transform each hit object

4. DifficultyCalculator

Calculates star rating and difficulty attributes. Base class: osu.Game.Rulesets.Difficulty.DifficultyCalculator Required methods:
  • CreateDifficultyAttributes() - Generate difficulty results
  • CreateDifficultyHitObjects() - Prepare objects for analysis
  • CreateSkills() - Define difficulty calculation skills

5. Mods

Gameplay modifiers that alter mechanics, difficulty, or automation. Base class: osu.Game.Rulesets.Mods.Mod Common mod types:
  • ModType.DifficultyIncrease - Makes the game harder
  • ModType.DifficultyReduction - Makes the game easier
  • ModType.Automation - Autoplay and assist mods
  • ModType.Conversion - Changes gameplay mechanics
  • ModType.Fun - Visual or audio effects

Getting Started

osu! provides official ruleset templates to help you get started quickly:
1

Install the templates

Templates are available in the osu! repository.
dotnet new install ppy.osu.Game.Templates
2

Create your ruleset

Choose between two template types:Freeform ruleset - For gameplay like osu!standard or osu!mania
dotnet new ruleset -n MyRuleset
Scrolling ruleset - For gameplay like osu!taiko or osu!catch
dotnet new ruleset-scrolling -n MyRuleset
3

Build and test

cd MyRuleset
dotnet build
dotnet run --project osu.Game.Rulesets.MyRuleset.Tests

Example: Pippidon Ruleset

The included example ruleset demonstrates core concepts:
osu.Game.Rulesets.Pippidon/PippidonRuleset.cs
public class PippidonRuleset : Ruleset
{
    public override string Description => "gather the osu!coins";
    public override string ShortName => "pippidon";

    public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) =>
        new DrawablePippidonRuleset(this, beatmap, mods);

    public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) =>
        new PippidonBeatmapConverter(beatmap, this);

    public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) =>
        new PippidonDifficultyCalculator(RulesetInfo, beatmap);

    public override IEnumerable<Mod> GetModsFor(ModType type)
    {
        switch (type)
        {
            case ModType.Automation:
                return new[] { new PippidonModAutoplay() };
            default:
                return Array.Empty<Mod>();
        }
    }

    public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;
}

Key Interfaces

Many components use interfaces to provide specific functionality:

Hit Object Interfaces

  • IHasPosition - Objects with X/Y coordinates
  • IHasDuration - Objects with EndTime
  • IHasPath - Slider-like objects with curves
  • IHasComboInformation - Combo counter behavior
  • IHasRepeats - Repeating patterns

Mod Interfaces

  • IApplicableToHitObject - Modify hit objects
  • IApplicableToDifficulty - Adjust difficulty settings
  • IApplicableToDrawableRuleset - Modify playfield
  • IApplicableToScoreProcessor - Change scoring
  • IApplicableToRate - Alter playback speed
Mod interfaces determine when and how mods are applied. Implementing the wrong interface can cause your mod to not work or apply at the wrong time.

Community Rulesets

Explore existing custom rulesets for inspiration and learning:
  • Custom Ruleset Directory
  • Browse community-created gameplay modes
  • Learn from real-world implementations
  • Share your own creations

Next Steps

Creating a Ruleset

Step-by-step guide to building your first ruleset

Hit Objects

Define gameplay elements and their behavior

Mods System

Create gameplay modifiers and effects

Difficulty Calculation

Implement star rating and performance points

Build docs developers (and LLMs) love