尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

osu-droid难度算法实现剖析:Aim、Speed与Reading技能模型深度解析

osu-droid难度算法实现剖析:Aim、Speed与Reading技能模型深度解析 osu-droid难度算法实现剖析Aim、Speed与Reading技能模型深度解析【免费下载链接】osu-droid项目地址: https://gitcode.com/gh_mirrors/os/osu-droidosu-droid 是开源社区广受欢迎的 osu! Android 移植版其自研的难度算法堪称评价谱面难度与玩家水平的大脑通过 Aim、Speed、Reading 等技能模型把一张包含数百个音符的谱面压缩成一个直观的星数与对应的 pp 值。这篇难度算法深度解析将从源码视角一步步拆解这套技能模型的计算流程与设计思想。一、难度算法整体架构一条从谱面到星数的流水线osu-droid 的难度计算入口是DroidDifficultyCalculator它遵循经典的 osu! 难度算法三阶段流程预处理把谱面物件包装成DroidDifficultyHitObject归一化距离、计算时间间隔与角度。技能建模创建多套技能并行打分每套技能独立评估谱面的某一维度负担。汇总换算把技能得分加权组合成 base performance再开立方得到最终星数Star Rating。其中技能创建逻辑非常直观createSkills默认创建DroidAim带滑条与不带滑条两份、DroidRhythm、DroidTap开启 Flashlight 模组时追加DroidFlashlightDroidReading则始终参与计算。最终星数公式为starRating cbrt(basePerformance * FINAL_MULTIPLIER)其中basePerformance由 Aim、Tap、CognitionReading 与 Flashlight 的合成通过范数norm加权得到。相关源码位于src/com/osudroid/difficulty/calculator/DroidDifficultyCalculator.kt。二、Aim技能模型把瞄准拆成 Snap、Agility 与 FlowAim 技能DroidAim是整个难度算法中最复杂的模块它继承自可感知滑条长度的VariableLengthStrainSkill将瞄准拆成三个正交维度Snap点按瞄准评估相邻物件间的跳跃距离与角度DroidSnapAimEvaluator会奖励锐角、广角与快速转向并对重复角度做削弱处理。Agility敏捷评估光标速度的突变率衡量连续快速转向的负担。Flow顺滑评估流线型连续滑动的难度主要作用于串stream段落。三个维度分别乘以 70.9、2.35、242 的权重后再通过 logistic 函数计算该音符更偏向 Snap 还是 Flow的概率加权求和得到当前物件的难度值。此外Aim 还会记录每个滑条的速度travelDistance / travelTime用于统计困难滑条占比这与结算面板上的滑条系数直接相关。每个技能都有一套应变衰减模型Aim 的衰减系数为0.2^(ms/1000)即 1 秒内难度记忆衰减到 20%同时它会将前 4 秒内的最高应变按 20ms 分块削减避免极端难度尖峰过度抬高整张谱面的星数。核心实现见src/com/osudroid/difficulty/skills/DroidAim.kt。三、SpeedTap技能模型BPM、节奏与三指检测Speed 技能在 osu-droid 中名为DroidTap属于谐波求和类技能HarmonicSkill衡量玩家跟上击打速度的能力。其评估器DroidTapEvaluator的核心公式非常简洁strain speedBonus * 1000 / strainTimeBPM 加成当音符间隔对应的 BPM 超过 200 时MIN_SPEED_BONUS 200通过误差函数逐步放大难度200 BPM 以上每提速一点都极其昂贵。连点削权利用doubletapness连点程度识别可以被双指连打糊过去的段落并降低其难度这就是常说的反作弊cheesability设计。节奏调制每个音符的 Tap 难度还会乘上DroidRhythm提供的节奏倍率节奏越难如变速、切分音倍率越高。值得一提的是osu-droid 还内置了三指速段检测当 Tap 应变连续超过阈值 175 且物件数不少于 5 个时会标记为可能三指速打的段落possibleThreeFingeredSections这一信息会进入 pp 计算用于识别移动端特有的作弊手段。相关实现见src/com/osudroid/difficulty/skills/DroidTap.kt与DroidTapEvaluator.kt。四、Reading技能模型信息密度与 AR 的阅读负担Reading 技能DroidReading是 osu-droid 相对原版 osu! 的特色模块专门衡量读图难度其评估器DroidReadingEvaluator在 3000ms 的阅读窗口内综合四类负担音符密度统计当前物件出现时与需要点击时可见的物件数量密度越高越难读。AR 预判以 AR 9.66500ms preempt为起点approach rate 越高、反应时间越短preempt 难度呈 2.5 次方增长。Hidden 加成开启 Hidden 模组时按 0.28 系数放大阅读难度并额外奖励完美堆叠前一个音符点击时当前音符完全不可见的段落。恒定角度削弱检测相似角度的反复出现连续同角度的物件会显著降低阅读难度熟能生巧。此外Reading 还模拟了人类前几秒背谱的行为谱面前 60 秒内的音符难度会被按对数曲线削减applyDifficultyTransformation这与我们第一遍打谱难、越打越简单的直觉完全吻合。核心实现见src/com/osudroid/difficulty/evaluators/DroidReadingEvaluator.kt。五、汇总换算技能值如何变成星数与 PP当各技能完成打分后DroidDifficultyAttributes会收集 Aim、Tap、Rhythm、Flashlight、Reading 五类难度值以及困难应变数困难滑条数可能三指段等辅助统计量。随后难度 → 性能HarmonicSkill.difficultyToPerformance采用4 × difficulty³的换算StrainSkill 类也有对应的换算函数把技能值映射为性能值。性能 → 认知合成Reading 与 Flashlight 先合成cognition光源对读图的影响按比例压缩。最终星数Aim、Tap、Cognition 三者通过 norm 组合后再开立方得到与玩家直觉高度一致的星数这个星数连同难度属性一起喂给DroidPerformanceCalculator最终算出 pp。整套换算链条都封装在src/com/osudroid/difficulty/attributes/与src/com/osudroid/difficulty/calculator/目录下属性类与计算器分离的设计让二次开发十分清爽。六、如何自行调试与二次开发这套难度算法如果你也想动手研究这套难度算法可以在本地克隆仓库后直接阅读与修改git clone https://gitcode.com/gh_mirrors/os/osu-droid推荐三个探索入口实时调试src/com/osudroid/debug/DebugPlaygroundScene.kt提供了难度计算的调试场景可直观看到各类技能值的变化。批处理入口src/com/osudroid/beatmaps/DifficultyCalculationManager.kt负责对谱面库批量计算难度。单元测试tests/test/kotlin/com/osudroid/下保留了 83 个测试文件覆盖了技能评估器与换算公式的边界情况修改算法后跑一遍测试即可验证效果。对于想给 osu-droid 贡献新模组难度加成、或复刻这套移动端难度算法的开发者来说从 Aim 的 Snap/Flow 概率模型与 Reading 的密度窗口这两个最有移动端特色的部分入手是最快理解整套设计精髓的路径。结语通过这次对 osu-droid 难度算法的剖析可以看到它并非简单照搬桌面版 osu!而是在 Aim 中引入 Snap/Agility/Flow 三维拆分、在 Speed 中加入三指检测、在 Reading 中构建信息密度窗口处处体现着对手指触屏操作这一场景的针对性建模。理解这套技能模型不仅能帮你读懂星数与 pp 背后的逻辑更能为移动端音游的难度设计提供一份高质量的参考样本。【免费下载链接】osu-droid项目地址: https://gitcode.com/gh_mirrors/os/osu-droid创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表