对抗型与沙盒模拟:建模 NIMBY 城市
当城市会反击,NIMBY 式的阻力就变成了游戏机制。对比对抗型与沙盒城市模拟各自擅长建模什么,以及何时该选哪一种。

有人做了一款城市建造游戏,你扮演旧金山的住房开发商,而城市本身就是最终 Boss。你想盖公寓楼,分区法规、规划委员会、邻居和上诉程序却处处阻拦。有位玩家在模拟的十六年里盖了 4,147 套住房,扛过 16 场听证会、3 次上诉和 4 场诉讼,最后拿到了“盖了点东西的建造者”评级,而这座城市需要超过 8.2 万套。作为政治讽刺,它相当好笑。作为模拟设计,它也确实有意思,因为它颠覆了自《模拟城市》以来几乎所有城市建造游戏的基本假设:玩家是无所不能的市长,模拟系统只是等着被优化的对象。在这里,模拟系统本身就是你的对手。
全知市长模型:《模拟城市》及其后继者
经典城市建造游戏属于沙盒模拟。你划分区域、收税、修路,而那些小小的模拟市民会对你的决策做出反应。有意思的是,这类游戏底层的模型在四十年间惊人地一致:地价、污染、交通流量和服务覆盖率都是网格上的场,而智能体(也就是模拟市民)会根据这些场做出简单决策。当下的重量级作品《城市:天际线 II》模拟了带有生命周期、工作地点和通勤路线的个体家庭,但它们从来不会对你提起诉讼。它们做不到。在系统里,它们的角色是被影响,而不是主动出招。
这种设计选择悄悄编码了一种政治哲学。在《模拟城市》里,如果你想从某个街区中间修一条高速公路,你直接修就行了。那片街区的居民最多也只是幸福度条上的一个小波动。游戏的反馈机制奖励的是吞吐量:更多分区、更多人口、更多税基。任何玩过这类游戏上百小时的人,都会内化一种世界观:好的城市规划之所以难,障碍在于玩家自己的远见不足。而这恰恰是现实中城市政策争论的核心。游戏教你像罗伯特·摩西那样思考,然后真实的城市会提醒你,正是罗伯特·摩西让我们有了今天这些规则。
我并不是要踩低这个类型。沙盒模拟在它擅长的事情上非常出色:培养人们对基础设施、土地利用以及分区二阶效应的系统直觉。把工业区紧挨着住宅区,地价就会被拖垮;拥堵来自道路层级而非路面宽度。这些教训都是真实的。但沙盒模型有一个大得像规划部门一样的盲点:它把治理摩擦当成噪声,而不是当成系统本身的一部分。
对抗型模型:把城市当作对手
NIMBY 城市建造游戏把这个思路反过来。你是一名开发商,资源是资金、时间和投资人的耐心。对手则是一套程序化的官僚体系:自由裁量式的审查听证、环境评估、社区上诉,以及时刻存在的诉讼威胁。你的目标不是最大化城市的幸福度,而是在资金耗尽或投资人失去信心之前,让房屋获得批准并建成。每一道审批关卡都是一次掷骰子,其概率由你所在片区的政治生态加权决定。
从机制上看,它更接近肉鸽(roguelike)而不是城市建造。你有一局游戏,资金或耐心耗尽时这局就结束。程序化生成的内容不是地形,而是流程。而这正是值得借鉴的洞察:官僚体系是一种可以被清晰描述、也可以被机制化的系统。听证会有排队,上诉有计时器,每道关卡都有吞吐量和失败率。如果你眯起眼睛看,一条审批流水线就像一个请求穿过一组过载的服务,途中有重试、有背压,偶尔还会丢包,而每次丢包都会让你损失十一个月。任何一个后端工程师看到这里,都会意识到自己在工作中已经搭建过这样的系统,只不过初衷要好得多。
有个 Factorio 模组常被人拿来调侃,它把文书处理做成了一棵配方树:如果你不清理官僚积压,组装机就会停工,而虫子会排队把投诉表格递给你。这个笑话之所以能引起共鸣,是因为它几乎不算玩笑。对抗型流程模拟玩起来之所以感觉如此不同,是因为它把等待变成了核心资源问题。在沙盒模拟里,时间基本是免费的,你直接快进就行。而在对抗型模拟里,时间正是对手想从你手里夺走的东西,因为拖延是否决点最可靠的杀伤机制。这并不是游戏里的抽象设定,而是住房政治的真实运作方式:你很少能直接击败一个项目,而是让它一直等,直到它自己死掉。
两种模型实际捕捉到了什么
坦白说,两者的对比是这样的。没有哪种模型是关于城市的“真相”,每一种都捕捉到了不同的因果层,而且它们的失败方向恰好相反。
- 沙盒模拟很擅长捕捉物理系统。交通、污染、地价、服务覆盖、高密度带来的网络效应,这些都是连续的场和流。网格上的智能体模型确实能复现诸如交通拥堵崩溃、绅士化压力之类的涌现现象。
- 沙盒模拟对政治系统的捕捉非常糟糕。把反对声简化成一个幸福度数值,并不是对权力的建模。它无法表达一个小而有组织、长期扎根的少数群体可以压倒一个分散而忙碌的多数,而这恰恰是地方土地利用政治中最重要的事实。
- 对抗型模拟很擅长捕捉否决点。自由裁量审查、上诉、诉讼风险以及把拖延当作武器,这些都是离散的、有状态的、可以被博弈的,非常适合做成机制。游戏正确地复现了经验性结果:当每个项目都要经过谈判,只有背后有律师团队的大开发商才能活下来,于是住房变得更少,项目却变得更大。
- 对抗型模拟对物理系统的捕捉非常糟糕。一旦你把房子盖好,模拟就不管这片社区是否真能正常运转。交通、学校、下水道,要么被抽象掉,要么被忽略。你完全可能赢得游戏,却建出一个功能失调的地方。
- 两者在反事实推演上都不及格。两种模型都无法展示在不同规则下会存在怎样的城市,而这恰恰是政策制定者真正争论的问题。
最后这一点值得强调,因为它正是这个比较超出游戏范畴的地方。那些争论分区法规修改的人,比如加州近年来一连串剥夺地方自由裁量权、允许在公交站点附近放宽限制的州级先占法案,实际上都在讨论一个反事实模拟。双方都在运行各自的心智模型:一方认为拆除否决点会释放供给,另一方则认为拆除之后会在不明显拉低房价的情况下毁掉社区特色。一款能让否决点这一层可以被玩的游戏,对这场争论是非常有价值的贡献,因为它迫使你去直面机制本身,而不是停留在感觉层面。当一位玩家通关时只盖了 82,000 套所需住房中的 4,000 套,他得到的教训不是“开发商太贪”或“邻居太自私”,而是:吞吐量是流程的属性,而不是任何人意图的属性。

模拟反对声的工程学
从模拟工程的角度看,对抗型模型之所以有意思,是因为反对力量是异质的能动性。邻居们不是一个场,而是有记忆、有关注度、动机又不对称的行动者。要把他们建模好,就得从人工智能工具箱里借鉴一些与城市建造游戏通常所用不同的东西。以下几种模式比较常见:
- 带滞回的激活阈值。大多数居民从来不会关注一份许可申请。只有当感知到的影响跨过某个阈值时,反对才会被激活,而且一旦激活,即使情况有所改善也不会自动消退。这种不对称很容易建模,也基本上就能复现现实中的大部分动态。
- 基于队列的流程关卡。每个审查阶段都是一个带有服务速率的队列。延迟来自负载,而不是恶意,这既符合现实,也正是游戏核心张力的来源。你可以把整个规划部门建模成几条
M/M/1队列,得到的行为却出奇地贴近现实。 - 作为持续伤害的延迟。持有成本按月累积。这一个机制就把程序性拖延转化为玩家能直接感受到的压力,并自然导出正确的策略适应:开发商会为“按权利可直接开发”的地块多花钱,并完全避开需要自由裁量审查的片区。
- 带记忆的随机冲击。一场诉讼不只是花钱,它还会改变片区的政治状态。持久的片区状态让一次性事件变成了路径依赖。
一个核心循环的最小草图大致是这样的:
class Project:
def __init__(self, units, district):
self.units = units
self.district = district # has: opposition_level, backlog, discretion
self.stage = "application"
self.months_in_process = 0
def tick(self, month):
self.months_in_process += 1
# carrying costs: land, loans, staff. delay is the killer.
burn = self.units * 900 # $/unit/month while entitled is pending
if self.stage == "application":
if self.district.backlog < self.district.staff_capacity:
self.stage = "hearing"
self.district.backlog += 1
elif self.stage == "hearing":
self.district.backlog -= 1
p_appeal = min(0.85, self.district.opposition_level
* (1 + self.district.past_appeals * 0.2))
self.stage = "appeal" if random.random() < p_appeal else "entitled"
elif self.stage == "appeal":
if self.months_in_process % 6 == 0: # appeals resolve slowly
self.stage = "entitled" if random.random() < 0.5 else "lawsuit"
return burn
这段代码只有四十行,却已经复现了这类游戏的标志性结果:无论需求多大,高反对的片区都建不起东西;开发商会扎堆进入低阻力片区;而“获批所需时间”主导着项目的经济性。规范与其涌现行为之间的差距,正是我们在规范与实现之间的差距一文中探讨过的那类问题。没人会在分区法规里写“制造住房短缺”,但短缺依然会从规则中自然冒出来。
涌现行为与脚本化难度
这里有一个很关键的设计分岔:你是给反对方写脚本,还是让它自然涌现?脚本化的难度,比如每一关城市都莫名其妙地更加难缠,更容易平衡,但教给玩家的却是错误的东西。它告诉玩家系统是出于意图而被操纵的。而由队列、阈值和持有成本涌现出来的反对,教给玩家的则更接近真相,也更让人不舒服:即使每个个体都在合理行事,系统依然会产生这些结果。一个积压了九个月案件的规划员并非恶人,她只是人手不足。上诉你项目的邻居也不是卡通式的 NIMBY,他只有一套房子,那是他全部的净资产,而游戏给了他一根杠杆,于是他就拉了下去。正如我们在关于防御式工程的文章中所论证的,系统得到的是激励所允许的行为,而不是设计者所期望的行为。
涌现还让这款游戏对辩论的另一方也具有可读性。一位 YIMBY 玩家在游戏里会切身体会到,为什么流程改革比任何单一项目都重要。一位文物保护主义者玩了之后会明白,否决点并不会有选择地挡下糟糕的项目,它们挡下的是所有时间线足够长的东西,这是毫无区分度的。这一点在评论文章里很难讲清楚,但在一局游戏里,你会亲眼看着自己的持有成本在第四十个回合慢慢流干。
拖延是否决点最可靠的杀伤机制。你很少能直接击败一个项目,而是让它一直等,直到它自己死掉。
严肃游戏与讽刺作品:各自何时更有优势
这个类型真正逼着我们去比较的,并不是沙盒与对抗,而是讽刺与严肃建模。这款 NIMBY 游戏是讽刺作品:它的参数是为喜剧和绝望调校的,而不是按照真实的审批时间线校准的。一个严肃版本,就是某位市议员曾经说过想拿来当作培训工具的那种,会根据真实许可数据来校准关卡吞吐量、上诉概率和持有成本。一些规划部门和研究人员确实会为此目的运行参与式模拟和严肃游戏,只不过通常做得很简陋,像是用 PowerPoint 做出来的效果。
当目标是引起关注、培养直觉时,讽刺作品更占优势。没人会在社交网络上转发一个经过校准的规划模型;而一款让旧金山用流程把你埋起来的浏览器游戏之所以能被广泛分享,正是因为夸张本身承载了论点。讽刺作品对正确性的要求也很低,它表达的是方向,而不是量级。但当问题变成“我们应该改什么?”时,讽刺就不够用了,你需要那个枯燥的版本:可参数化、可切换的规则。在模型里拿掉自由裁量审查,看看吞吐量怎么变;把规划人员翻倍,看看积压怎么消化。这种切换与观察的循环,正是游戏从评论变成政策工具的地方。这个类型最理想的形态,应该同时提供两种模式,让玩家在两者之间切换:先感受绝望,再去修好这台机器。
为什么游戏比评论文章更能说服人
对于任何构建解释性系统的人,这里还有一个更广泛的道理。一篇评论文章是在断言某个机制,而一个可以玩的模型是在演示这个机制,并允许用户去证伪它。如果你对住房政治的心智模型是“有人应该多盖点房子”,那么花三十分钟玩一个对抗型模拟,就会比看一堆“每年获批住房数”的图表更有效地重塑你的认知。这与从零实现一个 shell 比读 man 手册更能让你理解 Unix的道理相同:哪怕只是操作一个玩具系统,也会迫使抽象变得具体。这款游戏在 Hacker News 上的评论很能说明问题,人们立刻开始提议为自己的城市做类似版本,有人想做高铁项目,要处理强制性的野生动物缓解措施,也有人想做数据中心。这种模式之所以能推广,是因为否决点的架构本身就是通用的。只要存在顺序的审批关卡、不对称的动机和作为成本的延迟,这款游戏就有用武之地。
我还要再进一步:对抗型模拟在工程沟通领域是一个没被充分利用的类型。想象一下,让新工程师通过玩游戏来熟悉你们组织的变更管理流程。部署一次变更,看着它排在 CAB 评审、安全签收和冻结发布窗口后面排队;感受自己的热情一点点转化为对“人们为什么会去用影子 IT”的理解。如果这听起来很耳熟,那正是我们那篇“每一层代码审查都会让团队变慢”的论点背后的同一种直觉:在有人真正需要把东西推过这些关卡之前,这种摩擦是看不见的。
我的建议
所以:该选沙盒模拟还是对抗型模拟?两个都玩,但如果你要做点什么,就做对抗型的那个。沙盒类型已经很成熟,商业作品很多,它的教训(密度、网络、外部性)也早已融入大众文化。对抗型类型才是尚未开垦的设计空间,也是真正具有解释价值的地方。如果你是一名开发者,正在找一个有挑战性的副业项目,那就对你非常熟悉的某件事的流程层做建模:你所在城市的许可流水线、你公司的采购关卡、签证制度。用队列、带滞回的阈值和持有成本;让延迟成为反派;让结果自然涌现,而不是脚本化。让数值保持可调,这样持怀疑态度的人也能检验他们自己的假设。你从构建它的玩具版本中学到的关于系统的东西,会比多年争论中学到的更多,而每个玩你版本的人也会如此。这就是这款小游戏真正的巧妙之处:它把一场通常只会制造热量的辩论,变成了一台你可以拨弄的机器。我们的更多论点,也值得被做成这样的机器。


