主力批 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>
28 lines
2.9 KiB
JSON
28 lines
2.9 KiB
JSON
{
|
||
"title": "见缝插针 Needle",
|
||
"brief": "做一款经典见缝插针。竖屏逻辑视口 390×844。\n- 屏幕中心一个持续匀速旋转的圆盘。底部一根待发射的针指向圆心。开局圆盘上可预置 0~1 根针。\n- 点击任意位置:把当前待发射的针射入圆盘——针固定在圆盘上「当前角度」并随盘一起转动;随即底部生成下一根待发射针。若新针的落点角度与任一已插入针的角度过近(视为碰撞)= 失败。\n- 成功插入到目标数量(如 12 根)= 胜利。\n- 顶部文本 HUD:显示已插入数 / 目标数 / 当前状态。\n- 【终态契约·务必遵守】胜或负即把 _forensicsView().state().phase 置 'gameover' 并【驻留】(显示结果文案 + 「点击重玩」提示);玩家点击重玩前 phase 必须恒为 'gameover',**绝不自动重开 / 不下一帧复位回 playing**(宿主每 500ms 轮询 phase 判结束)。**gameover 状态下点击一律忽略**;仅点击明确的「重玩」按钮才允许重开。\n- 【可测性·务必导出状态】_forensicsView().state() 返回纯只读实时真值,除 phase 外导出:\n · result:null | 'win' | 'lose'(对局中为 null)\n · inserted:整数,已成功插入的针数(开局为 0 或预置数,每成功插入 +1)\n · target:目标针数。\n harness 依据 inserted/phase 验证进展与终局。\n- 反馈(juice):发射 / 成功插入触发 getEngine().particles.spawnEmitter 粒子 + getEngine().audio.synth.synthSfx 音效;碰撞失败时额外给一次明显反馈。\n- 画面:深色背景铺满 390×844;圆盘 / 针 / 文字均用亮色实心绘制。",
|
||
"play_spec": {
|
||
"inputs": [
|
||
{ "t": "wait", "ms": 700 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 },
|
||
{ "t": "tap", "x": 195, "y": 760 }, { "t": "wait", "ms": 520 }
|
||
],
|
||
"expectedEngineCallPrefixes": ["particles.", "audio.synth"],
|
||
"assertAfterPlay": [
|
||
{ "path": "inserted", "op": "increased", "why": "定时连发射针→已插入数上升;点击失灵/不响应则不升" }
|
||
],
|
||
"expectLatch": true
|
||
}
|
||
}
|