我们如何用程序生成一整座浮岛小镇
有机网格、一小套建筑语汇,加上大量“看邻居”的规则——《空岛日和》里房子、拱桥和屋顶背后的做法。
- #程序化生成
- #空岛日和
- #技术

在《空岛日和》里,你从来不用挑房子模型。点一下格子,长出一层;再点,就更高一层。至于墙、窗、屋顶、拱桥、台阶、码头和塔楼,全部由周围的格子推导出来。这篇讲讲它是怎么做的,以及为什么整个游戏还能塞进一个 0.7 MB 的 HTML 文件。
1. 一张看起来不像网格的网格
正方形网格会让小镇看起来像一张表格。我们想要的是山城那种微微弯曲的街巷,所以浮岛建在一张有机网格上:
- 先铺一片六边形的点阵,连成三角形。
- 随机把相邻的两个三角形合并成四边形。
- 把所有形状(三角形和四边形)再细分成更小的四边形,这样每个格子都恰好是四条边。
- 做几十轮松弛:一点点挪动每个顶点,让每个四边形都尽量接近正方形。
结果是一张每个格子形状都略有不同、但相邻格子总是共享整条边的网格。“四条边”非常关键:墙、屋顶、桥只需要为一种格子设计。
网格用固定种子生成,所有玩家拿到的都是同一张。这也是岛屿分享码能这么短的原因:链接里只需要记录“哪些格子有砖、是什么颜色”。
2. 每个格子是一根柱子
一个格子上最多叠八层,每层记住一个配色。整座小镇的数据就只有这些:高度和颜色。“盖成什么样”一个字节都不存。
3. 由上下文决定盖成什么
某根柱子变化时,我们看它和邻居,从一小套建筑语汇里挑部件:
- 靠岛边的地面层 → 石墙加拱门;靠内的地面层 → 带门的房子正面;挨着水 → 小木码头。
- 中间层 → 带窗的墙,但只有朝外露出的墙面才开窗,偶尔加个阳台或花箱。
- 顶层 → 坡屋顶加烟囱。如果邻居一样高,两片屋顶会合并成一条连排屋脊,沿着长边走。
- 两侧都有高楼的空格 → 架起拱桥。
- 邻居低一层 → 外侧台阶。
- 孤零零的一根高柱 → 尖顶塔楼。
单看每条规则都不复杂,合在一起,小镇就像被设计过一样,哪怕玩家只是随手乱点。这是第一个原型的核心目标:随便点十下,就应该得到一张想截图的画面。

4. 只重建变化的部分
在手机上,点击必须是“立刻”的。一根柱子变化时,它自己和紧挨着的一圈邻居在同一帧重建;外面两圈排进队列,每帧大约 4 毫秒的预算,分几次重建完。建筑再按区块合并,所以整座岛一帧大约只要 70 次绘制调用。
5. 不用贴图的水彩感
游戏里没有一张图片贴图。所有表面共用一种“水彩”材质:两三层柔和的明暗分层、偏蓝紫的阴影,再加一点程序化的笔触噪声。画面上下边缘轻微的移轴模糊,让小岛看起来像桌上的微缩模型。
6. 剩下的交给时间
每座建筑都记得自己第一块砖是什么时候放下的。随着真实时间流逝(关掉游戏也一样),常春藤爬上墙,屋顶长出青苔,窗台多了花箱;空地先长草,再开花,然后冒出小树苗,慢慢长成大树。外观来自“规则加时间”,所以不需要手工做任何动画。
自己试试
理解这些规则最快的办法是去“打破”它们:在空地中间叠一根高柱,然后在旁边加一个邻居,看看屋顶怎么改主意。