SteonMod
MashupSource only

osu! in Minecraft

Play osu!standard inside Minecraft: a Fabric mod for 1.20.1.

Source Follow

Play osu!standard inside Minecraft — a Fabric mod for 1.20.1 See the README below for details.

osu! in Minecraft

在 Minecraft 里直接游玩 osu!standard 谱面的 Fabric Mod。

Minecraft → Esc → 暂停菜单 → osu! → 选歌 → 游玩 → Esc → 回到 Minecraft

打开 osu! 界面时 Minecraft 世界会被冻结(单人存档下集成服务器同样暂停), osu! 拥有自己的场景栈、光标、输入与时钟,退出后 Minecraft 恢复原状。


1. 它能做什么

功能状态
暂停菜单中的 osu! 按钮(另有快捷键 O)✅
解析官方 .osu 格式(v3 – v14 及 lazer v128+)✅
.osz 拖入自动解包导入✅
选歌界面:搜索、上下浏览、音频试听✅
Hit circle / Slider(含 tick、repeat、legacy tail)/ Spinner✅
判定窗口、连击、分数(ScoreV1)、准确率、评级✅
Slider 路径:Linear / Bezier / Catmull / Perfect curve✅
绿线变速(SV)、NaN 关闭 slider tick✅
叠加(stacking)、combo 颜色、AR/CS/OD/HP 全部按官方公式✅
判定动画、approach circle、follow circle、hit error bar✅
暂停、重开(R)、跳过前奏(Space)、结算界面✅
音频:.ogg / .wav / .mp3✅
程序化生成的皮肤与打击音(无需任何外部素材)✅
自定义打击音:谱面自带 / 全局皮肤文件夹(.wav .ogg .mp3)✅
sample set(normal/soft/drum)、custom bank、逐音量、逐节点 edge sounds✅
游戏内设置:总/音乐/打击音三档音量、按键绑定、偏移、背景暗度等✅
Mod:EZ NF HT / HR SD PF DT NC HD FL / RX AP SO AT✅
osu!direct:搜索镜像站并直接下载导入✅
随 mod 附带 5 张谱面,首次启动自动解包✅
osu!taiko / catch / mania❌ 目前只支持 osu!standard
皮肤(osu! .osk / 图片素材)❌ 目前是程序化生成的一套
排行榜、回放、在线功能❌ 未实现

2. 安装

  1. 安装 Minecraft 1.20.1 + Fabric Loader 0.15+ + Fabric API。
  2. 把 osu-mc-1.0.0.jar 放进 .minecraft/mods/。
  3. 启动游戏。首次启动会把随包附带的谱面解包到 .minecraft/osu/Songs/:
谱面Mapper
kimono club - HIGHBALL DAY [AFTER I REACHED CHALLENGER]Sakagami Tomoyo
Hanakami Ryu - Near Under Seven [Heaven Burns Blue]Sakagami Tomoyo
stargaze shelter - Heisei (Mode: Tsukimiya Toto) [x_x]Sakagami Tomoyo
Sorihiko - doyobi [Extra]Sorihiko
iKz - Wo Yao Mai Mai Mai [Extra]Sorihiko

已经存在的文件夹不会被覆盖,删掉的也不会自己回来。

导入你自己的谱面

两种方式,任选其一:

  • 拖 .osz:把 .osz 丢进 .minecraft/osu/,进入选歌界面时会自动解包到

    Songs/,原文件移动到 osu/imported/。 (选歌界面左下角那串路径可以点,直接打开 Songs 文件夹。)

  • 直接用现有的 osu! 安装:编辑 .minecraft/config/osumc.json,把

    songsDirectory 指向你的 osu! Songs 文件夹,例如:

  "songsDirectory": "C:\\Users\\you\\AppData\\Local\\osu!\\Songs"

进入选歌界面按 F5 重新扫描。

osu!direct

选歌界面按 F4(或点右上角的 direct)。打字 → Enter 搜索 → 上下选 → Enter 下载, 也可以直接点两下某一行。下好会自动解包进 Songs 并重扫,不用退出游戏。

用的是公开镜像站(默认 Sayobot,国内网络下通常最快;设置里可换成 osu.direct)—— 官方 osu! API 要自己注册 OAuth 应用,对一个 mod 来说太重了。镜像站是免费的志愿服务, 所以这里按 Enter 才搜(不是边打边搜)、一次只下一个。

换掉附带的谱面

附带哪些谱面完全由资源目录决定,代码里没有任何一张的名字:

  1. 把 .osz 丢进 src/main/resources/assets/osumc/songs/;
  2. 在同目录的 index.txt 里写上文件名,一行一个(# 开头是注释);
  3. 重新构建。

想一张都不带就把 index.txt 清空——代码认得空列表。 注意 .osz 里是连歌一起打包的,随 mod 分发出去的东西要自己确认有没有这个权利。


3. 操作

场景按键
打开 osu!暂停菜单的 osu! 按钮,或游戏中按 O
选歌↑ ↓ 浏览,直接打字搜索,Backspace 删除,Enter 开始,F5 重扫
Mod选歌界面按 F2 或点右上角 mods;Backspace 清空,Esc 关闭
osu!direct选歌界面按 F4 或点右上角 direct;打字 → Enter 搜索 → Enter 下载
打开 Songs 文件夹点选歌界面左下角那串路径
设置选歌界面按 F1 或点右上角 options;游玩中 Esc → Options
游玩Z / X(可配置)或鼠标左右键点击,鼠标移动瞄准
跳过前奏Space
重开R
暂停 / 返回Esc(游玩中 → 暂停;选歌中 → 退出 osu! 回到 Minecraft)

4. 设置

游戏内就能改:选歌界面按 F1(或点右上角的 options), 游玩中 Esc → Options 会以浮层形式打开——不会把正在玩的谱面卸掉,关掉浮层就能接着打。 拖动音量滑块时声音会实时跟着变,改完自动存盘。

按键绑定点一下方框再按目标键即可;Esc 取消绑定。

三档音量是相乘关系:实际音乐音量 = masterVolume × musicVolume, 实际打击音音量 = masterVolume × effectVolume。

Hitsound latency(8–60 ms,默认 15 ms)是打击音输出缓冲的大小。 已经交给声卡的音频是改不动的,所以缓冲多大,打击音最小延迟就是多少:越小越跟手。 但太小了机器喂不满缓冲,声音会断续 / 发抖——听到这种情况就往上调,20–30 ms 一般就稳了。 拖完滑块松手时会自动重开音频输出,不用重启游戏。

也可以直接编辑 .minecraft/config/osumc.json:

键说明默认
audioOffsetMs全局音频偏移,正值表示物件更晚出现0
masterVolume总音量,乘在下面两个上面0.8
musicVolume / effectVolume音乐 / 打击音音量0.7 / 0.6
hitSoundLatencyMs打击音输出缓冲大小(8–60);越小越跟手,太小会断音15
backgroundDim游玩时背景变暗程度0.75
leadInMs第一个物件前的最短倒计时;谱面自己的 AudioLeadIn 更长时以谱面为准2000
key1 / key2敲击键的 GLFW keycode(Z = 90,X = 88)90 / 88
mouseButtonsTap鼠标左右键是否也算敲击true
hideSystemCursor游玩时隐藏系统光标true
sliderRenderModeFRAMEBUFFER(重叠正确)或 SIMPLE(兼容回退)FRAMEBUFFER
snakingSliders滑条是否随淡入沿路径画出来true
muteGameAudio打开 osu 界面时静音 Minecraft(服务器上很有用)true
damageAlerts在 osu 界面里受到伤害时弹提示true
show300Judgements打出 300 时是否弹判定字(100/50/miss 不受影响)false
mods选中的 mod,如 "HDDT";在选歌界面按 F2 改""
cursorSize光标大小倍率1.0
mirrorosu!direct 用哪个镜像:sayobot / osudirect"sayobot"
songsDirectory自定义 Songs 目录(留空用默认)""

如果 slider 在你的显卡上显示异常,把 sliderRenderMode 改成 SIMPLE。 设置里那一行如果显示成 Slider rendering (unavailable),说明离屏缓冲在你的显卡上初始化失败、 已经自动退回兼容模式了(日志里会有一条 Offscreen slider rendering failed 的 warn)。


5. Mod

选歌界面按 F2(或点右上角的 mods)打开,点一下开关,Backspace 清空,Esc 关闭。 选择会存进配置,下次进来还在;结算界面和游玩 HUD 都会显示当前 mod。

冲突是选进来时就解决掉的:开着 HT 再点 DT,HT 自己就没了,不会出现不可能的组合。

Mod效果倍率
降低难度EZCS/AR/OD/HP 全部 ×0.5,另外给 2 条命0.50
NF不会失败0.50
HT0.75 倍速,音调不变0.30
提高难度HRHP/OD/AR ×1.4、CS ×1.3(上限 10),谱面上下翻转1.06
SDmiss 一次直接结束1.00
PF非 300 直接结束1.00
DT1.5 倍速,音调不变1.12
NC1.5 倍速并升调1.12
HD没有 approach circle,物件提前淡出1.06
FL只能看见光标周围,连击越高范围越小1.12
特殊RX不用点,只需要瞄不计分
AP不用瞄,只需要点不计分
SO转盘自动完成0.90
AT全自动演示不计分

数值全部来自 ppy/osu(ModHardRock.ADJUST_RATIO = 1.4、CS 单独的 1.3、ModEasy.ADJUST_RATIO = 0.5、 HD 的 0.4 / 0.3 淡入淡出系数、FL 的 125 与 100/200 连击缩放),倍率用的是 osu!stable 的那套, 因为这里的计分是 ScoreV1。HD/FL 会让 S / SS 变成银色。

DT 和 HT 不升降调,只有 NC 升调——这是 osu! 的行为(ModDoubleTime.AdjustPitch 默认 false, 只有 Nightcore 打开它)。所以 DT/HT 走 WSOLA 时间拉伸,NC 走重采样。 两者都不靠改输出采样率实现:1.5 倍的 44.1kHz 是 66150Hz,很多声卡直接拒绝。

"不能失败"现在是 NF 这个 mod,设置里那一项已经去掉了——默认会掉血会失败, 想关就在 F2 里点 NF。


6. 自定义打击音

内置的打击音是代码合成的(osu! 原版素材不可再分发),但可以直接换掉。 把音频文件丢进 .minecraft/osu/Skin/,文件名按 osu! 的约定来:

文件名用途
normal-hitnormal基础敲击声
normal-hitwhistlewhistle 叠加音
normal-hitfinishfinish 叠加音
normal-hitclapclap 叠加音
normal-slidertick滑条 tick
normal-sliderslide按住滑条时的循环音
normal-sliderwhistle同上,滑条带 whistle 时用
combobreak断连
spinnerspin转盘
menuhit / menuback选歌界面

扩展名 .wav / .ogg / .mp3 都行。把 normal 换成 soft 或 drum 就是另外两套 sample set——谱面会按 timing point 逐段切换,想全覆盖就三套都放。 名字后面加数字是 custom sample bank,例如 normal-hitnormal2.wav。

优先级:谱面自己文件夹里的 > 这个皮肤文件夹 > 内置合成音。 所以谱师配好的逐图 hitsound 仍然按他的设计播放。没提供的那些自动回落到内置音, 不需要凑齐一整套。

两条值得知道的规则:

  • 只放 normal- 一套也够用。 谱面切到 soft / drum 时,如果你没提供对应文件,

    会先回落到你的 normal- 版本,而不是直接掉回内置合成音——否则一首歌里音色会突变。

  • 空音频文件 = 主动静音。 很多皮肤用零采样的 .ogg 把循环滑条音或

    slidertick2 静掉,这是有意为之,会被当作静音处理,而不是当成损坏文件去回落。 sliderslide / sliderwhistle 没有内置合成音,文件缺失时同样是静音—— 凭空循环一个没人要的音比安静糟糕得多。

文件夹首次创建时会自带一份 README.txt 说明同样的内容。


7. 构建

./gradlew build          # 产物在 build/libs/osu-mc-1.0.0.jar
./gradlew runClient      # 直接起一个带 mod 的开发客户端
./gradlew coreTest       # 只跑引擎自测,不需要 Minecraft
./gradlew modCheck       # 只跑 mod 规则的对照测试
./gradlew mapCheck       # 解析并自动打完一个文件夹里的所有谱面
./gradlew onlineCheck    # JSON 解析与镜像站响应解析

coreTest 跑的是 dev.sorihiko.osumc.core 这一层——它完全不依赖 Minecraft, 用普通 JDK 就能编译运行。也可以手动跑:

javac -d build/coreclasses $(find src/main/java/dev/sorihiko/osumc/core -name '*.java')
javac -cp build/coreclasses -d build/testclasses $(find src/test/java -name '*.java')
java -cp build/coreclasses:build/testclasses dev.sorihiko.osumc.core.CoreSelfTest
java -cp build/coreclasses:build/testclasses dev.sorihiko.osumc.core.ModCheck
java -cp build/coreclasses:build/testclasses dev.sorihiko.osumc.core.DemoCheck
java -cp build/coreclasses:build/testclasses dev.sorihiko.osumc.core.MixerLatencyCheck
java -cp build/coreclasses:build/testclasses dev.sorihiko.osumc.core.BundledMapCheck <谱面文件夹>

当前输出:

136 checks, 0 failures      (引擎)
 95 checks, 0 failures      (mod,含 60fps 逐帧 autoplay → SS)
 80 checks, 0 failures      (JSON 与镜像站解析,含 4 家的响应形状)
 18 checks, 0 failures      (打击音延迟)
 40 checks, 0 failures      (5 张附带谱面:3792 个物件全部 autoplay SS)
auto-play: SS  score=70899  combo=63x  acc=100.00%  300/100/50/x = 39/0/0/0

8. 项目结构

src/main/java/dev/sorihiko/osumc/
├── core/                       ← 零依赖引擎,纯 JDK,可单独测试
│   ├── beatmap/                ← .osu 解析、SliderPath、物件、谱面后处理
│   │   ├── OsuFileParser       ← 移植自 LegacyBeatmapDecoder + ConvertHitObjectParser
│   │   ├── SliderPath          ← 移植自 osu.Game.Rulesets.Objects.SliderPath
│   │   ├── SliderEventGenerator← 移植自 SliderEventGenerator(含 -36ms tail 宽容)
│   │   ├── Beatmap             ← 含 OsuBeatmapProcessor 的 stacking 算法
│   │   └── BeatmapLibrary      ← 目录扫描 + .osz 解包
│   ├── util/PathApproximator   ← 移植自 osu-framework 的 Bezier/Catmull/圆弧逼近
│   ├── scoring/                ← OsuHitWindows、ScoreV1、准确率、评级、失败条件
│   ├── mods/                   ← Mod 表、冲突解决、难度调整、HR 翻转、HD 曲线、FL 几何
│   ├── play/OsuGameplay        ← 判定状态机(时钟驱动,与帧率无关)
│   ├── play/AutoPlayer         ← RX / AP / AT / SO 的按键序列与光标轨迹
│   └── demo/DemoBeatmap        ← 生成谱面与音频(现在只作测试夹具用)
└── client/                     ← Minecraft 适配层
    ├── OsuMcClient             ← 入口:暂停菜单按钮、快捷键、库初始化
    ├── BundledBeatmaps         ← 解包 jar 里附带的谱面
    ├── OsuConfig
    ├── audio/                  ← 解码(stb_vorbis / Java Sound / JLayer)、时钟、
    │                              软件混音、WSOLA 变速(不变调)
    ├── render/                 ← 程序化皮肤、批量精灵、slider 渲染、HUD
    └── screen/                 ← OsuScreen 宿主 + 选歌 / 游玩 / 结算三个场景

9. 已知限制

  • 只支持 osu!standard。选歌界面会自动过滤 Mode != 0 的谱面。
  • 输入延迟受 Minecraft 帧率影响。GLFW 事件只在主线程轮询时派发,

    所以判定时间戳的粒度约等于一帧。建议把帧率上限调高(无限制最好)。 判定本身由音频时钟驱动,不会因掉帧而漂移。

  • HP 掉血是近似实现。osu!stable 的掉血曲线依赖大量历史细节,这里用了

    形状一致的简化模型。分数、准确率、判定窗口、转盘转数是严格按官方公式实现的。 觉得掉血不合理就开 NF。

  • 音频走 Java Sound,不走 Minecraft 的 OpenAL。这样 osu! 的时钟不会被

    Minecraft 音频线程干扰,但 osu! 的音量不受 Minecraft 音量滑块控制(用配置文件调)。

  • 内置打击音是合成的,不是 osu! 原版素材(那些不可再分发)。

    谱面自带的 hitsound 和皮肤文件夹里的文件都会优先使用,见第 5 节。

  • 不支持 storyboard、视频背景、break 期间的特效。
  • 变速用的是自己写的 WSOLA(DT/HT)和线性/盒式重采样(NC)。

    和 osu! 走 BASS 的 SoundTouch 是同一类算法,性格也一样:大部分音乐没问题, 非常纯的长音会有一点抖动。1.5 倍速下约占单核 1.8%。


10. 许可

本项目以 MIT 发布。core 中标注了 "ported from ppy/osu" 的文件是 ppy/osu 与 ppy/osu-framework (均为 MIT)的 Java 移植,版权归 ppy Pty Ltd,详见 NOTICE。

MP3 解码使用 JLayer(LGPL-2.1), 以未修改的形式 shade 进 jar。

osu! 是 ppy Pty Ltd 的商标。本项目与 ppy 无关,代码本身不包含任何 osu! 的 美术素材或音频素材——皮肤和打击音都是程序化生成的。

assets/osumc/songs/ 下附带的谱面是另一回事:它们包含各自的歌曲与 mapper 的作品, 版权归原作者,随本仓库一起分发只是为了开箱即玩。要公开发布这个 mod 的话, 先清空 index.txt(见第 2 节)。

From the project's repository, fetched . Images load from GitHub.

Releases

Feed

No releases yet. Follow the project to hear when the first one comes out.

Works for me

Did it work on your PC? A quick report tells other players which versions are safe to try.

Sign in to add a report

Discussion

No posts yet. Ask a question, share your setup or post a clip.

Sign in to post