with one click
krkr2-debug
指导 KrKr2 WebAssembly 完整调试工作流,从构建到浏览器。当用户需要调试、测试或排查运行时环境的端到端问题时使用。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
指导 KrKr2 WebAssembly 完整调试工作流,从构建到浏览器。当用户需要调试、测试或排查运行时环境的端到端问题时使用。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
指导 Codex 中的 KrKr2 WebAssembly 完整调试工作流,从构建、服务器到应用内浏览器。当用户需要调试、测试或排查运行时环境的端到端问题时使用。
使用 IDA Pro MCP 工具逆向工程 libkrkr2.so(Android kirikiroid2)。 当用户要求检查 libkrkr2.so 如何实现某功能、将 Web 移植版的 C++ 代码与原始二进制对比、 查找函数地址、追踪调用链,或理解 NCB 类注册时使用此 skill。 在修复需要理解原始 Android 实现的 bug 时也应主动使用。 触发关键词:libkrkr2.so、IDA、反编译、逆向工程、原始实现、 Android kirikiroid2 二进制、"原版是怎么做的"、二进制中的 NCB 注册、 在 .so 文件中查找函数。
使用 CMake 和 Emscripten 编译构建 KrKr2 WebAssembly 项目。当用户需要编译、构建或重新构建项目、配置构建预设或排查构建错误时使用。
Write and update KrKr2 differential test cases for the current geometry_hit_test port-wasm/wasmtime scheme. Use when adding or editing JSON cases under tests/differential/specs/geometry_hit_test, updating EXPECTED_HITS in tests/differential/python/run_geometry_hit_test_wasmtime.py, or extending the current hit-test case set while preserving the existing case format, wasm ABI, and intended oracle-aligned expectations.
使用 mtndump 工具把 KiriKiri2 的 .mtn / .psb motion 文件里所有 src/ 源贴图导出为独立的 PNG,并生成一份 TSV manifest(source、png、宽高、origin、BGRA 标志)。用于 KrKr2/E-mote/EmotePlayer 的离线资源提取、differential testing(对比 libkrkr2.so 与 Web port 的贴图输出)、调试 motionplayer/EmotePlayer 渲染路径,或者只是想知道一个 motion 到底引用了哪些 src/<group>/<name> 贴图。典型触发:用户提到 "mtndump"、"dump motion"、"dump .mtn"、"dump .psb"、"提取 motion 贴图"、"解包 e-mote"、"导出 PSB 图像"、"EmotePlayer 的 src"、"emote 贴图"、"motion snapshot";或者在调试 motionplayer 渲染问题需要看原始贴图、做 KrKr2 差分测试需要对比贴图输出、提到 `tests/test_files/emote/*.psb` 或 seed `742877301` 时。
在 IDA Pro 中跨所有编码(UTF-8、UTF-16LE、UTF-32)搜索字符串,使用 IDAPython。IDA MCP 的 `find` 工具仅匹配 ASCII/UTF-8 字符串,会遗漏 UTF-16 编码的字符串——此 skill 修补了这个缺口。当用户要搜索或查找 IDA Pro 中的字符串时使用,尤其是当用户说"搜索字符串"、"search string"、"find string in IDA",或之前的 `find` 字符串搜索意外返回空结果时。
| name | krkr2-debug |
| description | 指导 KrKr2 WebAssembly 完整调试工作流,从构建到浏览器。当用户需要调试、测试或排查运行时环境的端到端问题时使用。 |
服务器启动后,除了让用户手动访问页面外,也可以使用 playwright-cli 进行自动化调试。参考 playwright-cli skill。
?game=xxx.zip — 加载 ZIP 打包的游戏(ZIP 内含 XP3 文件)?xp3=xxx.xp3 — 直接加载单个 XP3 文件(需先复制到 out/web/debug/ 目录)?game=xxx.zip&entry=data.xp3 — 加载 ZIP 并指定入口 XP3playwright-cli 的 console 命令只保留最近约 200 条日志,WASM 引擎运行时每秒可产生数百条日志,早期的初始化日志会被后续高频日志挤出。console 命令获取的日志严重不完整,不能依赖它来诊断问题。
正确做法:使用 addInitScript 在页面加载前注入日志捕获脚本,按需过滤高频重复消息。
# 1. 打开空白浏览器(不要直接 open URL)
playwright-cli open
# 2. 注入日志捕获脚本(在页面加载前执行)
playwright-cli run-code "async page => {
await page.context().addInitScript(() => {
window._allLogCount = 0;
window._filteredLogs = [];
const orig = console.log;
const origW = console.warn;
const origE = console.error;
const cap = (lvl, args) => {
window._allLogCount++;
const msg = args.map(a => typeof a === 'string' ? a : String(a)).join(' ');
// 过滤掉高频重复消息,按需调整过滤条件
if (!msg.includes('isExistentStorage') &&
!msg.includes('UpdateToDrawDevice') &&
!msg.includes('InternalComplete2') &&
!msg.includes('DrawCompleted') &&
!msg.includes('BasicDrawDevice::Show') &&
!msg.includes('_TVPDeliverContinuousEvent') &&
!msg.includes('DrawDevice::Update')) {
window._filteredLogs.push('[' + lvl + '] ' + msg);
}
};
console.log = function() { cap('LOG', [...arguments]); orig.apply(console, arguments); };
console.warn = function() { cap('WARN', [...arguments]); origW.apply(console, arguments); };
console.error = function() { cap('ERR', [...arguments]); origE.apply(console, arguments); };
});
}"
# 3. 再导航到目标页面
playwright-cli goto "http://localhost:8080/index.html?xp3=data.xp3"
# 4. 等待一段时间后取回日志
# 查看总数和过滤后数量
playwright-cli eval "JSON.stringify({total: window._allLogCount, filtered: window._filteredLogs.length})"
# 分批取回过滤后的日志(每次取 80 条左右避免超长)
playwright-cli eval "JSON.stringify(window._filteredLogs.slice(0, 80))"
playwright-cli eval "JSON.stringify(window._filteredLogs.slice(80, 160))"
# 或者只取不重复的关键日志
playwright-cli run-code "async page => {
const logs = await page.evaluate(() => {
return window._filteredLogs.filter(l =>
!l.includes('某个高频但不重要的消息')
);
});
return JSON.stringify(logs);
}"
关键原则:
playwright-cli console 只作为快速浏览用途,不能作为诊断依据# 复制游戏文件到构建输出目录
cp /path/to/game.xp3 out/web/debug/
# 用 headed 模式打开(WebGL 截图需要)
playwright-cli open --browser=chrome --headed
# 注入日志捕获
playwright-cli run-code "async page => {
await page.context().addInitScript(() => {
window._logs=[];
const o=console.log, w=console.warn, e=console.error;
const c=(l,a)=>{const m=a.map(x=>typeof x==='string'?x:String(x)).join(' ');window._logs.push('['+l+'] '+m);};
console.log=function(){c('L',[...arguments]);o.apply(console,arguments);};
console.warn=function(){c('W',[...arguments]);w.apply(console,arguments);};
console.error=function(){c('E',[...arguments]);e.apply(console,arguments);};
});
}"
# 导航到目标页面
playwright-cli goto "http://localhost:8080/index.html?xp3=game.xp3"
# 等待加载后截图
sleep 3
playwright-cli screenshot --filename=/tmp/debug.png
# 取回日志(用 run-code 避免 eval 的 TypeError)
playwright-cli run-code "async page => {
return JSON.stringify(await page.evaluate(() => ({
total: window._logs.length,
logs: window._logs.slice(0, 80)
})));
}"
# 关闭
playwright-cli close