〇、两个数字
4 ——项目最初的形态,是四张静态人物 CG,和一个接上 AI 的对话框。
11,452 ——到今天,这个世界产生过的"珠子"数量。每一颗,都是某个角色在某个时辰做了一件会被记住的事。
从 4 到 11452 中间,隔着 2,970 次提交 、 70,536 行代码 、 1,218 篇文档 ,和 四次推倒重来 。
这篇讲的就是那四次。
---
一、第一代:前后端是什么?
最早那个页面,简陋到不好意思叫"工程"。
四张人物 CG 摆上去,接一个 AI 接口,能打字,能回话。没有世界书,没有角色设定,没有配音—— 什么都没有 。
而且更要命的是: 那时候我们分不清前后端。
所有功能塞进一个网页里。数据、逻辑、界面、请求,全在一个文件里纠缠。你现在让我回看那份代码,我大概会说:那不是代码,那是一团勉强能跑的东西。
做到后面,自己都觉得不对劲——每加一个功能,另外三个功能就坏。于是才 开始正式学前后端 。
这是第一轮。严格说它不算"重构",算 启蒙 :我们第一次意识到,写程序不是把功能堆出来,是要先想清楚 什么东西该待在什么地方 。
---
二、第二轮:一次编码事故,和"废了也好"
第二轮重构的契机,说出来有点丢人,但它是真的。
那时候,工程被一次 AI 编码事故搞成了乱码。
背景是这样的:我们已经做出了一套 类似"酒馆"(SillyTavern)的体系 ——世界书、人物卡、设定分层。虽然还有 bug,但 至少能玩了 。对一个独立项目来说,这是很关键的节点:你终于有东西可以点开,可以给人看,可以自己玩一下午。
然后就出事了。一次 AI 批量编码,代码变成了乱码。
而且那天,我正好没上传 Git。
没有版本,没有备份,整个工程几乎废掉。
(这里我们不打算点名是哪个工具。 工具会出错,这是正常的,现在也依然会。 真要说责任,没提交 Git 的是我们自己——工具只是暴露了问题,不是问题本身。)
我记得很清楚,当时第一反应是: 算了,不做了。
那种感觉不是愤怒,是虚脱。你花了好几个星期堆出来的东西,一秒归零,而且是你自己没备份。
但是——
坐了一会儿,突然想通了:废了也好。不破不立。反正前后端我也没理清楚,那就重头理一遍。
这句话现在听起来很洒脱,当时其实是给自己找个台阶下。但 台阶找对了 。
因为确实,那套"酒馆式"的东西,就算没被搞坏,它身上也背着两个先天问题:一是前后端从一开始就没分开,二是在它的架构里, 世界是死的 。
事故只是把"迟早要做的决定"提前了。
所以我们重来。这一次,前后端彻底分开,数据归数据,逻辑归逻辑,界面归界面。
这是整个项目最疼的一刀,也是最值的一刀。
(顺带一个血泪教训: 勤提交。 这条比本文其他所有内容都实用。)
---
三、第三轮:酒馆的路子,是不是对的?
重建之后,我们手里有了一套"能用"的体系。然后开始问一个危险的问题:
"酒馆"这条路,是不是对的?
先解释一下。以 SillyTavern(圈内叫"酒馆")为代表的 AI 角色扮演方案,核心思路是:给角色写一张卡(人设、口癖、经历),再配一本世界书(设定条目,按关键词触发)。玩家说话,AI 扮演这个角色回话。
这条路成熟、有效、上手快。我们当时也是照着它做的。
但用久了,会发现三个绕不过去的坎:
第一,记忆是"印象",不是"事实"。
角色对你的记忆,本质是一段被压缩的文本摘要。它回答不了"三年前的谷雨那天,在山门,发生了什么"。
第二,世界是背景板。
世界书里的条目是静态的。玩家不触发,它就不存在。NPC 不会在你不在的时候做任何事——因为根本没有"你不在的时候"这个概念。
第三,时间长不了。
聊到几十轮之后,设定开始漂移,往事开始自相矛盾。你越认真地写设定,它忘得越让你难受。
于是我们开始想: 能不能不按这条路走?
这个念头落地的产物,就是 "珠子" 。
我们扔掉了"角色卡 + 世界书"的结构,改成一条 编年史(Chronicle) :
- 世界里发生的每一件有叙事价值的事,存成一颗 珠子 ;
- 一颗珠子同时封装四样东西—— 发生了什么、改变了谁与谁的关系、悬置了什么没解决的问题、为未来留下了什么势能 ;
- 珠子用 时空坐标 做主键:年、月、日、时辰、场景。
那条时空坐标的灵感,来自一件很土的事——
我在写地图模块的时候,看着屏幕上一堆场景节点,脑子里突然冒出一句:
> 地图上的每一个场景节点,不就是小说题头的空间维度吗?
传统章回小说每一回开头都有一行题头:
> 【大荒历 3421 年 · 春 · 三月十五 · 巳时 · 落星剑宗 · 山门】
它同时锚定了时间、地点、时辰氛围、在场的人。它不是装饰, 它是检索键 。
那如果它也能成为数据库的主键呢?
```javascript spacetime: { year: 3421, month: 3, day: 15, hour: 6, sceneId: "dahuang/jiuqiu/qingqiu/luoxing/shanmen" } ```
从这一行开始,项目性质变了。
这是第三轮重构。 它不是技术升级,是 路线选择 :我们不再做一个更好的"酒馆",我们开始做一个 档案馆 ——不让 AI 去"想起来",而是给它建一座能精确查阅的档案库。
---
四、第四轮:把易经写进数据库
如果第三轮是选路,第四轮就是 把路修到地基里 。
我们开始把 易经的象数结构和邵雍的层级时间观 引入底层。这不是加个皮肤、换个名词,是真的 重构了整个数据层 。
具体做了什么,举几个例子:
卦象不是装饰,是数据结构。 每个角色有本命卦,这个世界的基本分类法、关系推演、爻变逻辑,都建立在六爻结构之上。
时间不是数字,是层级。 受邵雍《皇极经世书》启发,我们建了一套层级时间: 时辰 → 日 → 月 → 年 → 世 → 运 → 会 → 元 。前四层已经跑通,后四层接口留着(这也是我们至今没做完的部分,后面会说)。
"八定九变"。 八是先天定命书,只读;九是后天变爻书,可追加。角色的命盘有不变的底色,也有会被经历改写的爻。
这一轮重构持续的时间最长, 一直走到今天 。
为什么会走到这一步?回头看,逻辑其实很直白:
> 既然我写的是一本东方背景的小说,那我用东方的时空观去组织它的数据,有什么奇怪的?
>
> 奇怪的反而是——为什么大家默认数据库就该按西方那套表格和范式来建?
当下的编程体系建立在拉丁字母的抽象传统上:原子化、线性化、逻辑化。而中文的思维结构是网络式、关联式、意象式的。
一颗珠子同时承载事实、情感、关系、势能,它就不太像一条数据记录,更像一个 意义复合体 。
> 如果未来会以中文的意义重新架构代码体系,这颗珠子就是新范式的第一个可运行的"字"。
这话我说得挺满。但我们是认真的。
---
五、主文件越写越短
四轮重构听起来很宏大,但有一个很小的细节,我觉得比什么都说明问题。
项目里有个文件叫 `galgame_framework.html`,是第二、三代的主入口。它现在还躺在根目录里,第一行写着:
```
⚠️ 已废弃(DEPRECATED 2026-08-22 雷定音)
本页面为旧版游戏框架(IIFE + window.* 时代)
正式游玩入口 = public/main-window.html
本页保留仅作旧链路 fallback 参考,新功能勿在此施工。
```
对照一下现在的入口:
| | 旧框架 | 现役主窗口 |
|:--|:--|:--|
| 主文件 | `galgame_framework.html` | `public/main-window.html` |
| 行数 | 955 行 | 330 行 |
| 组织方式 | 单体(IIFE + `window.*`) | 26 个 ES Module |
主入口从 955 行缩到了 330 行,功能却翻了几十倍。
因为世界不再被塞进一个文件——它被拆成了 26 个模块,各管一摊。
我很喜欢这个对比。 一个项目的成熟,有时候恰恰体现在主文件的萎缩上。 就像一座城市长大的标志,不是市中心那栋楼越盖越高,是它终于摊开成了许多各司其职的街区。
---
六、世界开始自转
扯完架构,说点实的:这半年到底产出了什么。
开发强度曲线 (按月提交数):
| 月份 | 提交数 |
|:--|:--|
| 2026-04 | 125 |
| 2026-05 | 408 |
| 2026-06 | 630 |
| 2026-07 | 855 (峰值) |
| 2026-08 | 732 |
| 2026-09 | 220(月中进行) |
几个节点 :
- 05-07 立 MANIFESTO。不是写文档,是想明白了"我们到底在做什么"。
- 06-17 爻辞 384 条全部填满(实测 390/390)。
- 07-27 千目凝珠架构立。这是"每一段叙事都能被独立召回"的能力。
- 08 势力关系层。三大势力(大荒神朝/合欢宗/落星剑宗)之间会自己产生冲突、结盟、领地摩擦。
- 09 给角色装上声音。四个 NPC 四把嗓子——陆苍雪是预设音色,轩辕霓裳是"慵懒妖冶的御姐音,尾音上扬带钩,像狐狸在笑"。
而这个数字是我最在意的 :
> 11,452 颗珠子。
不是我们写了多少代码,是 这个世界真实运转过多少次 。八千多、一万一千多次——每一次,是某个角色在某个时辰做了一件会被记住的事。
顺带说说这个世界本身。
大荒九丘是个修仙末世,天地灵气里混着一种叫 "劫灰" 的东西,修行艰难且危险, 飞升之路已经断绝 。世界由 九块漂浮在虚空中的浮陆 组成——这就是"九丘"。北寒落星丘上的落星剑宗,建在一条 正在死去的冰龙脉 上。
做"灵气枯竭"而不是"灵气复苏",不是口味问题,是工程问题: 一个资源正在耗尽的世界,天然地产生冲突、抉择和"该不该" ——而不是"强不强"。它逼着叙事往人物身上走,不往数值上走。
---
七、最近一次:给角色装上声音
九月初这轮,我们做了一件一直想做的事。
大荒九丘的对话产出,本来就是 按段切好的文本 + 发言人 + 情绪 (这是 VRC 演出层早就有的东西)。所以配音不是另起炉灶,是把已有的文本段 有声化 :
- 角色段 → 角色专属音色
- 旁白段 → 独立的叙述音色
- 情绪 → 转成自然语言风格指令,塞给 TTS
四把嗓子:
| 角色 | 音色 |
|:--|:--|
| 陆苍雪 | 冰糖(预设) |
| 林婉 | 茉莉(预设) |
| 轩辕霓裳 | 文本描述生成:"慵懒妖冶的御姐音,气息缠绵,尾音上扬带钩,像狐狸在笑" |
| 银蕊 | 文本描述生成:"清冷空灵的天狐音,吐字轻而字字分明,带一丝疏离" |
实测四小时, 165 次语音合成请求 ,生产侧和消费侧埋点 1:1 对账,没有丢。
过程中还抓到一个真 bug:某句台词里有"永不"这个带引号的强调词,净化器把它当成了整段台词,于是整句被截成两个字——
```
原文:……嘴上说着"永不"的人,脚步可往往最诚实。
净化后:永不
```
查出来之后,我们把它写进了架构文档的契约里: 净化器只剥舞台动作的括号,绝不做引号抽取 。回归测试 59 条含括号台词,59 条全部正确。
这种事听起来很小,但纪实就该记这些。 世界的真实感,是被几十个这种小坑垫起来的。
---
八、还没做到的
机核的读者大概最烦自吹,所以把没做到的也摆出来:
- 单句语音有 1~2 秒延迟 。目前的取舍是"整段文字齐了才发声",逐字同步要等下一阶段。
- 文本描述的音色会浮动 。同一次描述两次调用,字节量差约 7KB——声线气质稳定,语速断句会飘。
- 历史重读没有情绪 。冷加载的旧对话拿不到当时的情绪标记,只能中性兜底。
- 玩家语音输入、实时语聊还没做 。接口位留了,没接。
- 高层时间(世/运/会/元)的跨层计算还没实现 。时辰→日→月→年这四层通了,上面四层还在纸上。
- 生产库里势力关系珠子是 0 条 。不是 bug——是几个角色的成员还没在同一场景里碰过面。它在等一个时机。
这些不是免责声明,是待办清单。
---
九、所以,我们现在在哪
半年多前,是四张 CG 和一个对话框。
今天是 70,536 行代码、1,218 篇文档、11,452 颗珠子,四把各有性格的嗓子,和一个在你关掉页面后仍会继续生长的末法世界。
我们推倒了它四次。第一次因为不懂,第二次因为一场事故,第三次因为不想走别人的路,第四次因为想把根扎得更深。
有人问过:你们为什么不直接做一个 AI 版的 Galgame?
不是做不了。是我们想要的更多。
但这句话今天还只是我们的说法,不是结论。 等这个世界再跑一程,等有人真的在里面过完一段日子,我们再来说这话。
那会是另一篇文章。
---
_大荒九丘 · 坏空之纪_
_2026 年 9 月 10 日,于第 2,970 次提交之后_
---
评论区
共 条评论热门最新