Skip to content

Latest commit

 

History

History
240 lines (194 loc) · 18.5 KB

korean-client-comparison.md

File metadata and controls

240 lines (194 loc) · 18.5 KB

韩服 O2JamO2 / Classic 与 O2Lazer 行为对照

维护状态(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 导入、 元数据编码观感、样本编号逐事件对应或音频后端播放验收。

已明确的 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 路径的静态证据,未在在线环境中试听,不推断所有选曲操作都 只采用这一种音轨。当前本地预览同步方案是用户需求,不因本次对照而退回远程音频。

尚待确认

  1. 零血后的最终通过语义、运行回调及任务/特殊模式的完整规则。2026-10-05 的 零血专项对照已确认普通场景、最高 Combo/ 计数、药丸 BAD 例外及声音停止分支;Classic 的普通零血报告含网络边界。 静态差异不等于两客户端所有生命周期已完成实机验证。项目已由用户选定新的 EX 完整记录/锁血/曲终 F 契约;这些原版待核对项不阻塞新规则实现。
  2. LN 漏头、提前松手、正常释放的颜色、裁切和消失动画,以及皮肤/滚动行为。
  3. 空击选音及 LN 尾控制事件。两份程序均存在尾标志走停止缓冲的分支,但普通命中 路径跳过尾播放;尚不能将其解释为“正常松手必定切断头 KS”。项目防止已判 LN 再次播放 KS 的用户验收仍保留。
  4. 音频实际响度、叠音、输入延迟、帧稳定性,以及在线更新/启动参数改变的路径。
  5. 异常网格、非整 tick 小节、异常 LN、缺失资源与正式回放重判的边界。 此报告当时记录的 KS 中段尾音限制已由 2026-10-08 的预览与回放原生 Track 补播适配处理;冷缓存准备、不同设备与异常资源覆盖仍有边界。

后续修改的位置与顺序

用户明确选择这两份客户端为主要行为参考,并授权完成 C02–C05。实现保留原生 时钟及独立 Core,桥接只传递原始/计分判定。C01 已按连续不对称区间实现,C07 等待进一步对照;C06 的 本次授权只涉及玩家触发游玩音,不扩大到预览或背景编排。

  1. 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 不取整位置,使用统一连续区间。
  2. Formats / Integration / Host.Audio:未来若启用 C07,应保留足够原始参数以翻译 nibble,在桥接与音频宿主应用混音。C06 的声道替换、暂停、seek 清理留在 Host.Audio; 已判定选音限制只读取原生 lifetime 状态,MS 通过保留的 OJM 样本身份识别。预览和 自动音的并发策略本轮不变。后端继续复用原生 Sample/Track,无需搬入 Core。
  3. Presentation:补 Jam/药丸 HUD,只消费 Core 快照;LN 视效以逐帧材料验收。
  4. 成绩/回放:正式 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 与验证范围见音频契约。