2026年3月5日 · Mikhail Vasilyev
《构宙》开发日志:引擎原型
一个半月前,我在网站上发布了工作室的计划——关于《构宙》引擎:它是什么,我们会在上面做哪些项目,一直到策略游戏和埃及系列的续作。那里还有一份路线图。引擎很复杂,为了降低风险,我想一步步把它搭起来。但玩家在评论里说得很直接:这种东西根本搭不出来。所以我决定先从一个原型做起——证明这样的引擎终究是能搭出来的。我要展示的就是它。

这就是引擎现在的样子。表面上看,它是个相当简陋的控制台程序。但它很好地说明了最重要的一点——不同的机制都跑在同一个通用引擎上。
现在上面跑着四个模拟。第一个是 Stone Age《石器时代》,工作室最早的一款游戏,2013 年的。另外三个是照着别人的项目做的。我没打算抄袭它们,也不会发布,它们摆在这里只是为了说明:完全不同的游戏机制可以跑在同一个引擎上。
Stone Age《石器时代》
《石器时代》在引擎上被完整复刻了出来。一样的属性、年份和回合、人口、土地。你把工人派进森林,他们采集食物,人口增长,科技出现——你研究它们,解锁建筑和进化树,从南方古猿到能人,再往后。事件、结局——原作里的一切都在。

Slay the Spire《杀戮尖塔》
接下来是 Slay the Spire《杀戮尖塔》,一款很出色的卡牌肉鸽游戏,应该有人玩过。引擎上只做了战斗这部分:玩家有手牌、能量和生命,敌人有自己的意图。Strike(打击)造成伤害,Defend(防御)提供格挡。你消耗能量,结束回合,就这样轮流来,直到分出胜负。

GURPS
第三个模拟是 GURPS,一套桌面游戏系统,相当复杂。我只从中取了一个模块,恒星系统生成器。有意思的是,这个模块本身根本不是游戏,而是一个复杂的生成器。它生成了一个系统:一颗恒星,外加一大堆属性,十条轨道,上面是各不相同的世界。第一颗又小又是岩质的,像水星——有自己的质量、大气压等等。整个模拟里一共有六千多条事实。这是一次很好的压力测试:能看出引擎能扛住多少数据。

Oregon Trail《俄勒冈之旅》
第四个是 Oregon Trail《俄勒冈之旅》,1971 年的经典,也是最早的电脑游戏之一。讲的是拓荒者驾着篷车横穿美洲:上路前先采购物资——牛、食物、弹药、衣物——然后一路打猎、分配口粮、应对各种事件。我们这就遭到了袭击。就这样一直走到旅程的终点。

四款游戏都跑在同一个引擎上,而且没有一个需要写代码。
运行时改
但引擎不只是把这些游戏跑起来——你还能在运行时直接改它们,不碰代码。拿 Slay the Spire《杀戮尖塔》来说。

我把 Strike(打击)牌的伤害改成 100:
/set Strike.CalcDamage Value 100这两张牌的属性一下子都变了,因为它们是同一个类。

也可以加一张全新的牌 Fireball(火球):
/add Fireball Is DirectDamage
/set Fireball.CostEnergy Value 2
/add Fireball Has CalcDamage
/set Fireball.CalcDamage Value 20
/add Fireball Has ApplyDamage
/add Fireball.ExecutionEffects Has CostEnergy
/add Fireball.ExecutionEffects Has CalcDamage
/add Fireball.ExecutionEffects Has ApplyDamage它本来不存在,现在进了游戏——躺在手里,能打出,造成 20 点伤害,然后像普通牌一样进弃牌堆:

连规则本身也能改,一条命令就行。我把“打出的牌进弃牌堆”这条规则去掉。
/remove PlayCard Has MovePlayedCard现在它们留在手里了。打出 Defend(防御):格挡挂上了,能量也花了,可牌还在。
![改了规则之后:Defend(防御)打出——能量 0/3,格挡 5——但所有打出的牌都留在手里,标着 [X]](/_next/image?url=%2Fvblog1_slayrule.jpg&w=3840&q=75)
在一款用编程语言写的普通游戏里,要做到这一点,得钻进代码、重新编译整个项目。在这里不用。
同样的方式,还能往游戏里加进原本压根没有的东西。比如金币——我把它建起来,并描述它是怎么花的:
/set Player.Gold Value 100
/add CostGold Output Owner.Gold
/add CostGold Math.Subtract.Apply true出现了一项刚才还没有的属性——金币,而且一上来就是整整一百。

有了这些金币,还能做一个新动作 Bribe(贿赂)。它花的不是能量,而是金币:
/add Bribe Is DirectDamage
/set Bribe.CostEnergy Value 0
/set Bribe.CostGold Value 30
/add Bribe Has CalcDamage
/set Bribe.CalcDamage Value 15
/add Bribe Has ApplyDamage
/add Bribe Has CostGold
/add Bribe.ExecutionEffects Has CostGold
/add Bribe.ExecutionEffects Has CalcDamage
/add Bribe.ExecutionEffects Has ApplyDamage
/create Bribe Player.HandBribe(贿赂)要花三十金币,造成十五点伤害——而且立刻就能用。

你可能会觉得这是作弊,觉得敲这些命令很别扭。但这不是作弊。这是在改整个游戏赖以成立的逻辑事实和数据——它的对象、属性和机制。本质上,这就是这款游戏所用的语言。
这门语言不学也行。你可以让 AI 把一句普通的话翻译成《构宙》能懂的命令。比如:
give 999 gold翻译过来不过就是“加 999 金币”。

AI 想了想,找到对应的命令并执行,于是我们就有了 999 金币。
换种说法也行,“金币 100”一样管用。“让我变成神”——AI 会给你无敌。结束回合、攻击、回血——这些都能用话说出来,引擎都懂。而且这里没有一处是脚本写死的,全都是真的在跑。
计划
命令我想再简化一下。现在要做出同样这张 Fireball(火球),得用大约八条命令,我想把它压到三四条。下一个视频里,我会尽量展示一些更直观的东西——2D 渲染。
关于引擎和后续计划的更多内容,见《构宙》专区。
声明:Stone Age《石器时代》是工作室自己的游戏。Slay the Spire《杀戮尖塔》、GURPS 和 Oregon Trail《俄勒冈之旅》归各自的权利人所有,这里只作为引擎演示展示——这些版本不在任何地方发布。
