{ "title": "多球弹球 Multiball", "brief": "做一款多球打砖块变体。竖屏逻辑视口 390×844。\n- 底部一块玩家挡板(水平移动,厚度≥14)。开局有 2~3 个球同时斜向匀速运动,碰墙/挡板反弹(碰挡板按击中位置调水平速度)。\n- 顶部一片砖块网格;任一球击中砖块→该砖消除、得分 +1。部分砖被击碎后掉落道具(下落,挡板接到=增球或扩板)。\n- 任一球 y 越过屏幕底沿即出局丢失(绝不在底部反弹回弹);所有球都掉到挡板下方出局 = 失败;清光所有砖 = 通关。\n- 命中砖块触发屏震 + 闪白(getEngine().particles.shakeScreen / flashScreen 或 spawnEmitter)。\n- 【CCD 注意】球速较快,碰撞请沿速度向量做连续检测,避免高速球穿砖/穿墙。\n- 球速:合速度约每秒 320~420 逻辑像素。\n- 【终态契约·务必遵守】失败/通关即把 phase 置 'gameover' 并【驻留】(结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位。gameover 下点击忽略。\n- 【控制·务必跟手】挡板朝触摸点 x 平滑逼近(每帧插值 0.2~0.35),绝非一格一跳。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score;remaining(剩余砖数);ball:{x,y,vx,vy}(任选一个【活跃主球】的位置,供 harness 挡板接球用,实时);paddle:{x,y,w};balls:[{x,y}...](所有活跃球,可选)。harness 读 ball.x 自动移挡板接球、据 remaining/phase 验进展与终局。\n- 反馈(juice):击砖/接道具/掉球触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;挡板/砖/球/道具/文字亮色实心。", "play_spec": { "controlCheck": { "paddlePath": "paddle.x", "paddleY": 800, "tapXs": [50, 340], "tapsPerTarget": 6, "moveMin": 25, "tolerance": 70 }, "driver": { "type": "paddle-intercept", "ballPath": "ball.x", "paddleY": 800, "steps": 80, "stepMs": 130, "drainAfter": 48, "drainX": 10 }, "expectedEngineCallPrefixes": ["particles.", "audio.synth"], "assertAfterPlay": [ { "path": "remaining", "op": "decreased", "why": "多球+挡板接球击碎砖→剩余下降;碰撞失效/高速穿透(CCD缺)则不降" } ], "expectLatch": true } }