#osu #beatmap #calc #resources #vsrg

bin+lib rhythm-open-exchange

A try to create the ffmpeg of vsrg

9 releases (4 breaking)

Uses new Rust 2024

new 0.6.2 Feb 3, 2026
0.4.1 Jan 19, 2026
0.3.3 Jan 10, 2026
0.2.2 Dec 12, 2025
0.1.3 Dec 10, 2025

#143 in Configuration

Download history 39/week @ 2026-01-06 31/week @ 2026-01-13 3/week @ 2026-01-20

73 downloads per month
Used in minacalc-rs

MIT license

2.5MB
6.5K SLoC

Rhythm Open Exchange (ROX)

A universal, compact binary format for Vertical Scrolling Rhythm Games (VSRG). ROX serves as a pivot format for converting between different rhythm game formats like osu!mania, Quaver, StepMania, Etterna, and BMS.

"so i'm just trying to make a ffmpeg of vsrg game idk where i'm going"

Overview

ROX is designed to be:

  • Compact — Uses rkyv zero-copy serialization with zstd compression
  • Precise — Microsecond timestamp precision (i64) for accurate timing
  • Universal — Supports all common VSRG features across different games
  • Verifiable — BLAKE3 content hashing for integrity verification

Features

  • Support for any key count (4K, 7K, 9K, etc.)
  • Multiple note types: Tap, Hold (LN), Burst/Roll, Mine
  • BPM changes and Scroll Velocity (SV) modifications
  • Keysound support for BMS/O2Jam style charts
  • Comprehensive metadata (title, artist, difficulty, tags, etc.)
  • Content-based hashing for chart identification
  • C# bindings for Unity/Godot/.NET integration

Installation

Rust

Add to your Cargo.toml:

[dependencies]
rhythm-open-exchange = "0.5"

C# / .NET

dotnet add package RhythmOpenExchange --version 0.5.0

From Source

git clone https://github.com/Glubus/Rhythm-Open-Exchange.git
cd Rhythm-Open-Exchange
cargo build --release

Quick Start

Creating a Chart

use rhythm_open_exchange::{RoxChart, Note, TimingPoint, Metadata};

// Create a 4K chart
let mut chart = RoxChart::new(4);

// Set metadata
chart.metadata = Metadata {
    title: "My Song".into(),
    artist: "Artist Name".into(),
    creator: "Your Name".into(),
    difficulty_name: "Hard".into(),
    audio_file: "audio.ogg".into(),
    ..Default::default()
};

// Add a BPM timing point at the start
chart.timing_points.push(TimingPoint::bpm(0, 180.0));

// Add notes (time in microseconds, column index)
chart.notes.push(Note::tap(1_000_000, 0));      // Tap at 1s, column 0
chart.notes.push(Note::tap(1_500_000, 1));      // Tap at 1.5s, column 1
chart.notes.push(Note::hold(2_000_000, 500_000, 2)); // Hold at 2s, 0.5s duration

Auto-Converting Formats

use rhythm_open_exchange::{auto_decode, auto_encode, auto_convert};

// Load any supported format (auto-detected from extension)
let chart = auto_decode("chart.osu")?;

// Export to any format
auto_encode(&chart, "chart.sm")?;

// Or convert directly
auto_convert("input.osu", "output.qua")?;

C# Usage

using RhythmOpenExchange;

// Load a chart
byte[] data = File.ReadAllBytes("chart.osu");
using var chart = RoxChart.FromBytes(data);

Console.WriteLine($"{chart.Title} by {chart.Artist}");
Console.WriteLine($"{chart.KeyCount}K - {chart.NoteCount} notes");

// Convert to StepMania
string? sm = chart.ToString(RoxFormat.Sm);
File.WriteAllText("chart.sm", sm);

Supported Formats

| ROX (native binary) | .rox | ✅ | ✅ | | osu!mania | .osu | ✅ | ✅ | | osu!taiko | .osu | ✅ | ❌ | | StepMania / Etterna | .sm/.ssc | ✅ | ✅ | | Quaver | .qua | ✅ | ✅ | | Friday Night Funkin' | .json | ✅ | ✅ | (Experimental) |

Planned

  • Malody (.mc)
  • BMS (.bms/.bme/.bml)
  • O2Jam (.ojn/.ojm)
  • Clone Hero (.chart/.mid)

Multi-Language Support

  • C# / .NET - Full feature parity, located in bindings/ffi/csharp.
  • Python - High-performance bindings in bindings/ffi/python.
  • WebAssembly - Optimized for browser-based tools, located in bindings/wasm.
  • C/C++ - Stable C-API via UniFFI in bindings/ffi.

CLI Tool

# Convert a file
cargo run --bin rox -- convert input.osu output.sm

# Validate a file
cargo run --bin rox -- validate chart.sm

Performance

ROX is built for extreme efficiency. Benchmarks on a 50,000 note chart (4K):

Metric .osu Format .rox Format Improvement
File Size 1.55 MB 50 KB 97% Smaller
Decode Speed ~26 ms ~0.82 ms 30x Faster
Encode Speed N/A ~1.69 ms Lightning Fast

Development

Prerequisites

  • Rust 1.85+ (2024 edition)
  • Cargo
  • (Optional) just - for running QA checks

Building

cargo build --release

Running QA Checks

# If you have 'just' installed
just qa

# Or manually
cargo check --all-targets --all-features
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features

Project Structure

rhythm-open-exchange/
├── src/                    # Core library (Rust)
├── bindings/
│   ├── api/                # Stable C-API / FFI (Native)
│   ├── csharp/             # C# Bindings
│   ├── python/             # Python Bindings
│   └── wasm/               # WebAssembly Bindings
├── tests/                  # Integration tests
├── assets/                 # Test assets
└── justfile                # QA automation

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run QA checks (just qa or manual commands above)
  4. Commit your changes (git commit -m 'Add amazing feature')
  5. Push and open a Pull Request

License

This project is licensed under the MIT License.

See Also

Dependencies

~11–15MB
~218K SLoC