lili 4836a6f519 feat(wg1-scale20): 20基准放量(14款)+ 三方门验证 + driver库泛化 + 宿主键盘缺口定位
主力批 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>
2026-06-14 10:30:06 -07:00

28 lines
2.9 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"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
}
}