# osu!framework: templates, VisualTests and a commercial audio dependency

> A rhythm game engine published as a general C# framework, where the widget layer, texture caching and test harness come ready but the audio dependency is commercial. Adoption decisions hinge on whether you want that opinionated layer at all.

**ppy/osu-framework** — A game framework written with osu! in mind.

- Repository: https://github.com/ppy/osu-framework
- Stars: 2,028 · Forks: 511
- Language: C#
- License: MIT
- Published: 2026-10-13 · Updated: 2026-10-13 · Language: en
- Canonical page: https://hysenlabs.com/projects/ppy-osu-framework

## A rhythm game engine published as a general framework

osu!framework started as the engine under osu! and was published so other projects could take it. The stated goal is to sit past what a normal framework hands you: basic UI elements, text rendering, advanced input handling for textboxes, and performance overlays are all present out of the box, and any osu! code judged useful to other games is expected to move into this repository. The audience is therefore teams that want a designer-facing component tree for a 2D game, not general purpose engine shoppers.

The adopters list shows how wide that turned out. GDEdit is a third-party Geometry Dash editor, Vignette an OpenCV facial recognition tool for Live2D, IWBTM an I Wanna-style platformer with a level editor, DeltaDash a multi-direction lane-based scroller, fluXis a creativity-focused rhythm game, alongside osu! itself. Editors and note charts, in other words, rather than shooters or physics toys. More of them are collected in the discussion thread at `discussions/6771`.

## Generic components, cached textures and fonts loaded at runtime

Wherever graphical components exist, they are displayed with a generic design and left derivable for further customisation. That derivation point is the part game code leans on hardest. Texture caching and font loading are initialised automatically at runtime, so a new screen does not rebuild its own atlas, and the performance overlays that let you judge frame cost are already wired in.

The layout shows how much sits under the framework. Beyond the core osu.Framework/ folder there are osu.Framework.NativeLibs/ for native dependencies, osu.Framework.SourceGeneration/ with its own project under osu.Framework.SourceGeneration.Tests/, osu.Framework.Benchmarks/ for performance work, and osu.Framework.Templates/. Platform folders arrive as osu.Framework.Android/ and osu.Framework.iOS/ with matching props files, and the test tree repeats the split through osu.Framework.Tests.Android/ and osu.Framework.Tests.iOS/.

## Start from templates, not from a dotnet install command

The README contains no dotnet install command, so installation here is a wiki page plus a template clone. Readers are pointed at the getting started wiki resources first, with the project templates in osu.Framework.Templates/ as the direct route, and told they can begin from an empty project or copy a working sample game. Requirements are short: a desktop platform with the .NET 10 SDK, a system-wide ffmpeg installation when running on Linux to support video decoding, and an IDE with intellisense and syntax highlighting.

Building happens inside that IDE rather than on a command line. Visual Studio and Rider users load a platform-specific .slnf file instead of the main .sln, because that keeps the template run configurations reachable, and there are three of them: osu-framework.Desktop.slnf, osu-framework.Android.slnf and osu-framework.iOS.slnf. Static analysis is the one command-line habit the project documents.

```bash
powershell ./InspectCode.ps1
InspectCode.sh
```

Code analysis runs through the PowerShell script or the shell script, and the rest of the path is the Build/Run button of your IDE.

## Three sample game heads and three solution filters

SampleGame/, SampleGame.Desktop/, SampleGame.Android/ and SampleGame.iOS/ mirror the framework's own platform split, and the test projects repeat it. Picking Desktop, Android or iOS is not a runtime switch. It decides which .slnf you open, which platform folder compiles, and which props file, osu.Framework.Android.props or osu.Framework.iOS.props, feeds the build.

Root-level files are where the remaining controls live: global.json sits beside Directory.Build.props, an .editorconfig and a .cfsignore, while Cake is wired in through cake.config with build.ps1 and build.sh. A .git-blame-ignore-revs file and the .idea/, .vscode/ and .config/ directories complete the tooling. That much root configuration is itself a signal about how much of the build runs scripted rather than through IDE dialogs.

## VisualTests is where new components are supposed to be born

The contributing section treats VisualTests as a requirement rather than a convenience. New component development, and where possible bug fixing and debugging of existing components, should always be done under VisualTests, and TestCases exist so one component can be developed in isolation. In practice you open the VisualTests project or configuration before writing the component, not after.

The same section draws a harder boundary. Any contribution, an issue report included, that is created by, documented by, or aided by AI/LLM usage will typically be closed and locked without further discussion, so an automated patch pipeline has no route into this repository. Newcomers get a labelled path instead, through issues carrying a good first issue label and pull requests as the delivery mechanism. Elsewhere the project is unusually open to process feedback, inviting complaints about code structure, libraries or the contribution workflow itself.

## Commercial distribution is decided by BASS, not by the MIT grant

MIT covers the framework source, yet the BASS audio library it depends on is a commercial product that is free for non-commercial use only, so a paid build needs a licence obtained from un4seen.com. That limit lives in the dependency tree rather than in the source code, which is where most readers look first.

Linux adds a packaging obligation of its own: ffmpeg has to be present system-wide to support video decoding, which works against a single self-contained binary on that platform. Then there is the toolchain mismatch worth noticing on a careful read. The requirements ask for the .NET 10 SDK while the same list still recommends Visual Studio 2019+ alongside JetBrains Rider and Visual Studio Code with the EditorConfig and C# plugins. An IDE numbered 2019 is a stale recommendation sitting next to a much newer SDK requirement, and a .travis.yml file survives at the root beside the GitHub workflows.

## Four root scripts override the pinned native dependencies

osu.Framework.NativeLibs/ holds the native binaries, and four root scripts exist to override them: UseLocalVeldrid.ps1 and UseLocalVeldrid.sh for one dependency, UseLocalOpenTabletDriver.ps1 and UseLocalOpenTabletDriver.sh for the other. The pairing pattern is the point. When a fix lands upstream but has not shipped in the pinned package, you point a build at your own working copy rather than wait for a tag.

```bash
UseLocalVeldrid.sh
UseLocalOpenTabletDriver.sh
```

Teams rendering video and reading a drawing tablet get a fast path for testing native changes, and the cost is obvious once you use it: a build assembled this way is not the build anyone else receives. CodeAnalysis/ at the root explains the same pattern for static analysis, and build.sh with build.ps1 covers scripted builds for people working outside the IDE. The last push was on 2026-10-06, with master as the default branch.

## A lower level engine leaves the widget layer to you

If your project needs none of what the framework ships, that difference is the whole decision. A lower level C# engine such as MonoGame offers the window, the game loop and the drawing primitives, and stops there. Composition, textboxes, texture caching, font loading, performance overlays and a VisualTests harness all become code you write and then carry across every platform head. osu!framework asks for the .NET 10 SDK and a platform-specific .slnf file before any of that arrives.

Going the other way, you inherit opinions rather than a neutral toolkit: generic designs everywhere, components meant to be derived rather than restyled, a contribution process that insists on VisualTests, and a flat refusal of AI-assisted patches. Teams writing 2D games with editors, overlays and heavy text entry, exactly what the adopter list contains, get a large head start. Everyone else pays for components they will never open. The README concedes as much about itself, noting that the page covers working on the framework rather than using it, which tells you how much real guidance lives in the wiki.

## Conclusion

Adopt osu!framework for a 2D game with text entry, overlays and an editor, since the widget layer, texture caching, font loading and the VisualTests harness are already paid for. Pass on it when you need only a renderer and a game loop, because you still inherit generic component designs and a contribution process that demands VisualTests. On Linux, budget for a system-wide ffmpeg installation as well. Before writing a component, open VisualTests and confirm it runs, and settle the BASS terms first if the build ships.

## FAQ

### What does osu!framework need before a project will build?

A desktop platform with the .NET 10 SDK, plus a system-wide ffmpeg installation on Linux so video decoding works. The README also asks for an IDE with intellisense and syntax highlighting, such as Visual Studio 2019+, Jetbrains Rider or Visual Studio Code with the EditorConfig and C# plugin.

### Can osu!framework be used in a commercial game?

The framework source is MIT, but the BASS audio library it depends on is a commercial product that is free for non-commercial use. A commercial build needs a valid BASS licence obtained from un4seen.com.

### How do you build osu!framework without an IDE?

Code analysis can be run with powershell ./InspectCode.ps1 or InspectCode.sh from the command line, and Cake scripts build.ps1 and build.sh handle scripted builds. Everything else is documented as Build/Run inside Visual Studio or Rider using a platform-specific .slnf file rather than the main .sln.

### What is VisualTests in osu!framework?

It is a project and configuration the contributing guide requires. New component development, and where possible bug fixing and debugging, should always be done under VisualTests, with TestCases used to develop a single component in isolation.

### Does osu!framework accept contributions written with an AI assistant?

No. Any contribution, including an issue report, created by, documented by, or aided by AI/LLM usage will typically be closed and locked without further discussion, and the project states that it believes in human contributions.

## Sources

- [Issues](https://github.com/ppy/osu-framework/issues)
- [License: MIT](https://github.com/ppy/osu-framework/blob/master/LICENSE)
- [ppy/osu-framework on GitHub](https://github.com/ppy/osu-framework)
- [README](https://github.com/ppy/osu-framework/blob/master/README.md)
- [Releases](https://github.com/ppy/osu-framework/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ppy-osu-framework
