文档整理: - 重写 game/操作说明.md 为项目主文档(6游戏/6手势/旁白/模型生成音频/TTS两步流程) - 归档过时文档至 other_docs/(林夏原始设计、旧执行文档) - 新增 docs/音频制作执行手册.md(从零制作游戏音频的完整流程) - docs/ 下保留旁白音色提示词、音频脚本 代码清理: - 删除旧架构死代码: story.js / gestures.js / profile.js - 删除耦合旧架构的过时测试目录 game/tests/ 脚本配置修正: - check_tts_env.sh: 启动脚本路径 AutoVideo → tts-server(实际位置) - gen_narrator_samples.py: 硬编码地址改为环境变量,默认对齐 tts-server 端口 8000
176 lines
8.2 KiB
JavaScript
176 lines
8.2 KiB
JavaScript
// games/shouye.js — 《守夜》
|
|
// 夜班保安,监控室,五个小时。
|
|
// 单击=去查那个声音,双击=按兵不动。
|
|
// 结局由你调查了什么决定。
|
|
|
|
const GAME_SHOUYE = {
|
|
id: 'shouye',
|
|
intro: '凌晨零点。你是这栋楼的夜班保安,独自坐在一楼监控室。你不能离开座位,但你有一部对讲机和一部电话。今晚五点交班。单击,去查那个声音。双击,按兵不动。',
|
|
first: 's01',
|
|
bgm: null,
|
|
ambience: '../audio/mp3/ambience/amb_apartment_night_01_v1.mp3',
|
|
initialState: {
|
|
investigated: [],
|
|
ignored: [],
|
|
family_called: false,
|
|
saw_dawn: false,
|
|
missed_fight: true, // 默认"没管四楼争吵"
|
|
},
|
|
|
|
scenes: {
|
|
// ── 00:10 地下室水声 ──
|
|
s01: {
|
|
delay: 2000,
|
|
narrate: '凌晨零点十分。地下室传来水声,不大,但是持续的,一直在响。',
|
|
tap: {
|
|
label: '打电话下去查',
|
|
narrate: '你拨了地下室的内线。没人接。你下去看了一眼,是一根管子在漏水,用旧布堵住了。回到监控室,零点二十三分。',
|
|
state: s => ({ investigated: [...s.investigated, '地下室漏水'], ignored: s.ignored }),
|
|
next: 's02',
|
|
},
|
|
doubleTap: {
|
|
label: '先不管',
|
|
narrate: '你听了一会儿。应该不碍事。你把注意力放回到监控屏幕上。',
|
|
state: s => ({ investigated: s.investigated, ignored: [...s.ignored, '地下室水声'] }),
|
|
next: 's02',
|
|
},
|
|
},
|
|
|
|
// ── 00:47 四楼争吵 ──
|
|
s02: {
|
|
delay: 3000,
|
|
narrate: '零点四十七分。四楼传来争吵声,一男一女,断断续续,能听出来语气很激动,但听不清说什么。',
|
|
tap: {
|
|
label: '打电话上去',
|
|
narrate: '你拨了四楼的号码。男的接了,说没事,就是聊天,让你别担心。声音还是有点紧,但他们关掉了。你记下来了:四楼,零点五十二分,双方均在场。',
|
|
state: s => ({ investigated: [...s.investigated, '四楼争吵'], ignored: s.ignored, missed_fight: false }),
|
|
next: 's03',
|
|
},
|
|
doubleTap: {
|
|
label: '不管,私事',
|
|
narrate: '家务事,你管不着。你转过身去继续盯着屏幕。争吵后来停了,你不知道是什么时候。',
|
|
state: s => ({ investigated: s.investigated, ignored: [...s.ignored, '四楼争吵'], missed_fight: true }),
|
|
next: 's03',
|
|
},
|
|
},
|
|
|
|
// ── 01:17 三楼脚步(老陈)──
|
|
s03: {
|
|
delay: 3000,
|
|
narrate: '凌晨一点十七分。三楼有脚步声,很轻,走走停停。监控记录:三楼只有七零二亮着灯,住户是老陈,八十岁,独居。',
|
|
tap: {
|
|
label: '打电话问问',
|
|
narrate: '电话通了,老陈说他在找眼镜,眼镜掉床底下了。你说没事我就是例行确认一下。他说谢谢你小伙子,然后你们聊了几句,关于他年轻时候也做过工程。你挂掉电话,一点二十八分。',
|
|
state: s => ({ investigated: [...s.investigated, '三楼老陈'], ignored: s.ignored }),
|
|
next: 's04',
|
|
},
|
|
doubleTap: {
|
|
label: '应该没事',
|
|
narrate: '老人家睡不好,很正常。你记了一笔,继续监控。脚步声后来停了。',
|
|
state: s => ({ investigated: s.investigated, ignored: [...s.ignored, '三楼脚步'] }),
|
|
next: 's04',
|
|
},
|
|
},
|
|
|
|
// ── 02:03 门铃无应答 ──
|
|
s04: {
|
|
delay: 4000,
|
|
narrate: '凌晨两点零三分。大门门铃响了,不是访客系统,是有人在外面按了手动铃,按了两下,然后停了。没有人应答。监控画面:门口没有人了。',
|
|
tap: {
|
|
label: '出去看看',
|
|
narrate: '你走到门口,什么都没有,只有一个快递包裹靠在墙边,大概是外卖或者什么。也许是送错了。你把包裹推到角落,拍了张照,两点一刻回到座位。',
|
|
state: s => ({ investigated: [...s.investigated, '门铃'], ignored: s.ignored }),
|
|
next: 's05',
|
|
},
|
|
doubleTap: {
|
|
label: '不是你管的事',
|
|
narrate: '无应答,无入侵,记录在案,按流程忽略。你回到屏幕前。',
|
|
state: s => ({ investigated: s.investigated, ignored: [...s.ignored, '门铃'] }),
|
|
next: 's05',
|
|
},
|
|
},
|
|
|
|
// ── 02:55 你打盹了(自动)──
|
|
s05: {
|
|
delay: 4000,
|
|
narrate: s => {
|
|
const base = '凌晨两点五十五分。你不知道从什么时候开始,眼皮变得很重……你睡着了一会儿。';
|
|
if (s.missed_fight)
|
|
return base + '醒来的时候,你看到监控里,四楼门口放着一个箱子,不知道是谁的,不知道什么时候放的。';
|
|
return base + '醒来的时候,监控里一切正常。你记录:三点十二分,短暂失守。';
|
|
},
|
|
next: 's06',
|
|
},
|
|
|
|
// ── 03:30 家人来电 ──
|
|
s06: {
|
|
delay: 3000,
|
|
narrate: '凌晨三点半。你的私人手机响了。是家里的人打来的。这么晚打来——可能是什么事,也可能只是弄错时间了。',
|
|
tap: {
|
|
label: '接了',
|
|
narrate: '是你妈,她说睡不着,看见你今天发的朋友圈,就想打个电话。你们聊了十分钟,说了些不重要的事。挂掉之后,监控室比之前暖了一点点。',
|
|
state: s => ({ ...s, family_called: true }),
|
|
next: 's07',
|
|
},
|
|
doubleTap: {
|
|
label: '没接',
|
|
narrate: '这么晚不方便。你把手机调成静音,准备待会儿发条消息。你没有发。',
|
|
state: s => ({ ...s, family_called: false }),
|
|
next: 's07',
|
|
},
|
|
},
|
|
|
|
// ── 04:12 屋顶声音 ──
|
|
s07: {
|
|
delay: 4000,
|
|
narrate: '凌晨四点十二分。屋顶传来动静,断断续续,不像是机械设备,更像是有什么东西在走动。',
|
|
tap: {
|
|
label: '上去看',
|
|
narrate: '你拿着手电上了顶层,推开屋顶的铁门,风吹过来,你看见了天边刚刚开始发白的颜色——还不是黎明,但是快了。然后你看见了一只流浪猫,坐在水箱上看着你。你们看了对方一会儿,然后你下来了。你是今晚唯一上了屋顶的人。',
|
|
state: s => ({ ...s, investigated: [...s.investigated, '屋顶'], saw_dawn: true }),
|
|
next: 's08',
|
|
},
|
|
doubleTap: {
|
|
label: '可能是猫',
|
|
narrate: '你记了一笔,继续监控。动静后来停了。',
|
|
state: s => ({ ...s, ignored: [...s.ignored, '屋顶声音'], saw_dawn: false }),
|
|
next: 's08',
|
|
},
|
|
},
|
|
|
|
// ── 05:00 交班(自动→结局)──
|
|
s08: {
|
|
delay: 5000,
|
|
narrate: '五点整。接班的人进来了,你们交接了几句,递了记录本,你背上包走出去。外面已经有一点点亮了。',
|
|
next: null,
|
|
},
|
|
},
|
|
|
|
getEnding: s => {
|
|
if (s.saw_dawn) return 'dawn';
|
|
const n = s.investigated.length;
|
|
if (n >= 4 && s.family_called) return 'solid';
|
|
if (n <= 1 && !s.family_called) return 'detached';
|
|
if (s.missed_fight) return 'oversight';
|
|
return 'ordinary';
|
|
},
|
|
|
|
endings: {
|
|
dawn: {
|
|
narrate: '《你看到了什么》。今晚你一个人上了屋顶,你看到了那只猫,你看到了天边开始变色。只有你看到了。这算不上什么,但只有你知道。',
|
|
},
|
|
solid: {
|
|
narrate: '《平凡守夜》。你今晚查了应该查的,接了应该接的电话。没有大事,没有遗漏。这栋楼平安了一夜,有一部分是因为你在。',
|
|
},
|
|
detached: {
|
|
narrate: '《这不是我的事》。你今晚保持了距离。声音来了,你记录,你不动。你守住了一夜,但不知道楼里发生了什么。这也是一种守夜的方式。',
|
|
},
|
|
oversight: {
|
|
narrate: '《疏忽》。你今晚漏掉了四楼的事。那个女人在凌晨两点多拎着箱子离开了,你没有注意到。也许和你没有关系。也许有。你不知道。',
|
|
},
|
|
ordinary: {
|
|
narrate: '《普通的夜班》。你做了你能做的,漏掉了一些,照顾到了一些。和所有普通的夜班一样。',
|
|
},
|
|
},
|
|
};
|