/** * 《暗室》新手会话剧本:老玩家二周目不算——这里清空过进度走首局引导(G0-G7), * 每步听清再做;进 PLAY 后先连撞两次墙(触发向导提前一级的卡关提示), * 然后找到铁柜房开柜拿保险丝、照 round4 H1 的目标方位句跨四个房间修电箱、 * 再摸到大门收工(目标句后 3s 内都能听到方位句)。 */ export function describe(game) { switch (game.phase) { case 'REOPEN': return '有人问我回不回来看过引导:单击直接开始,上滑重听引导'; case 'GUIDE': return game._guideBusy ? '引导在说话,照它说的做就行' : `引导第 ${game.guideStep + 1}/8 步,等我做手势`; case 'PLAY': return `探索中,我在 (${game.x},${game.y})。四向滑挪步,单击摸一遍房间,双击用物品`; case 'ENDING': return '逃脱了,结算播报中。播完单击再来,下滑开菜单'; case 'MENU': return '菜单里:单击切选项,双击确认,下滑关闭'; default: return '……'; } } export async function session(ctx, mock) { const { game } = ctx; // 首局:交互式引导 G0-G7(n = 引导步号 guideStep)。 // 注意:卡关轮询 interval 常驻,虚拟时钟永不"空闲"——等待一律用有界/带条件等待。 ctx.status('黑屏,只有引子的声音,先听完'); await ctx.waitCond(() => game.phase === 'GUIDE' && !game._guideBusy); // g0_intro 播完 const steps = [ { n: 0, do: async () => { ctx.note('照引导单击了一下'); await ctx.gesture('tap'); } }, { n: 1, do: async () => { ctx.note('随便滑了一步,有脚步声'); await ctx.gesture('up'); } }, { n: 2, do: async () => { await ctx.gesture('left'); await ctx.waitVirtual(1600); ctx.note('又滑一步,又撞墙了——墙的方位听出来了'); await ctx.gesture('right'); }, }, { n: 3, do: async () => { ctx.note('这回往左,走通了一步'); await ctx.gesture('left'); } }, { n: 4, do: async () => { ctx.note('往下滑,进了储物间'); await ctx.gesture('down'); } }, { n: 5, do: async () => { ctx.note('单击摸一遍房间,摸到钥匙了'); await ctx.gesture('tap'); } }, { n: 6, do: async () => { ctx.note('双击看了看背包'); await ctx.gesture('doubletap'); } }, ]; for (const s of steps) { await ctx.waitCond(() => game.phase === 'GUIDE' && game.guideStep === s.n && !game._guideBusy); ctx.status(`引导第 ${s.n + 1}/8 步`); await s.do(); await ctx.waitVirtual(800); // 缓一缓再继续(推进链由语音 onComplete 驱动) } // PLAY:自由探索。引导结束时我站在储物间 (0,2),手里已有钥匙 await ctx.waitCond(() => game.phase === 'PLAY'); ctx.status('引导完毕,正式开始。我在储物间'); const move = async (g, why) => { await ctx.gesture(g); await ctx.waitVirtual(1600); // 听脚步/环境音/描述 if (why) ctx.note(why); }; // 先往北乱撞探探边界:两步走到 (0,0),再连撞两次北墙——向导把卡关提示提前带上来 ctx.silence(3, '辨了辨方向'); await move('up'); await move('up'); await move('up', '北边是墙,撞了一下——「那边是墙」后面还跟了句方向(向上推的是北墙)'); await move('up', '又撞了一下——听到游戏主动来问我了'); await ctx.waitVirtual(5200); // 等卡关轮询的 5s tick:连续撞墙 → 提前一级的暗示 // 去铁柜房:(0,0) → 右×2 = (2,0) → 下 = (2,1),双击用钥匙 await move('right', '往东走,风声换了个方向'); await move('right'); await move('down', '到了铁柜房,柜子锁着'); // 用钥匙 → unlock_cabinet + gd_next_fuse + gd_room_l(round4 H1:目标句带方位, // 从铁柜房 (2,1) 看电箱房 (0,0) 在西 = 左面的房间) await ctx.gesture('doubletap'); await ctx.waitVirtual(5600); ctx.status('柜子开了。「保险丝到手。接下来,去找电箱。」后面还跟了一句「左面的房间。」——这回知道该往哪边摸了'); // round4 H1 剧本:照方位句跨房间去电箱房——(2,1) → 左×2 = (0,1) → 上 = (0,0) await move('left', '照方位句往左(西)摸'); await move('left'); await move('up', '电流声越来越清晰——电箱房到了'); // 修电箱 → fix_box + gd_room_r(round4 H1:从 (0,0) 看大门 (2,2) 在东 = 右面的房间) await ctx.gesture('doubletap'); await ctx.waitVirtual(5600); ctx.status('电箱修好了。目标句后面照样跟着方位——「右面的房间。」大门在东边'); // 照方位句多跨两个房间摸向大门:(0,0) → 右×2 = (2,0) → 下×2 = (2,2) await move('right', '照方位句往右(东)摸'); await move('right'); await move('down'); await move('down', '脚步声停下来——面前这间就是大门'); ctx.status('解到通电、照目标句的方位跨了四个房间摸到大门,收工'); }