minacalc-rs 0.2.0

Rust bindings for MinaCalc C++ library (Etterna rating calculator)
Documentation

MinaCalc Rust Bindings

Crates.io Documentation License

Safe and idiomatic Rust bindings for the MinaCalc C++ library, providing rhythm game difficulty calculation capabilities.

Overview

MinaCalc is a sophisticated difficulty calculator for rhythm games like Stepmania, and similar games. This Rust crate provides a safe, memory-managed interface to the original C++ library, allowing you to calculate:

  • MSD (Mina Skill Difficulty) scores for all music rates (0.7x to 2.0x)
  • SSR (Single Song Rating) scores for specific rates and score goals
  • Multiple skillset evaluations (Stream, Jumpstream, Handstream, Stamina, etc.)

Features

  • Memory Safety: RAII-based resource management prevents memory leaks
  • Error Handling: Comprehensive error handling with descriptive messages
  • Cross-Platform: Supports Windows (MSVC), Linux (GCC/Clang), and macOS
  • C++17 Compatibility: Full support for modern C++ features
  • Zero-Cost Abstractions: Minimal runtime overhead
  • Comprehensive Testing: Unit tests and integration tests included

Installation

Prerequisites

  • Rust: 1.70+ (install via rustup)
  • C++ Compiler:
    • Windows: MSVC (Visual Studio 2019+)
    • Linux: GCC 7+ or Clang 6+

Quick Start

# Add to your Cargo.toml

cargo add minacalc-rs


# Or clone and build from source

git clone https://github.com/your-username/minacalc-rs.git

cd minacalc-rs

cargo build --release

API Reference

Core Types

Calc

Main calculator instance with automatic resource management.

impl Calc {
    /// Creates a new calculator instance
    pub fn new() -> Result<Self, &'static str>
    
    /// Gets the calculator version
    pub fn version() -> i32
    
    /// Calculates MSD scores for all music rates (0.7x to 2.0x)
    pub fn calc_msd(&self, notes: &[Note]) -> Result<MsdForAllRates, &'static str>
    
    /// Calculates SSR scores for specific rate and goal
    pub fn calc_ssr(&self, notes: &[Note], music_rate: f32, score_goal: f32) -> Result<SkillsetScores, &'static str>
}

Note

Represents a single note row in the rhythm game.

pub struct Note {
    pub notes: u32,      // Number of notes at this time position
    pub row_time: f32,   // Time position in seconds
}

SkillsetScores

Difficulty scores for different gameplay skills.

pub struct SkillsetScores {
    pub overall: f32,     // Overall difficulty
    pub stream: f32,      // Stream patterns
    pub jumpstream: f32,  // Jumpstream patterns
    pub handstream: f32,  // Handstream patterns
    pub stamina: f32,     // Stamina requirements
    pub jackspeed: f32,   // Jack speed
    pub chordjack: f32,   // Chord jack patterns
    pub technical: f32,   // Technical patterns
}

MsdForAllRates

MSD scores for all supported music rates.

pub struct MsdForAllRates {
    pub msds: [SkillsetScores; 14], // 14 rates: 0.7x, 0.8x, ..., 2.0x
}

Error Handling

All functions return Result with descriptive error messages:

Error Message Description
"Failed to create calculator" C++ library initialization failed
"No notes provided" Empty note array provided
"Music rate must be positive" Invalid music rate (≤ 0)
"Score goal must be between 0 and 100" Invalid score goal

Project Structure

minacalc-rs/
├── Cargo.toml              # Rust project configuration
├── build.rs                # C++ compilation and bindgen setup
├── API.h                   # C++ header file
├── API.cpp                 # C++ implementation
├── NoteDataStructures.h    # C++ data structures
├── MinaCalc/               # Original MinaCalc C++ library
├── src/
│   ├── lib.rs              # Library entry point
│   ├── bindings.rs         # Auto-generated FFI bindings
│   └── wrapper.rs          # Idiomatic Rust interface
├── examples/
│   ├── basic_usage.rs      # Basic usage example
│   └── osu.rs              # osu! integration example
├── assets/
│   └── test.osu            # Test beatmap file
└── README.md               # This file

Building from Source

Development Setup

# Clone repository

git clone https://github.com/your-username/minacalc-rs.git

cd minacalc-rs


# Install dependencies

cargo build


# Run tests

cargo test


# Run examples

cargo run --example basic_usage

cargo run --example osu

Cross-Platform Compilation

The build system automatically detects your platform and uses appropriate compiler flags:

  • Windows (MSVC): Uses /std:c++17
  • Linux/macOS (GCC/Clang): Uses -std=c++17

Troubleshooting

Common Issues

  1. MSVC not found: Install Visual Studio 2019+ with C++ workload
  2. Bindgen errors: Ensure you have libclang installed
  3. C++17 not supported: Update your compiler to a C++17-compatible version

Platform-Specific Notes

  • Windows: Requires Visual Studio Build Tools or full Visual Studio
  • Linux: May need libclang-dev package: sudo apt install libclang-dev
  • macOS: Requires Xcode Command Line Tools: xcode-select --install

Testing

# Run all tests

cargo test


# Run tests with output

cargo test -- --nocapture


# Run specific test

cargo test test_calc_version

Examples

See the examples/ directory for complete working examples:

  • basic_usage.rs: Simple MSD/SSR calculation
  • osu.rs: Integration with osu! beatmap parsing

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Acknowledgments

  • Original MinaCalc library developers
  • Rust FFI and bindgen communities
  • Rhythm game community for feedback and testing

Changelog

v0.1.1

  • Fixed MSVC compilation issues
  • Improved cross-platform compatibility
  • Added comprehensive error handling
  • Translated documentation to English

v0.1.0

  • Initial release
  • Basic MSD/SSR calculation support
  • Memory-safe Rust interface

Support