2026年3月5日 · Mikhail Vasilyev

《構宙》開發日誌:引擎原型

Watch on YouTube

一個半月前,我在網站上發布了工作室的計畫——關於《構宙》引擎:它是什麼,我們會在上面做哪些專案,一直到策略遊戲和埃及系列的續作。那裡還有一份路線圖。引擎很複雜,為了降低風險,我想一步步把它搭起來。但玩家在留言裡說得很直接:這種東西根本搭不出來。所以我決定先從一個原型做起——證明這樣的引擎終究是能搭得出來的。我要展示的就是它。

原型選單:引擎讓你從四個模擬裡選一個——Stone Age《石器時代》、Slay the Spire《殺戮尖塔》、恆星系統生成器,以及 Oregon Trail《俄勒岡之旅》

這就是引擎現在的樣子。表面上看,它是個相當簡陋的主控台程式。但它很好地說明了最重要的一點——不同的機制都跑在同一個通用引擎上。

現在上面跑著四個模擬。第一個是 Stone Age《石器時代》,工作室最早的一款遊戲,2013 年的。另外三個是照著別人的專案做的。我沒打算抄襲它們,也不會發布,它們擺在這裡只是為了說明:完全不同的遊戲機制可以跑在同一個引擎上。

Stone Age《石器時代》

《石器時代》在引擎上被完整重現了出來。一樣的屬性、年份和回合、人口、土地。你把工人派進森林,他們採集食物,人口成長,科技出現——你研究它們,解鎖建築和演化樹,從南方古猿到能人,再往後。事件、結局——原作裡的一切都在。

原型主控台:Stone Age《石器時代》——部落屬性、土地、科技與演化選單

Slay the Spire《殺戮尖塔》

接下來是 Slay the Spire《殺戮尖塔》,一款很出色的卡牌 Roguelike,應該有人玩過。引擎上只做了戰鬥這部分:玩家有手牌、能量和生命,敵人有自己的意圖。Strike(打擊)造成傷害,Defend(防禦)提供格擋。你消耗能量,結束回合,就這樣輪流來,直到分出勝負。

同一個主控台執行 Slay the Spire《殺戮尖塔》——生命、能量、敵人的意圖,以及手牌

GURPS

第三個模擬是 GURPS,一套桌上遊戲系統,相當複雜。我只從中取了一個模組,恆星系統生成器。有意思的是,這個模組本身根本不是遊戲,而是一個複雜的生成器。它生成了一個系統:一顆恆星,外加一大堆屬性,十條軌道,上面是各不相同的世界。第一顆又小又是岩質的,像水星——有自己的質量、大氣壓等等。整個模擬裡一共有六千多條事實。這是一次很好的壓力測試:能看出引擎能扛住多少資料。

GURPS 模組裡生成的一個恆星系統——恆星、各條軌道,以及第一個世界的屬性

Oregon Trail《俄勒岡之旅》

第四個是 Oregon Trail《俄勒岡之旅》,1971 年的經典,也是最早的電腦遊戲之一。講的是拓荒者駕著篷車橫越美洲:上路前先採購物資——牛、食物、彈藥、衣物——然後一路打獵、分配口糧、應對各種事件。我們這就遭到了襲擊。就這樣一直走到旅程的終點。

同一個主控台裡的 Oregon Trail《俄勒岡之旅》:物資——食物、彈藥、衣物、金錢——以及遇到騎手時的行動選擇

四款遊戲都跑在同一個引擎上,而且沒有一個需要寫程式碼。

執行時即時改

但引擎不只是把這些遊戲跑起來——你還能在執行時直接改它們,不碰程式碼。拿 Slay the Spire《殺戮尖塔》來說。

引擎上 Slay the Spire《殺戮尖塔》的起始回合:生命、能量、敵人,以及手裡的五張牌——Strike(打擊)的傷害還是 6

我把 Strike(打擊)牌的傷害改成 100:

/set Strike.CalcDamage Value 100

這兩張牌的屬性一下子都變了,因為它們是同一個類。

手裡有兩張 Strike(打擊)牌,現在都是 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 點傷害,然後像普通牌一樣進棄牌堆:

改完之後:兩張 Strike(打擊)牌都是 100 點傷害,手裡還多出一張 20 點傷害的新牌 Fireball(火球)

連規則本身也能改,一條指令就行。我把「打出的牌進棄牌堆」這條規則去掉。

/remove PlayCard Has MovePlayedCard

現在它們留在手裡了。打出 Defend(防禦):格擋掛上了,能量也花了,可牌還在。

改了規則之後:Defend(防禦)打出——能量 0/3,格擋 5——但所有打出的牌都留在手裡,標著 [X]

在一款用程式語言寫的普通遊戲裡,要做到這一點,得鑽進程式碼、重新編譯整個專案。在這裡不用。

同樣的方式,還能往遊戲裡加進原本根本沒有的東西。比如金幣——我把它建起來,並描述它是怎麼花的:

/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.Hand

Bribe(賄賂)要花三十金幣,造成十五點傷害——而且立刻就能用。

手裡出現了一個新動作 Bribe(賄賂):零能量、三十金幣、十五點傷害

你可能會覺得這是作弊,覺得敲這些指令很彆扭。但這不是作弊。這是在改整個遊戲賴以成立的邏輯事實和資料——它的物件、屬性和機制。本質上,這就是這款遊戲所用的語言。

這門語言不學也行。你可以讓 AI 把一句普通的話轉換成《構宙》能懂的指令。比如:

give 999 gold

翻譯過來不過就是「加 999 金幣」。

用大白話向 AI 發出請求——「give 999 gold」。引擎會自己找到對應的指令並執行

AI 想了想,找到對應的指令並執行,於是我們就有了 999 金幣。

換種說法也行,「金幣 100」一樣管用。「讓我變成神」——AI 會給你無敵。結束回合、攻擊、回血——這些都能用話說出來,引擎都懂。而且這裡沒有一處是腳本寫死的,全都是真的在跑。

計畫

指令我想再簡化一下。現在要做出同樣這張 Fireball(火球),得用大約八條指令,我想把它壓到三四條。下一個影片裡,我會盡量展示一些更直觀的東西——2D 渲染。

關於引擎和後續計畫的更多內容,見《構宙》專區。

聲明:Stone Age《石器時代》是工作室自己的遊戲。Slay the Spire《殺戮尖塔》、GURPS 和 Oregon Trail《俄勒岡之旅》歸各自的權利人所有,這裡只作為引擎演示展示——這些版本不在任何地方發布。