会自己运转的世界
一组靠局部规则自己变化的模拟实验,从 2017 年断断续续做到现在。留下来的有生命游戏和沙漠水热反应的代码,还有一份没写完的温度草稿。
- TYPE
- 局部规则驱动的模拟实验
- STATUS
- 有规则和原型,还没有一个算做完
- WHEN
- 2017 至今
- BUILT WITH
- Unity 和 Bevy,用 C# 与 Rust 写
- WHO
- 我一个人做的
这是什么
这组实验是让局部规则推动变化,有格子的生灭,也有温度和物质在邻格之间的传递。开发日志最早一条写在 2017 年 12 月,那时我已经在想用元胞自动机(格子和邻居)搭游戏世界。
引擎换过好几轮,2017 年是 Laya,2018 年换成 Phaser,2021 年起用 Unity 和 Bevy,2024 年 5 月我比较过几个引擎,2026 年 4 月用 Bevy 做了沙漠实验。最早两个阶段的原工程找不到了,后面几个阶段还留着提交记录或文件。
FIG. 1 · 换过的引擎
年份和引擎按开发日志整理。实线框是留有提交记录或文件的阶段,虚线框只在日志里有记录。
格子只看身边
Unity 那版默认是 100 × 100 个格子,每格随机有 50% 的机会存活。每格只数身边八格,左边接右边,上边接下边,边缘格也有八个邻居。
活格有两个或三个活邻居就留下,死格恰好有三个活邻居才出生,其他情况都变成死格。全部格子先读这一轮的数组,把结果写进下一轮,算完才交换,这样结果不取决于先算哪个格子。代码每帧推进一轮,没有单独的计时器。
FIG. 2 · 一轮格子更新
按代码里的规则画的示意图,不是运行截图。
地表会改变水和反应
沙漠原型用连续数组存水、矿物、溶解物、有机前体和热值,默认 512 × 512 格,一格不对应一个独立实体。每帧默认推进三次,可以调到 1–24 次,也能暂停,七种视图和鼠标探针用来看整体和单格。
每一步先处理降雨,再算水流、热扩散和溶解物扩散,应用变化之后做反应。沙、岩石、黏土和反光平地各有一组参数,保水参数决定水留下多久,流动参数管水流和扩散,催化参数管矿物风化和合成。
这里的水量和热值是实验里的数,没有做现实单位校准,热值不能读成摄氏度。推进次数跟着帧走,同一组规则跑多快会受帧率影响。
FIG. 3 · 四种地表的基础参数
数值是代码里的地表基础参数,用 0–1 的数表示,没有校准物理单位。实际每格还会加扰动,表里的数不是每格的最终值。
有机物还不是生命
雨水让矿物溶解,水、热值和地表参数一起影响有机前体的合成,之后有机物还会衰减,一部分回到溶解物里。这里说的“有机物”只是一个数值场,现在没有复制规则,生命量也没有更新。
画面里的反应适宜度只是一项显示和统计分数,越过阈值不等于生命出生。物质守恒还没建立,溶解物只按浓度差扩散,没有跟着水流搬运。
做到哪了
- 已有的是两套生命游戏规则、温度创建和平均的草稿,以及沙漠里的水热和非生命反应代码。
- 温度草稿的传播和邻接部分还注释着,创建部分有未定义变量,还不能当成能运转的热传导。
- Unity 生命游戏每帧都新增整片格子的显示对象,Bevy 那版只在启动时画一次,后续的格子变化不会更新到图像上。
- 用汉字当材料的那一支后来单独做下去了,见文字修仙。