BMS · Be-Music Source

超軽量Rust製BMSプレイヤー

バイナリサイズを最優先の指標とし、外部ランタイムのインストール不要の単一実行ファイルで動作するBMSプレイヤーです。
オーディオハードウェアのクロックに基づく決定論的な判定と、ノンブロッキングUIを提供します。

Windows専用 • Direct3D 11 • 無料オープンソース • バイナリのリリースは準備中です

主な機能

🪶

超軽量な単一実行ファイル

コーデックパック、C++ランタイムDLL、シェーダーコンパイラ、組み込みDBは不要で、.exe一つで動作します。プレイヤー本体はリリースビルドで約2.85 MBです。

🎯

決定論的な判定

判定とノーツ位置を、オーディオハードウェアが実際に再生したサンプル数から計算します。フレームレートの変動やラグがあっても判定誤差は蓄積しません。

⚡

ノンブロッキングUI

ファイルI/Oとオーディオデコードはバックグラウンドスレッドが担当し、キー音はロード時にPCMへ事前デコードするため、プレイ中のデコードは一切ありません。

🎹

幅広い譜面対応

BMS / BME / BML / PMSに対応し、5鍵・7鍵・9鍵・14鍵(DP)を自動判別します。BPM変化、#STOP、ロングノーツ(LNOBJ/LNType1)を処理します。

🎛️

プレイオプション

Hi-Speed(0.5x~10.0x)、判定オフセット、レーンカバー、サドゥン、Mirror / Random / R-Random / S-Random、Groove · Survival · EX-Hard · Easyゲージに対応します。

🎬

リプレイ & 練習

リプレイの録画/再生(.rep)、小節早送りの練習モード、オートプレイ、キーコンフィグUIを内蔵しています。

設計原則

01

オーディオクロックがマスター

判定とノーツ描画位置のどちらも、AudioClock(実際の再生サンプル数)を唯一の基準にします。

02

ロックフリー・ゼロアロケーションのオーディオスレッド

オーディオコールバックはミューテックスやヒープ確保なしに、SPSCリングバッファ(rtrb)でコマンドを受け取ります。

03

Direct3D 11単一レンダラー

OS標準のDirect3D 11を外部クレートなしで直接呼び出し、共有アトラスで画面の大部分を1回のドローコールで描画します。GPUがない場合はWARP(CPUラスタライザ)で同じパイプラインを実行します。

バイナリサイズ

beetle-app.exe

~2.85 MB

BMSプレイヤー

bpm.exe

~2.67 MB

パッケージマネージャー CLI

bpm-gui.exe

~4.60 MB

パッケージマネージャー GUI

opt-level="z"、LTO、panic="abort"、strip適用の単一静的バイナリです(2026-10-04測定)。組み込みのサブセットフォント(Noto Sans KR/JP、約1.5 MB)が、目標の1 MB未満を超える主な理由です。

パッケージマネージャー (bpm)

BMSフォルダを標準の.bmspアーカイブにまとめてインストール・バージョン管理し、差分(.bmdp)パッチでアトミックに更新できます。CLI(bpm)とスタンドアロンGUI(bpm-gui)を提供します。

bpm import ./songs/my_song/
bpm pack ./songs/my_song/ -o my_song-1.0.0.bmsp
bpm install ./my_song-1.0.0.bmsp
bpm update patch-1.1.0.bmdp
bpm list

はじめに

現在はGitHubリポジトリから自分でビルドしてお使いください。(Windows上のRustツールチェーンが必要です)

STEP 01

ソースを取得

git clone https://github.com/orphera/beetle でソースを取得します。

STEP 02

リリースビルド

cargo build --release を実行すると、target/release/ に実行ファイルが作られます。

STEP 03

曲を登録して起動

bpm import <BMSフォルダ> で曲を登録し、beetle-app.exe を起動します。

💡 基本操作: 選曲画面で ↑↓ 移動 · Enter 開始 · Tab プレイオプション · F12 キーコンフィグ。7鍵の標準配置は LShift(スクラッチ) + Z S X D C F V です。
GitHubリポジトリ ↗ Issues / フィードバック ↗