- engine/guide.js 运行时合成8个签名earcon(方法论L2硬参数),off档零定时器,插播queue不顶对白 - settings: guide三档(full/standard/off默认full) + 语速2.2视障档;audio: isVoicePlaying()/setRateBoostEnabled() 清两个已知问题 - 6游戏按schemes§2接线: storyline看门狗+无效手势纠错、simon免扣重听看门狗、escape turn cue+提前卡关提示、rhythm gd_answer/gd_miss+结算看门狗+快进豁免、space首撞指令提示+结算看门狗、rpg格挡纠错+60s催促+状态签名 - 大厅设置面板+向导文档(14-guide-layer.md)+00-global-ux §6;R5台词表补4条一致性 - 试玩转写含向导事件;6 playtest(guide=off断言零改动)+guide.test(34断言)+资产终检全绿
78 lines
3.2 KiB
JavaScript
78 lines
3.2 KiB
JavaScript
/**
|
|
* 《声命线》新手会话剧本:像真人一样等语音播完再动、偶尔走神(触发看门狗)、
|
|
* 在非抉择节点试一次无效的左滑(触发向导纠错)、菜单进去逛一圈再出来、
|
|
* 抉择点一律选左,一路打到结局。
|
|
*/
|
|
export function describe(game) {
|
|
if (game.mode === 'MENU') return '菜单里:左滑重开、右滑或单击返回剧情、上滑听帮助';
|
|
if (game.awaitingRestart) return '结局播完了。单击屏幕,可以回到故事开始的地方';
|
|
if (game.choiceArmed) return `「请选择」念完了(节点 ${game.nodeId}):左滑或右滑,做出你的决定`;
|
|
if (game.voicePlaying) return '旁白正在播。单击跳过本句,双击重听整个节点';
|
|
return `剧情等着你(节点 ${game.nodeId}):单击继续,双击重听`;
|
|
}
|
|
|
|
export async function session(ctx, mock) {
|
|
const { game } = ctx;
|
|
let invalidTried = false;
|
|
let menuDone = false;
|
|
|
|
// 开场:n00 全听完,愣一会儿——向导看门狗先说话
|
|
await ctx.waitIdle();
|
|
ctx.status('开场旁白播完了,屏幕黑着,有点不知所措');
|
|
ctx.silence(8, '新手没反应过来');
|
|
await ctx.waitVirtual(8600); // 触发看门狗:nudge + gd_continue
|
|
ctx.status('听到一声轻响和「轻触屏幕,继续」,试着点一下');
|
|
await ctx.gesture('tap');
|
|
|
|
for (let i = 0; i < 60 && !game.awaitingRestart && mock.now < 20 * 60 * 1000; i++) {
|
|
await ctx.waitIdle(); // 等当前语音链播完(真人不会抢话)
|
|
|
|
if (game.awaitingRestart) break;
|
|
|
|
// 中途进一次菜单,逛一圈再出来
|
|
if (!menuDone && game.nodeId === 'n04') {
|
|
menuDone = true;
|
|
ctx.note('想看看还有什么可按的,下滑呼出菜单');
|
|
await ctx.gesture('down');
|
|
await ctx.waitIdle();
|
|
ctx.status('菜单里');
|
|
await ctx.gesture('up'); // 听帮助 + 进度
|
|
await ctx.waitIdle();
|
|
await ctx.gesture('doubletap'); // 重听菜单项
|
|
await ctx.waitIdle();
|
|
ctx.note('听懂了,先回去继续剧情');
|
|
await ctx.gesture('tap'); // 关菜单(回剧情并重播当前节点)
|
|
continue;
|
|
}
|
|
|
|
if (game.choiceArmed) {
|
|
ctx.status('抉择点,提示音念完了');
|
|
if (mock.now % 2 < 1) await ctx.waitVirtual(3000); // 偶尔犹豫一下
|
|
ctx.note('选了左边');
|
|
await ctx.gesture('left'); // 抉择点一律选左
|
|
continue;
|
|
}
|
|
|
|
// W1:叙事节点播完,静默等待
|
|
ctx.status('剧情停下来了,在等我');
|
|
if (!invalidTried) {
|
|
invalidTried = true;
|
|
ctx.note('试着左滑了一下——这里用不上,向导纠正了我');
|
|
await ctx.gesture('left');
|
|
await ctx.waitIdle();
|
|
} else if (i % 4 === 2) {
|
|
ctx.silence(8, '走神想剧情去了');
|
|
await ctx.waitVirtual(8600); // 偶尔挂机,触发看门狗轻提醒
|
|
ctx.status('又听到那声轻响,想起该点屏幕了');
|
|
}
|
|
await ctx.gesture('tap');
|
|
}
|
|
|
|
await ctx.waitIdle();
|
|
ctx.status('结局');
|
|
ctx.note('听完结局,单击重开一次看看别的走向');
|
|
await ctx.gesture('tap'); // 结算态单击重开
|
|
await ctx.waitIdle();
|
|
ctx.status('回到开头,会话结束');
|
|
}
|