主力批 7/8 真可玩(Opus 对抗审计 0 假绿)、压测 match3 ✅;失败收敛:3 键盘款(2048/Tetris/Asteroids)挂宿主缺 keydown 桥=唯一真·L0 门面缺口(已 spawn_task 交 L0)、multiball/flappy/愤怒小鸟=driver-coverage(非模型)。spec 预判 CCD/文本HUD/网格/match/手势缺口全推翻(便宜 flash 自带 swept CCD/自写网格文本)。
- driver 库 1→6 型(tap-targets/flap-to-gap/seek-x/tap-pairs/key-cycle/paddle-intercept)+ drag 输入事件 + key() Arrow 修
- M3 视觉 player 当生产过滤器实证(与门 8/9 一致、抓显性空心)→ 门(地板)+M3(主观过滤)+创始人(人锚)三层互补
- 短板量化报告定稿 + 两 skill 沉淀(game-e2e §8 driver库/门承重/键盘缺口 · cheap-model §9 模型能力画像)
- 2 个 ultracode 对抗 workflow(审计10+诊断7 agents)抓 saolei 弱断言、纠 flappy 归因(driver 非模型)、定位宿主键盘根因
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
26 lines
2.7 KiB
JSON
26 lines
2.7 KiB
JSON
{
|
||
"title": "跑酷 Runner",
|
||
"brief": "做一款经典横向无尽跑酷。竖屏逻辑视口 390×844。\n- 角色在固定 x 处自动向右奔跑(世界向左滚动),距离随时间自动累加。\n- 地面障碍物从右侧较密地滚入;点击任意位置 = 角色跳跃(受重力,落回地面);跳过障碍则安全,撞到障碍 = 失败(障碍较密,不跳必撞)。\n- 计分 = 已跑距离(随时间单调增加)。\n- 顶部文本 HUD:显示距离分 / 状态。\n- 【终态契约·务必遵守】撞击失败即把 _forensicsView().state().phase 置 'gameover' 并【驻留】(显示结果 + 「点击重玩」提示);玩家点击重玩前 phase 必须恒为 'gameover',**绝不自动重开 / 不下一帧复位**(宿主每 500ms 轮询 phase 判结束)。**gameover 状态下点击一律忽略**;仅点击「重玩」按钮才重开。\n- 【可测性·务必导出状态】_forensicsView().state() 返回纯只读实时真值,除 phase 外导出:\n · result:null | 'lose'\n · score:整数,已跑距离(开局为 0,自动增加)\n · player:{ x, y, vy, onGround }(角色当前中心逻辑像素坐标、竖直速度、是否在地面,实时)\n · nextObstacle:{ x }(前方最近障碍的 x 逻辑像素;无则 null)。\n harness 依据 score/phase 验证进展与终局(nextObstacle/player 供后续适配性驱动用)。\n- 反馈(juice):跳跃 / 撞击触发 getEngine().particles.spawnEmitter 粒子 + getEngine().audio.synth.synthSfx 音效。\n- 画面:深色背景铺满 390×844;角色 / 障碍 / 地面 / 文字均用亮色实心绘制。",
|
||
"play_spec": {
|
||
"inputs": [
|
||
{ "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 },
|
||
{ "t": "tap", "x": 195, "y": 420 }, { "t": "wait", "ms": 500 }
|
||
],
|
||
"expectedEngineCallPrefixes": ["particles.", "audio.synth"],
|
||
"assertAfterPlay": [
|
||
{ "path": "score", "op": "increased", "why": "自动跑→距离分上升(稳过);G 门验跳跃是否真改变存活、latch 验真撞死" }
|
||
],
|
||
"expectLatch": true
|
||
}
|
||
}
|