很长一段时间以来,Fortuna 在各个 Discord 服务器里掷骰子、管理货币,让一场场战役顺畅运转。可在幕后,这个机器人渐渐长成了一个庞大的单体程序,什么活儿都得它一肩挑——而裂缝已经开始显现。于是我们做了每个长寿项目最终都得面对的事:把它从头彻底重写。
全新的 Fortuna 响应更快、负载下更稳定,对我们来说也更好维护,更能跟着你的牌桌一起成长。这些工作大多发生在你永远看不到的地方——而这恰恰是重点所在。但它带来的改变,会在你实际使用的每一处冒出来。下面就来完整讲讲到底改了什么,以及这些改动为什么重要。
最初的 Fortuna 建立在一个很常见的模式上:机器人与 Discord 之间保持着一条永久敞开的连接——Discord 把它叫做 gateway(网关)——时时刻刻监听着它所加入的每一个服务器里发生的一切。随着机器人规模变大,为了扛住负载,这条连接被拆成了几个并行的副本,叫做 shard(分片),每个分片都是一个独立运行的进程,必须时刻盯着、随时重启,确保它们都健康运转。
这套方案能用,而且确实用了很多年。但它背后是实打实的代价。一个永久在线的机器人即便没人输入任何命令,也始终在占用内存、维持状态。它能看到的每一个服务器、频道和成员,都给它增添了一份负担。某个分片一打嗝,一大批服务器都可能跟着遭殃。而每加一个新功能,都得小心翼翼地穿插进一个本就同时在忙十几件事的程序里。
我们想要的是更精简的东西。有活儿干的时候才干活儿,没活儿的时候就安安静静,并且由一个个可以单独修复、单独扩展的小部件拼搭而成。
对于命令的处理,现代 Discord 机器人有更好的选择:机器人不必一直挂着连接干等,而是只在有人真正使用斜杠命令时,让 Discord 主动来叫它。Discord 会把这条命令打包,作为一个安全的网络请求发过来,机器人随即回应。没有常驻连接,没有空转的负担。无事发生时,机器人几乎不消耗任何资源。
这就是新设计的核心。我们把旧的单体拆成了两个各司其职的部分:
可以把它想象成一家餐厅。旧版 Fortuna 是一个手忙脚乱的厨子,一边点单、一边管大堂、一边还得在厨房里掌勺。而新版 Fortuna 有一个订单一到就瞬间开火的厨房(fortuna-http),还有一位专心守在门口、留意散客上门的迎宾(fortuna-gateway)。各干各的本职,谁也不拖谁的后腿。
架构的事儿说说挺好,但下面才是你在自己服务器上真正能感受到的东西。
响应更利落。 因为命令核心只干一件事,不背任何空转的包袱,它回应得又快又稳定。命令不必排在一堆杂事后面苦等。
可靠性更高。 这两个部分彼此独立。哪怕聊天掷骰的助手需要重启,你的斜杠命令也照样运转,连一下都不会卡。问题被牢牢圈住,而不会在整个机器人里一波波蔓延。
压力下更稳健。 无状态的命令核心不会随着服务器和玩家越堆越多而越背越重。再热闹的夜晚,表现也跟清闲时差不了多少。
改进更迅速。 有了干净、模块化的核心,我们就能添加和修复功能,而不必惊动它周围的一切。新命令能利落地嵌进来,这意味着更新更快地送到你手里。
重写也是个机会,让我们把惦记已久、一直想加的东西终于做出来。新版 Fortuna 带来了一批相当实在的功能:
/lc、管理员用 /mod_lc 来管理余额。奖励和等级都牢牢限定在你的社区范围之内。/config 命令,把按服务器划分的各项设置集中到一处,让每个社区都能把 Fortuna 调到贴合自己玩法的状态。/handouts 流程,把线索、信件和图片分享给你的牌桌,一张好的虚拟桌面本就该这样。/checkin 命令让标记出勤、让团队保持步调一致变得轻而易举。所有这一切,都与 Fortuna 一向的拿手好戏并肩而立:丰富的掷骰(既能通过斜杠命令,也能直接在聊天里敲出骰式)、每日奖励、等级、商店,以及其余种种。
最贴心的体验升级之一,就直接内建在新核心里:完整的本地化。Fortuna 如今能说 Discord 支持的所有语言——三十多种语言区域——并会根据每位用户的 Discord 设置自动挑选对应的那一种。命令名称、说明和回应都会以玩家自己的语言呈现,配上一套合理的回退链条,所以谁都不会盯着一段缺失的译文发愣。无论你的牌桌用葡萄牙语、英语、西班牙语、法语、日语,还是介于其间的任何一种语言来玩,Fortuna 都会迎上去,用对方的语言相见。
如果你喜欢技术细节,下面是几个我们引以为豪的选择——要是你不感兴趣,跳过这一节也完全没问题。
来自 Discord 的每一条命令请求,在 Fortuna 据此行动之前,都会用 Ed25519 签名做密码学校验,因此机器人只会对真实、未被篡改的请求做出回应。命令核心运行在 Bun 之上,搭配轻量的 Hono 框架;聊天掷骰助手则是一个用 Go 静态编译的小程序,空闲时占用极小。两者都以干净的容器镜像形式发布,让部署既快速又可复现。我们还接入了完善的错误监控,这样一旦出了岔子,我们能第一时间得知并迅速修复——同时格外小心,绝不记录任何敏感信息。
共用的掷骰引擎,与驱动我们其他工具的,是同一套久经信赖的算法,所以一次掷骰的含义完全一致,无论你是在 Discord 上掷,还是在这个生态里的其他任何地方掷。
这一切都没有改变 Fortuna 的内核。它依然是那个为你掷骰、把你的战役打理得井井有条的友好机器人。变的是底下的根基:更精简、更稳健,并且这样搭建——好让我们能不断把它打磨得更好,同时绝不碍着你的事。
把 Fortuna 加到你的服务器,试试这些新命令,再告诉我们你接下来想看到什么。你准备好了,骰子也就备好了。