Files
blind/game/js/games/shouye.js
T
xsl 866f363591 项目整理:重写主文档、归档过时文档、清理死代码、新增音频制作手册
文档整理:
- 重写 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
2026-06-19 22:29:04 +08:00

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: '《普通的夜班》。你做了你能做的,漏掉了一些,照顾到了一些。和所有普通的夜班一样。',
},
},
};