维护状态(2026-10-06):主参考与差异记录;已选对齐阶段结束,其余差异暂缓,不宣称完全复刻。 文档职责与最新状态入口见索引。
检查日期:2026-10-04。按用户指定,以提供的 O2JamO2 和 Classic 两份客户端为主要 行为参考;Remix 作交叉核对,DPJAM 的增强补丁单独记录。初次检查只整理证据和差异, 未修改玩法、音频或已安装的 ruleset DLL;以下同时记录后续授权修正的结果。
后续处理(同日):C02–C05 已授权对齐。用户实测 O2JamO2 后,为 C06 选择了游玩内 同 KS 停旧重播、已判定物件禁止再触发的组合策略。2026-10-05,C01 按用户选定的连续不对称区间实现,不截断位置;C07 继续暂缓。当前规则和 处理状态以下表及行为规范为准;安装包检查材料保留不变。
2026-10-05 已另行完成原版客户端功能覆盖检查, 将对照扩展到判定呈现、Jam/药丸 HUD、曲风、外观、技能、教程、任务、Classic 3Key、 对战及结果/设置。本文七项计分/音频对照不能当成整个客户端已经完全对齐的结论。
| 对象 | O2JamO2 | Classic |
|---|---|---|
| 本地包 | E:\Downloads\O2JamO2.zip |
E:\Downloads\O2Jam-Classic.zip |
| ZIP 大小 | 397,083,790 字节 | 139,855,943 字节 |
| ZIP SHA-256 | 712768e1802819648180e88169a19e7fe88e06f6590435c9cfc329dfcf6be592 |
9eab6017b2c89185c62744296c38d8f1276cb21ab0b5165f7997a2ea0c2a56e8 |
| 安装器成员 | O2JamO2_Setup.exe |
O2Jam_Classic.exe |
| 游戏主程序大小 | OTwo,2,998,272 字节 | OTwo / AngelO2Jam,5,029,888 字节 |
| 主程序 SHA-256 | 2c8ac19bc26a7e1cfde527f5871c22b14fcc5473137101f4be849435d99b3102 |
83a045418b6219ba340681766b33de2bfbb5ff51b813ef4e2e9dd1def72c823b |
| 主程序 PE 时间字段 | 2008-06-17 00:28:25 UTC | 2009-10-29 02:22:42 UTC |
| 程序类型 | 原生 PE32 / x86,ImageBase 0x400000 |
同左 |
Classic 安装目录的 OTwo.exe 和 AngelO2Jam.exe 是同一份数据的两个别名:偏移、
长度及 MD5 相同,解压后的 SHA-256 也相同。它们不构成两套不同玩法证据。目录有
74 个安装描述项,其中 45 个为游戏载荷;主程序保留 NOWCOM 注册表路径、韩服
历史服务地址和 O2Jam_Client(2005) PDB 路径,并包含 GAMEANGEL 发行入口信息。
它与 O2JamO2 的 OTwo 并非同一二进制,但两包的 O2Net32.dll 完全相同。
Classic 包中未找到可以可靠绑定主程序的版本资源或 VersionInfo 文件,因此不直接 将其标为某个公开流传的版本号。历史谱系和用户提供的来源可以支持选择这两份文件作 项目参考,但本轮没有官方哈希用于认证安装包未被修改。O2JamO2 的来源分析另见 单包报告。本文结论均限定于上表文件。
初次检查将安装柜目录、选定 EXE/DLL 和谱面/音频成员在内存中读取,逐成员检查长度及记录的
MD5。未运行安装器、游戏或 DLL,未将它们的可执行成员落盘。忽略目录 .artifacts
保存检查脚本、派生的元数据和指令清单;仓库不包含客户端资源。静态执行路径能确定
规则和参数,不能代替输入、声音、动画或在线更新后的实际验收。
后续已建立 O2JamO2 独立本地运行环境,用户确认可以进入并游玩。原主程序未修改, 登录使用本机 Identity 服务端;部署与验证范围见本地对照环境。 这不表示七项行为差异已完成实际验收;Classic 仍只做静态检查。
以下针对不启用 Mania Score 的 O2Jam 玩法。MS 是用户选择的另一套原生 mania 规则,不应按 O2Jam 判定核验。
| 项目 | 两份客户端与当前项目的关系 |
|---|---|
| 时间基础 | 都以谱面位置、BPM 和每完整小节 192 tick 为基础,而非固定毫秒窗口;项目用独立 TimingMap 接到 lazer 时钟 |
| 窗口常量 | COOL 6、GOOD 18、单点/长条头 BAD 25 相同;比较时的位置量化不同,见 C01 |
| 分数公式与次序 | COOL 200+10×Jam、GOOD 100+5×Jam、BAD 4、MISS -10 且最低 0;先按已有 Jam 计分,再更新 Jam |
| Combo | 第一击显示 0、第二击显示 1;普通 BAD/MISS 断连。项目的内部 -1 与客户端的计数减一属于表示差异 |
| 常规药丸 | 连续 15 COOL 得一颗,上限 5;有药丸时 BAD 可按 COOL 处理。救回后的进度和 LN 控制见 C04/C05 |
| 血量增减 | 上限 1000;EX +3/+2/-10/-50、NX +2/+1/-7/-40、HX +1/0/-5/-30 |
| LN 端点 | 头与释放分别计分;漏头产生头/尾 MISS;未被救回的 BAD 头终止 LN |
| 采样身份 | OJN 引用减一,背景类别加 1000;普通 LN 判尾不重新播放头 KS |
这些证据没有要求推翻现有 note/KS 映射或缺失零号 KS 的处置,也不要求将判定移回 drawable。零 KS 的玩家验收结论仍有效;非法或缺失资源的完整边界行为另行验证。
两份主程序在下列七项上互相一致。初次对照发现五项核心规则和两项音频差异; C02–C05 已对齐;C01 使用用户选定的连续不对称区间,C06 按用户选定范围实现,C07 暂缓。编号沿用之前的 Remix 对照。
| 编号 | 两份韩服客户端 | 当前 O2Lazer | 实际影响 |
|---|---|---|---|
| C01 判定位置量化 | 输入位置向零截成整数 tick,再比较整数距离 | 连续区间 [-6,7)、[-18,19)、[-25,26) |
已按用户选择实现;普通整数 tick 目标边界一致,负位置/非整 tick 采用统一区间 |
| C02 LN 释放 BAD | 包含整数距离 25 tick | 连续 BAD 区间 [-25,26) |
同头判定,晚侧 +26 排除并超时 |
| C03 Jam 晋级 | COOL +2、GOOD +1,累计进度严格大于 50×(Jam+1) 才晋级 |
保留归一化 COOL +4 / GOOD +2,严格超过 100 后扣除 100 并保留余量 | 晋级时点与计分次序已对齐,连续 COOL 在第 26、51、76…击后晋级 |
| C04 救回 BAD 的药丸进度 | 清零连 COOL,消耗药丸,直接进入 COOL 计分;该击不增加连 COOL 进度 | 按原始判定管理药丸进度;救回后为 0 | 已对齐,还需 15 次真正 COOL 才得下一颗 |
| C05 救回 BAD 的 LN 头 | 头按 COOL 计分,LN 控制仍检查原始 BAD,尾强制 MISS | 快照与桥接分别保留原始/计分判定,BAD 头强制尾 MISS | 已对齐;绘制继续只消费 Core 状态 |
| C06 同采样重复播放 | 每个样本编号一个固定缓冲;再次触发先停止并从头播放;用户观察已判定物件仍可重触发 | 游玩内同 KS 停旧重播,单点/LN 头判定后不可再触发;预览/自动音保留原有并发 | 用户选择的组合策略,已实现,实际听感待验收 |
| C07 音量/声像 | 谱面 nibble 与 KS/BG 设置结合后转换为 DirectSound 分贝衰减 | nibble 转整数百分比线性增益,声像线性映射为 Balance | 用户暂缓,待实际混音对照 |
对于整数端点 T、非负谱面位置,两份客户端的 COOL 区间为
T-6 <= position < T+7;当前项目显式采用同一区间,早期项目为 T-6 <= position <= T+6。在 BPM 150 时一 tick
约 8.33 ms。当前 Core 保留连续位置,直接定义早侧包含、晚侧排除的区间;lazer 时钟及 TimingMap
仍保持精确。负位置与非整 tick 目标采用统一区间,因此不宣称与原版截断算法全域等价。
从全新状态连续 26 个 COOL,两份客户端和修正后项目均得 5200,修正前项目为 5210。 严格累计阈值不表示 每一级都需要 26 个 COOL:持续连 COOL 时晋级在第 26、51、76…击之后,下一击才 使用新的加分。GOOD 混入时同样按累计进度比较。
普通 15 COOL 发药丸与 BAD 救回属于不同调用路径。救回在计分上仍是 COOL, 但这并不保证它在“连续 COOL 发药丸”或“长条允许继续”中等同于真实 COOL。 这两个区别应该由 Core 的明确状态转换表达,不能让 HUD 或 drawable 再判一次。
客户端 KS/BG 设置值为 255、音量 nibble 为 8 时,转换结果为 -15 dB,振幅约 0.178;项目为 50% 线性增益。pan 1/15 对应左右约 ±26.25 dB 的衰减参数,项目 映射到 Balance 两端。此处比较参数含义,没有测量设备输出。详细公式与 DirectSound 文档链接见 C07 音频对照。
下表均为各主程序自己的虚拟地址,不能跨版本直接套用偏移。
| 路径 | O2JamO2 | Classic |
|---|---|---|
| 192 tick 网格读取 | 0x52a771–0x52a7b3 |
0x57240a–0x57244c |
| 输入位置整数化 | 0x52dbd5–0x52dc04 |
0x576595–0x5765c4 |
| 释放 6/18/25 | 0x52dc86–0x52dcb3 |
0x576646–0x576673 |
| 头 6/18/25 | 0x52e185–0x52e1a9 |
0x576b7f–0x576ba3 |
| Jam 累计阈值表 | 0x52868b–0x5286a3 |
0x570284–0x570293 |
| 严格超过阈值 | 0x528afb–0x528b08 |
0x570712–0x570727 |
| Combo 加一后减一显示 | 0x528a78–0x528a99 |
0x570638–0x570660 |
| 普通 COOL 发药丸 | 0x5271dd–0x52723e |
0x56e4c5–0x56e519 |
| BAD 清零/消耗药丸/直接计分 | 0x5274b0–0x5274f2 |
0x56e80b–0x56e87e |
| 原始 BAD 头强制尾 MISS | 0x52e28c、0x52e2e8–0x52e34b |
0x576d8b–0x576e4a |
| 血量增减表 | 0x5292d0–0x52939c |
0x570f90–0x571059 |
| KS 编号翻译 | 0x5287f9–0x52881b |
0x570415–0x570437 |
| 同编号播放缓冲与混音 | 0x50d210–0x50d373 |
0x551b44–0x551c83 |
| Stop / 重设播放位置 | 0x5082a0–0x5082f6 |
0x54cbb0–0x54cc16 |
Classic 的音量/声像分支为 0x551b80–0x551c6f。它与 O2JamO2 及 Remix 的
参数曲线相同。两份韩服客户端释放 BAD 均为 25,DPJAM 的 O2Hook2 替换路径为 24;
因此不能以 DPJAM 补丁作为韩服原生释放规则的依据。
对两包中的 OJN/OJM 数据,使用当前 O2Jam.Formats 和 O2Jam.Core 源码编译的
临时检查程序完成读取。检查程序运行于本地 .NET 10;没有改动正式项目的 net8.0
目标或依赖。文件数据从内存传入,不经安装器。每份 OJN 对照全难度与指定难度读取的
音符/BPM 序列,并检查头尾时间转换为有限值;每份音频库提取/解密样本并检查
RIFF/OggS 头部。结果记录在忽略的 .artifacts/korean-client-corpus-check.json。
| 项目 | O2JamO2 | Classic |
|---|---|---|
| OJN | 149 | 14 |
| 难度槽位 / 有可演奏节点的槽位 | 447 / 445 | 42 / 40 |
| 解码后的配对可玩 LN | 7,571 | 67 |
| 非单位小节长度记录 | 0 | 3 |
| OJM / OMC / M30 音频库合计 | 156 | 21 |
| 提取样本 | 36,443 | 2,458 |
| 读取异常 / 非 RIFF、OggS 样本头 | 0 / 0 | 0 / 0 |
O2JamO2 原始事件有 7,574 个可玩 LN 头,与解码后配对数量不是同一统计口径; 不能将原始头数直接作为最终长条数。现有格式模块会将未配对/重复头转为单点, 忽略没有头的释放,客户端在这些异常序列上的完整行为尚未逐项核对。
O2JamO2 有 148 份 new 封装;Classic 有 13 份,另各有一份普通教程。
Classic 版本字段为 13 份 2.9、一份 2.7;音频库为 13 M30、5 OMC、3 OJM。
它的 o2ma769 三个难度在第 21 小节有长度 0.75:客户端按
round(fraction×192) 得到 144 tick,项目按小节长度归一化,此值可以精确对应。
非整 tick 的小节长度仍可能因整数宽度与连续宽度产生差异,尚未覆盖。
两包实际网格均不超过 192 且能整除 192。客户端以整数 192 / 槽数 定位,并拒绝
超过 192 的块;项目允许更细及非整除网格。这是格式兼容范围差异,不能宣称这些
扩展输入在原客户端也会同样游玩。当前材料也没有完成懒读取文件路径、lazer 导入、
元数据编码观感、样本编号逐事件对应或音频后端播放验收。
| 类别 | 当前处理与参考关系 |
|---|---|
| 模式与 Mod | Mania Score 整体切换到原生 mania;HR/EZ 等依赖 MS,变速和其他 Mod 遵循已制定的接入策略 |
| 选图/等级/皮肤 | lv 原值、lv/10 颜色、原生胶囊动画、筛选、皮肤及布局由 lazer 的展示/产品模块处理 |
| 成绩体系 | 使用原生成绩/正式回放、准确率、评级与 PP 资格表达;O2Jam 无独立 PP,非 MS 不计 PP |
| 音量路由 | BGM 与 KS 不受全局效果音量或全局打击音效开关支配,依照用户明确要求保留 |
| 预览 | 项目本地混合 BGM 与 KS;Classic 有 Player.dll / 远程 WMA soundtrack 路径,与本地混合预览不同 |
| 暂停/回放跳转 | 项目按 lazer 时钟一起管理 BGM 和 KS;回放 KS 忠实于录制命中,自动 KS 另有未公开入口 |
| 独立客户端功能 | 登录、房间、商城、Avatar、发行渠道、视频/直播接口等不作为 custom ruleset 的缺失项 |
| Jam/药丸 HUD | Core 已提供状态,专用显示组件仍未完成,属于路线图 R09 的表现待补项 |
| LN 视效 | 当前保色、裁切和滚动消失包含用户已选定规则;两份客户端仍需逐帧核对,不能声称已经精确复原 |
Classic 的预览字符串为 mms://media.talesrunner.com/o2jam_soundtrack/%d.wma
(0x645b68),附带 Player.dll 的 Init/Release/SetPlayURL/SetStopURL 接口。
这是远程 soundtrack 路径的静态证据,未在在线环境中试听,不推断所有选曲操作都
只采用这一种音轨。当前本地预览同步方案是用户需求,不因本次对照而退回远程音频。
- 零血后的最终通过语义、运行回调及任务/特殊模式的完整规则。2026-10-05 的 零血专项对照已确认普通场景、最高 Combo/ 计数、药丸 BAD 例外及声音停止分支;Classic 的普通零血报告含网络边界。 静态差异不等于两客户端所有生命周期已完成实机验证。项目已由用户选定新的 EX 完整记录/锁血/曲终 F 契约;这些原版待核对项不阻塞新规则实现。
- LN 漏头、提前松手、正常释放的颜色、裁切和消失动画,以及皮肤/滚动行为。
- 空击选音及 LN 尾控制事件。两份程序均存在尾标志走停止缓冲的分支,但普通命中 路径跳过尾播放;尚不能将其解释为“正常松手必定切断头 KS”。项目防止已判 LN 再次播放 KS 的用户验收仍保留。
- 音频实际响度、叠音、输入延迟、帧稳定性,以及在线更新/启动参数改变的路径。
- 异常网格、非整 tick 小节、异常 LN、缺失资源与正式回放重判的边界。 此报告当时记录的 KS 中段尾音限制已由 2026-10-08 的预览与回放原生 Track 补播适配处理;冷缓存准备、不同设备与异常资源覆盖仍有边界。
用户明确选择这两份客户端为主要行为参考,并授权完成 C02–C05。实现保留原生 时钟及独立 Core,桥接只传递原始/计分判定。C01 已按连续不对称区间实现,C07 等待进一步对照;C06 的 本次授权只涉及玩家触发游玩音,不扩大到预览或背景编排。
- Core:C02–C05 已实现。初次修正的过滤验收覆盖 T+6.5 为 GOOD、释放 25 tick 包含/25.01 排除;2026-10-05 后 T+6.5 为 COOL、释放 25.01 为 BAD、26 排除。另覆盖连续 25/26/27 及后续 Jam、COOL/GOOD 混合、药丸救回 单点/LN、No Release 和回退重判。C01 不取整位置,使用统一连续区间。
- Formats / Integration / Host.Audio:未来若启用 C07,应保留足够原始参数以翻译 nibble,在桥接与音频宿主应用混音。C06 的声道替换、暂停、seek 清理留在 Host.Audio; 已判定选音限制只读取原生 lifetime 状态,MS 通过保留的 OJM 样本身份识别。预览和 自动音的并发策略本轮不变。后端继续复用原生 Sample/Track,无需搬入 Core。
- Presentation:补 Jam/药丸 HUD,只消费 Core 快照;LN 视效以逐帧材料验收。
- 成绩/回放:正式 v5 的封装、帧、导入身份与已有成绩不变,未重写成绩。
输入回放重演使用当前规则:修正前录制的回放可能得到不同的实时判定/分数;
2026-10-05 新写入包含规则版本
20261005,原有未标记 v5 为测试数据,本次不新增旧规则路由。文件可读与历史分数精确复现 必须分开表述。回退后药丸、Jam 与原始头判定由同一历史恢复。
参考优先级与实现策略应分开记录:两份客户端为目标证据,C01 已按连续区间实现、C07 暂缓,C06 的 判后禁止重触发属于用户明确保留的差异。分层本身足以承载这些修正,不需要重新耦合判定、 绘制、音频与存储。
2026-10-04 的过滤测试通过 262 项:独立 Core 70 项、宿主接入 192 项,无失败或跳过。 宿主验证包括真实原生 drawable 树中的药丸救回 BAD 头、强制尾 MISS、两种滚动方向、 视效开关和回退重判,以及成绩、Mod 与正式 v5 回放兼容测试。本轮没有运行基准或 未过滤的完整测试集,也没有改写真实客户端数据库。
模块、存储、计分边界检查通过;实际源码的语义架构检查为零编译错误、零越层引用、
零过期例外。测试报告保存在忽略目录的 .artifacts/test-results/korean-alignment-*.trx,
架构报告为 .artifacts/architecture/dependencies.json。这些验证不能替代用户的实际
游玩验收,尤其不表示暂缓的三项差异已对齐。
同日 16:44 已备份旧 DLL 并安装到 D:\osu-lazer\rulesets,安装后 SHA-256 与
测试构建一致。备份路径及哈希保存在 .artifacts/install-korean-core-alignment.json;
未启动客户端,实际游玩表现待用户验收。
同日 C06 游玩重触发策略的后续验证:203 个不同过滤用例通过(音频/游玩/回放 201,
BMS 两种载入顺序各一项),分层检查无新增违规,已备份安装供实测。
原生声道从零替换与暂停续播已由无声设备测试验证;实际听感仍待验收。
报告 keysound-retrigger-final.trx 与验证范围见音频契约。