跳转到主要内容

物理

虚拟世界的基础是它的地理与人口,两者好比棋盘与棋子。设计者每当着手做一个新的虚拟世界,最先考虑的若干事项里总有地理,也有生态/经济。

在《MUD1》里,罗伊·特鲁布肖(Roy Trubshaw)就是从物理开始的。

今天的设计者从前人那里继承了太多东西,以至于常常不去想事情为什么会是现在这个样子。不去想,就没有理解;没有理解,就无从创新。虚拟世界里有那么多特性都依赖它的物理——地理与人口也在其中——被当作理所当然的东西之多,令人吃惊。

物理关心的是变化的基本系统;它是虚拟世界的机械装置。我在第 1 章给出的虚拟世界定义里,它被列为第一条,这并非偶然。它以隐含的方式界定了虚拟世界一切实实在在的可能;凡物理不允许的,就不可能存在。

设计者确实应当对自己虚拟世界的物理了如指掌:知道采用了哪些约定,知道为什么要采用它们,也知道它们意味着什么。有了这些认识,他们就应当想方设法改进这些约定,让自己虚拟世界及其玩家都能从中受益。如果你确实随了大流,那也只应是因为大流的方向正是你想去的方向。

自然法则

虚拟世界的物理建立在真实世界的物理之上。这自有道理。

我推一扇门,门就开了。我推一扇虚拟的门,那扇虚拟的门就开了。我同样可以轻松地规定成:我推一扇虚拟的门,就会有虚拟的鸟从一只虚拟的杯子里飞出来。除非那扇门被标记为“不是普通的门”(No Ordinary Door)、那只杯子被标记为“不是普通的杯子”(No Ordinary Mug),否则这会把人搞糊涂。为什么?因为人从小就学会了支配现实如何运作的那些因果规则。在虚拟世界里,除非刻意为之,否则他们无法阻止自己去套用这同一套规则。因此对虚拟世界来说,任何干扰这套规则的东西都会构成一次情境之外的打断;任何遵循这套规则的东西,都在默默支撑着“虚拟即真实”这一错觉。

真实世界遵从物理定律运行。人们为了模拟物理定律而在头脑中建立起来的那些规则 1 要简单一些,但对于几乎所有实际用途来说都够用了。因此,想让玩家信服的虚拟世界,至少必须实现这些规则(而且,说来矛盾,也许不必实现更多;我们在这里要说服的是玩家,不是现实)。

所以从根本上说,虚拟世界的物理所关心的,就是把那些显而易见的东西实现出来。

关键在于透明。透明意味着玩家不必刻意搁置怀疑,因为他们的感官让这些信息径直通过,不作任何评论。设计者在营造透明上越成功,他或她的工作就越不为人所注意:这对沉浸来说是好事,对设计者的自尊心来说就不那么好了。

玩家对虚拟世界物理的预期,只要情境合适,并不一定要直接对应现实。最显眼的例子,是一个自有一套物理学的类型:卡通。在卡通里,你跑出悬崖边缘之后并不会掉下去,直到你意识到自己跑出了悬崖边缘。自然法则仍然适用,只是方式不同 2。只要人们接受了这套虚构设定,它就能成立。《卡通城》可以像《无尽的任务》一样有沉浸感。

虚拟物理的核心问题,是它运行在什么样的细节层次上。

我松手放开一个物体,它就会往下掉。这就是重力在起作用。它撞到地面时,会弹起来吗?会受损,也许会摔坏吗?也许是地面坏掉?如果地面是斜的呢?物体会顺着它滚下去吗?这取决于物体的形状、它的质量、它由什么材料做成、地面由什么材料做成,等等。如果有风,又会产生什么影响?

如果我丢下的物体和地面之间还隔着另一个物体,又会怎样?它会把物体接住,还是让它穿过去;物体是会被弹开,还是从里面弹出来?我可以把苹果丢进柳条筐里,但在装满之前能装下多少个?就算筐满了,装不下苹果了,我还可以往里加沙子。然后我还可以加水,水会在里面留上一小会儿,但最终会渗漏出去。也许,如果我在沙子里再加上水泥粉,它反倒会凝结起来。

这还只是开头。虚拟世界的物理必须处理各种各样的问题,而这些问题在真实世界里是不费吹灰之力就实现的。一根羽毛从窗口掉下去,要多久才落地?我的指南针为什么指向北方?我拿手电筒照镜子,会发生什么?冰能保持多久?我朝一群人泼一桶水,谁会淋湿?我能把书架拆开,拿这些部件做一只木筏吗?如果我放火烧一栋木房子,会怎样?

真实世界能回答所有这些问题,因为它就是这么运作的。它有分子、原子、原子粒子、夸克,还有天知道什么别的东西,全都在至少四种力 3 的作用下协同工作。虚拟世界别指望能跟真实世界的物理一较高下。遗憾的是,正如上面的例子所示,虚拟世界目前也还应付不了朴素物理学(naïve physics)。

话虽如此,如今的虚拟世界可以调用的计算资源比过去更多,因此推测它们可以拥有更好的物理,也不算离谱。在建模工具已经能做实时光线追踪、流体力学、布料变形和表面摩擦效果的今天,虚拟世界却很少费心去实现“把这个东西丢进水里,它会沉下去”这样简单的概念,这有点令人伤感。

能做到的事情有实际的限度。随着细节增加,活动组件的数量会增加,组件之间的交互数量则呈指数增长 4。往这个问题上再堆多少台计算机,也不会有丝毫改善。话虽如此,如果《MUD2》能让你从井口把一个物体丢下去,落进一条地下暗河,河水把它冲走,直到它撞上一个也许会、也许不会把它拦住的格栅——而这全程还要计算物体的密度、撞击损伤、水浸损伤,以及撞到别人或被别人抓住的可能性——那么一个大规模的图形化虚拟世界没有理由做不到更好。诀窍不在于实现全部物理,甚至也不在于实现全部朴素物理学,而在于实现刚好够用的朴素物理学,以满足玩家对细节的感觉。

这仍然比听起来要难。

虚拟世界是在命令这一层上运作的。玩家在决定自己想做什么时,用的是一组组实际上不可再分的操作,这些操作就构成了命令集。他们想穿上一双靴子,可不想(对每只靴子都)先松开鞋带、把脚套进去、拉紧鞋带,然后再打一个双结。在现实生活中大多数人想都不用想就能做到的简单目标,在虚拟世界里也应当照此实现。信不信由你,为《MUD1》做设计时,罗伊和我确实讨论过这些问题,然后才决定把动作切在哪个粒度上。这就是我们选择 “unlock door”(开锁)、而不是 “put key in door; turn key; remove key from door”(把钥匙插进门;转动钥匙;从门上拔出钥匙)的原因。这也是我们把 “lock”(锁)和 “door”(门)做成同义名词的原因。

要实现物理,你其实只需要比最深的命令再往下一个概念层级。比这更深的东西,玩家反正也看不见。如果一个角色能射出一支箭,虚拟世界引擎就应当能呈现箭的飞行,并让它的到达不是瞬间完成的;不过,这不必靠把牛顿定律套用到抛物线轨迹上来实现——它只需要看起来像是那样做的就行。

有一种观点认为:如果更深的物理模型比更浅的模型复杂度更低,或者可以拿它构建出若干个复杂的浅层模型,那就可以采用更深的模型 5。比如说,如果你为了实现虚拟网球游戏,已经建好了一个不错的牛顿力学模拟器,那不妨把它也复用到射箭上。这很合理——前提是你确实需要那个模拟器来做网球。在实践中,程序员比设计者更容易往深处走得太远:你也许只是规定了角色的呼吸在寒冷的空气中应当可见,但要花上 10 天去实现一个绝妙的涡流计算新例程的人,并不是你。

那么,总结一下:

  • 玩家头脑里已经“编译”进了一套对真实世界如何运作的感觉。

  • 虚拟世界如果模仿这一点,对沉浸有极大的帮助。

  • 玩家很少需要想到“直接就能做”以外的层次。

  • 命令就应当写在这一层次上。

  • 物理通常只需要构建在这一层次再往下的那一层。

  • 问题在于:很多时候,物理根本没写到这下一层附近,甚至压根就没写。

既然如此,设计者可选的应对方式并不多。按从最糟到最好的顺序,分别是:

  • 硬扛。虚拟世界里有池塘;玩家可以在池塘的水面上行走;有什么大不了的。

  • 条件反射式的应对。玩家没法走进池塘,却没有任何情境之内的理由。

  • 消除症状。玩家没法走进池塘,因为池塘里住着的凶恶鱼群会拦住他们。这给出了一个情境之内的理由,但它总是很牵强。

  • 掩盖裂痕。这个虚拟世界里根本没有池塘。

  • 实现物理。走进池塘的角色可以站在水里,水漫过膝盖,并如预期那样浸湿衣服。

玩家的命令蕴含着虚拟世界的物理。因此,设计者在决定要实现哪一层次的物理时,应当去看命令。


  1. 这些规则被称为朴素物理学(naïve physics),是定性推理(qualitative reasoning)的一个例子。帕特里克·J·海斯(Patrick J. Hayes),《朴素物理学宣言》(The Naïve Physics Manifesto)。唐纳德·米基(Donald Michie)编,《微电子时代的专家系统》(Expert Systems in the Micro-Electronic Age)。爱丁堡,爱丁堡大学出版社,1978。约翰·德·克莱尔(Johan de Kleer),《经典力学中的定性与定量推理》(Qualitative and Quantitative Reasoning in Classical Mechanics)。帕特里克·H·温斯顿(Patrick H. Winston)与理查德·H·布朗(Richard H. Brown)编,《人工智能:MIT 的视角》(Artificial Intelligence: an MIT Perspective)。马萨诸塞州剑桥,MIT 出版社,1978。 ↩︎

  2. 见《卡通物理学定律》(Cartoon Laws of Physics),它有好几个版本。http://funnies.paco.to/cartoon.html 与 http://www.bbc.co.uk/dna/h2g2/alabaster/A645095。 ↩︎

  3. 引力、电磁力、强核力、弱核力。也许还有别的力尚未被发现。 ↩︎

  4. 潜在 exploit 的数量也是如此。 ↩︎

  5. 虚拟世界的物理本身就可以看作实现更高层效果的一个模型。一致性从中受益:如果你能让物理去处理某个既定的桥段,通常比你为它单独硬编码要好。 ↩︎

六大类

令人意外的是,虚拟世界的命令只有六个类别,其中只有一半是情境之内的。把这些实现出来,你就具备了搭建一个基本虚拟世界所需的材料。这六大类是:

  • 退出虚拟世界(“quit”)。

  • 获取游戏说明(“help”)。

  • 记一条备忘(“bug”)1。

  • 通信(“tell”“say”“shout”“pose”,等等)。

  • 创建/销毁物体(“chop wood”)。

  • 状态变化(移动、“get”“drop”,以及其他所有命令)。

在这六大类里,从虚拟世界物理的角度看,最后一类最重要。

虚拟世界里的有形物体都有属性,属性又各有取值。属性可以有多种形式:“Mass”(质量)可能是一个整数;“label”(标签)可能是一个字符串;“location”(位置)可能是一组坐标;“contents”(内容物)可能是一个物体列表;“components”(组件)可能是一种树状数据结构。这些取值中,有些可以独立存在;另一些则可能因为取决于许多因素(例如对魔法的抗性),而要在每次使用时重新计算。

状态变化类命令会改动属性。比如说,一个简单的 “get”(拿),意味着把一个物体的位置从地板上改到角色身上;移动意味着把角色的位置属性从一个点改到另一个点;“open door”(开门)意味着把门的“opened”(已打开)属性改成 true。

当然,在实践中这要更复杂。有各种各样的前提条件需要满足(物体可能太重搬不起来,可能被固定住了,可能着了火,可能正被踩在脚下,还有一大堆别的烦人情况);需要生成反馈(你看见门开了,门另一侧的人也一样);属性本身也可以有不同的表示形式(位置可以表示为坐标,也可以表示为「包含/被包含」的层级)。不过,从设计者的角度看,实际的机制并不特别重要;更值得关心的是拿它们能做出什么。这是因为,除了物体的创建/销毁之外,一切有形的东西都可以用它们来做。

这意味着,你选择的属性决定了玩家命令的粒度,而命令的粒度又决定了物理的粒度。如果属性是细粒度的(比如说,如果你记录了一丛灌木上开着多少朵玫瑰,属性就可能是细粒度的),那么改动这些属性的命令也必须是细粒度的——因此,命令底下的物理还必须再细一点(因为正是它赋予了属性以意义)。人们是频繁使用这些命令还是很少使用,并没有什么区别;一旦你有了那样的细节层次,就必须支撑它。

同样,反其道而行,采用粗粒度的属性,你就会得到粗粒度的命令。如果花是花园的属性,而不是自身独立成物的物体,角色能拿它们做的事情就少得多(这意味着你的物理要处理的事情更少)。

至于该采用哪一档细节层次,这既取决于虚拟世界,也取决于真实世界。说取决于虚拟世界,是因为有些情境需要更细粒度的属性,而另一些情境没有它们也行。举例来说,一款谋杀悬疑侦探游戏需要为每个物体设定许多细致的属性,因为一丝不苟正是侦破的特征;而一款太空歌剧游戏则可以含糊带过大部分这类属性,因为它关心的是更宏大的尺度。不过,在所有情况下,真实的物理都是绝对的。玩家会有某些预期,并且会照着这些预期去行动。如果你鼓励他们往深处看,他们可能看得比你能应付的还要深;如果你只鼓励他们看表面,那又可能太表面,满足不了他们天生的好奇心。

在这里,设计者真正能做的,就是把自己放到玩家的位置上。先想象这个虚拟世界完成之后会是什么样子,再考虑玩家会想在里面做什么。按这一层次创建物体,按这一层次为物体设定属性,按这一层次规定命令。由此,你就能得出你的物理层次。

稍后我会更详细地讨论物体的属性 2。不过眼下,我们先接着看底下这套基本的物理系统,并问一个问题:如果你想模拟某种在真实世界里不可能的东西,会发生什么?


  1. 如果你愿意,可以把它(记备忘这一条)归到通信那一类,但我认为它比通信更基本。 ↩︎

  2. 为了不让你空欢喜一场,我先把话说在前头:我不会给出一份常见物体属性的清单。这一节的目的,毕竟是让设计者自己从基本原理出发去思考虚拟世界的物理。 ↩︎

超越真实世界的物理

现实能应付的细节比虚拟世界所能应付的要多,因为它的资源更多。不过,有两种情况会让虚拟世界物理的范围超出真实世界所能提供的范围。

其中第一种是:虚拟世界会与一个元世界(meta-world,也就是现实)发生物理上的互动,而现实不会 1。现实世界里的玩家可以成为虚拟世界中的 persona,因此虚拟世界能通过它的玩家影响真实世界(反过来,真实世界也能通过玩家影响虚拟世界)。最能说明这种双向互动的,是与通信有关的命令。它们有四种类型:

  • 在世界之内,在虚构之内。基于真实世界物理的命令,在虚拟世界的情境之内实现。例子:“shout”“say”“whisper”“pose”/“act”/“emote”。

  • 在世界之内,在虚构之外。虚拟世界里的命令具有真实世界里不可能实现的功能。例子:“tell”“mail”、群组频道。

  • 在世界之外,在虚构之内。与虚拟世界里发生的事情有关的材料,在真实世界里制作出来,再以情境之内的方式呈现。例子:报纸、报信人。

  • 在世界之外,在虚构之外。与虚拟世界中的事件有关的材料,在虚拟世界之外呈现。例子:IRC、电子邮件、吐槽网站。

虚拟物理能够超出真实物理的第二种情况,出现在超物理学(ultraphysics)这个领域。它涉及的是人们愿意当作日常物理之延伸来接受的那些东西,无论这些设定实际上是否与日常物理相容。例子包括超光速旅行、灵能(psychic powers)、赛博技术(cybertechnology)、祈祷、时间旅行,以及(人人都爱的)魔法。这些现象里,没有一个在今天得到了可靠的验证,其中一些恐怕永远也做不到。不过,有足够多的玩家了解这些套路,因此把这类想法容纳进虚拟世界是可行的。有时有必要造出一套设定,来说明这个虚拟世界采用的是几种子套路中的哪一种;这里的魔法是靠 mana(法力)、法术记忆、手势编程,还是别的什么起作用的,这本身就取决于出于玩法理由做出的决定。不过,只要它合乎玩家的朴素超物理学(naïve ultraphysics),玩家就能接受。

任何超物理学都需要以与常规物理同样的严谨来实现。玩家会面不改色地告诉你:喷漩涡的龙不现实,喷火的龙则不然。正如你的虚拟物理必须遵从玩家的朴素物理学(naïve physics)一样,你的虚拟超物理学也必须遵从玩家的朴素超物理学。超物理学对沉浸的支撑不如真实物理,但超物理学一旦出了岔子,对沉浸的破坏跟真实物理出岔子时一样严重。

超物理学实现在哪一层次,取决于使用它的那些命令(作为法术、通过技能、借助器物),而这些命令又取决于与真实物理同类的属性。这里有很大的实验余地。别的虚拟世界都用一次性的大威力法术来实现魔法,但这并不意味着你也必须如此。法师为什么不能像弓箭手射箭那样频繁地施法?法术为什么不能有持续、流动的效果,让你把治疗流导向任何需要它的人?魔法为什么不能需要时间才能生效,从而逼你猜一猜当它终于奏效时谁会用得上?可以改动的维度很多,而所有这些改动都能被纳入玩家对传递它的那套超物理学的模糊设想之中。你施一个法术,出现一个火球;你是怎么施法、火球又是怎么出现的,由虚拟世界说了算——玩家不在乎,只要他们拿到火球就行。

超物理学有一个尴尬的后果:它跟那些建立在真实物理之上的游戏类型合不来。奇幻小说也许可以无视飞马对城堡建造的影响,但它们不必应付一支飞行骑兵部队把兵力投送到城墙之后、造成一片混乱。玩家角色也许可以利用神庙里便宜的治疗与祛病设施,但如果 NPC 也这么做,那这个世界就会大不一样。

关于超物理学,最后要提的一点是它容许超维度(hyperdimensionality)。图形世界处理它的能力不如文字世界,因为图形世界必须呈现出一个在真实世界里渲染出来的虚拟世界视图。文字世界可以拥有装在自己内部的物体、里面比外面大的物体、可以捡起来的声音,等等。图形世界可以实现某些文字世界历来觉得困难的超维度(比如随身洞),但总体上说,它们没有文字世界那么灵活。


  1. 按定义,任何与现实发生物理互动的东西都是现实的一部分。神学家和哲学家也许会主张,现实之外还存在一些世界,它们能与现实重合,但那与虚拟世界同真实世界的关系并不相同:我们可以证明,虚拟世界是现实的一部分。 ↩︎

物体

虚拟世界里处理物体的准则是:把一切都整合起来。

实现一个虚拟世界时,构成它的那些实体就是它的对象。这些实体之间的关系就是它们的属性。对象与属性合在一起,构成了虚拟世界中可触摸的部分,而物理赋予这部分以生命。事情并不非得如此——理论上你可以设计出这样一种系统:对象只是基本方程之间相互作用的产物,就像数字那样。你要是打算那么做,祝你好运。

设计者必须认识到:虽然他们的虚拟世界里许多对象与另一些对象在特性上千差万别,但从根本上说它们是同一回事。它们可以被归入一些在概念上有用的分组——玩家角色、活动生物、容器、房间、可携带物体、固定景物,等等——但把这些分组当成互不相干、彼此隔绝的集合,是一个大错。如果你把它们看作一个通用抽象对象的特化,而不是各自抽象层级的根,你会得到好得多的一致性(也对自己这个世界理解得好得多)。

举例来说,假设你决定让自己的玩家角色拥有一个 “health”(生命值)属性。那么用这同一个属性来记录活动生物的生命值,就是很自然的一步。你也许还想给普通物体一个 “wear”(磨损)评分,用来追踪它们离散架还有多远。那么你就应当想到,“wear” 衡量的东西和 “health” 是同一类,因此你该用 “health” 而不是 “wear” 1。

这也许显得相当显而易见,但很多时候它偏偏不是 2。早期,MUD 设计者同时也都是程序员。直到他们接触了面向对象编程语言的思想之后,其中一些人才愿意承认:嘿,也许房间和玩家角色说到底就只是对象而已?这有点讽刺,因为事实证明,虚拟世界的对象与 C++ 这类面向对象编程语言里的对象对应得并不好。要解释为什么,我得先岔开一段(不过我会尽量说得短些)。

在面向对象编程语言里,有一个对象类的层级。单个对象是某个类的实例。因此,你可以说达布隆是一种硬币,硬币属于财宝这一类,财宝是一种可携带物体,可携带物体是一种(根)对象。虽然我在这里用了 “object” 这个词,但在编程的意义上,这些应当叫类。Doubloon33 可能是 “doubloon” 这个类的一个实例,那样它才是一个对象。面向对象编程的威力在于它能消除重复:我不必去定义 “get doubloon1”、“get doubloon2” 等等,只需要定义 “get doubloon”。

如果对象可以是多个类的实例,或者类可以是多个超类的子类,你拥有的就是多重继承系统。否则就是单继承系统。对虚拟世界设计来说,多重继承系统极为便利。如果一个房间里有达布隆、一便士和一只明代花瓶,那么当我发出 “get coin” 命令时,我想要的是把达布隆和便士捡起来;如果我试着发 “get antique”,我想要的是达布隆和那只花瓶。达布隆既是硬币又是古董,但并不是所有硬币都是古董,也不是所有古董都是硬币。这种情况很常见:并非所有哺乳动物都是食肉动物,也并非所有食肉动物都是哺乳动物;并非所有流行歌手都是男性,也并非所有男性都是流行歌手。方块皇后主要是一张方块,还是主要是一位皇后?

遗憾的是,程序员很可能想用 C++ 或它的某个衍生品(例如 Java),而这些语言只支持单继承{勘误:C++ 其实确实有某种形式的多重继承,用的(说来有点讽刺)是 virtual 关键字。}。他们看到虚拟世界里有 “对象”,就把它们对应到自己那套面向对象系统里的 “对象” 上,然后在编码进行到 95% 的时候撞上麻烦。在单继承系统里伪造多重继承是可能的,正如在扁平系统里伪造单继承也是可能的。这要花很多工夫,里面还有大量重复;不过仍然办得到。

办不到的是命令的继承。面向对象编程会把一段段代码(称为方法)关联到对象类上。这些方法本身不是对象;它们不存在于继承树里。换句话说,我不能说 “punch” 方法是 “hit” 方法的子类。如果我想要 30 种不同的打东西方式,就必须把它们一一实现。如果我想让效果随被打对象的软硬而不同,每一种都得把这套逻辑重写一遍。对大型或复杂的虚拟世界来说,这很快就会变得令人抓狂地枯燥,无论实现还是维护都是如此。面向对象编程的目的是消除无谓的重复,不是制造重复。

出现这种局面,是因为虚拟世界的 “对象” 对编程语言里的 “对象” 来说是个糟糕的选择。应当把命令当作对象才对。如果把 “hit object” 和 “hit soft_object” 定义成(面向对象的)类,那么像 “slap cushion” 这样的命令就是某个命令类(在这里就是后一个)的实例,据此就能找到并运行对应的代码。这本质上是个编程问题,而不是设计问题,但由于虚拟世界的历史包袱,它已经进入了设计范式。设计者往往按对象和方法来思考,而他们本该思考的是多重继承的层级和命令。

好,题外话到此为止。

所以,虚拟世界里的对象类通常会被组织成某种层级。这样可以共享属性,共享属性会促成整合,整合又带来一致性。那种因为 “hit” 这个名字已经被 “hit creature” 占用、只能改用 “ring bell” 的日子已经过去了 3。

如果去问,大多数设计者大概都会赞成整合是好事这个想法。可惜的是,他们往往并不怎么考虑这件事。比如说,法术与技能有很多共同之处——它们都是把某项专门任务做到某一水准的能力,而这种能力是必须学来的。但很少有虚拟世界认为这两者有任何关联。同样,器物也能以效果或附魔的形式,拥有玩家角色靠技能或法术拥有的那种东西。如果我能学会施放闪电箭法术,那为什么不能教会一根魔法法杖也这么做?这种思路已经在单人角色扮演游戏里用过,例如拉瑞安工作室(Larian Studios)的《神界》(Divine Divinity),但在虚拟世界里并不常见。

关于物体的这一大段讨论,虽然大多讲的都是文字世界,但它同样适用于图形世界。

图形世界在功能上一般远不如文字世界丰富,但差距正在缩小;迟早有一天,用单继承来组织虚拟对象类会成为一个问题。没有多重继承、也没有对动作进行量化的能力,你能走完 95% 的路程,但到了那最后的 5%,这两样东西就会变得很重要。


  1. 只是要确保不会有人跑去铁匠铺治伤,或者找治疗师给剑重新开刃。 ↩︎

  2. 至今还有很多虚拟世界认为,把物体丢在地上与把物体放进背包是完全不同的两种动作。 ↩︎

  3. 你注意到那处讽刺了吧? ↩︎

物体的常见问题

既然虚拟物体总体上是要在物理层面表现出与真实世界一致的行为,那么可以想见:每当考虑现实的某一个侧面时,总会有一些反复出现的常见问题。事实正是如此:现实的某些侧面很容易做出来,另一些则根本不可能做出来。这些问题之所以出现,有许多是因为人类心目中的“物体”其实只是一个概念上的实体。这个概念实体在朴素物理学里行得通,但朴素物理学并不非得要把它实现出来。

有一些惯例能解决其中一部分问题,但一如既往,设计者最好去理解某个惯例为什么存在,而不只是接受它就这么存在着。谁知道呢,如果你理解了这些问题,说不定就能给出更好的解决方案。

那我们就来看看这些问题吧。

固体:组合体

组合体是由其他物体构成的物体。铁钥匙有磁性吗?有。那斧头呢?嗯,头部那一块有。那一条牛仔裤呢?不太算,除非你把拉链和铆钉也算进去(前提是它们用钢做,而不是用铜做)。

大多数时候,人们把物体当作单一的物品来想,但只要有必要,他们也很乐意把它们看成由其他物体构成的。在虚拟世界里,这就成了个麻烦。如果物体是由其他物体做成的,那些物体也必定是由别的物体做成的,如此一路下去,直到某一点上你不得不就此打住为止。这个点在哪里?反过来说,如果物体不是由其他物体做成的,你又怎么指称一个物体的组成部分?门既然有钥匙,就必然有钥匙孔,对吧?

按惯例,虚拟世界没有组合体。你不能把物体拆成零件。如果你需要指称某个物体的一部分,指称这一部分,就等同于指称作为整体的那个物体。当我能透过门上的钥匙孔看时,就等于我在透过门看。

组合体之所以不存在,原因很简单:支撑这套功能的物理还不够格。属性挂在物体上,不挂在物体的配置上;如果你把属性挂到物体的配置上,那些配置本身就等于成了物体。

举例来说,假设在现实生活中我有一架木梯子。我能爬上梯子。我爬不上木琴。不过,我可以把梯子拆开,用那些部件做一架木琴。我能在木琴上演奏音乐,在梯子上却不能。木琴这个组合体与梯子那个组合体所用的物体相同,但两者有着截然不同的属性。

要给这个问题硬凑一个解决方案是可能的。你可以规定 “dismantle ladder” 或 “dismantle xylophone” 会销毁原来的物体、创建出两个新物体:“poles”(杆)和 “nails”(钉)。然后你可以允许 “make ladder from poles and nails” 和 “make xylophone from poles and nails”。遗憾的是,除非你事先已经想到了这一步,否则那个试着 “make fence from poles and nails” 的玩家会失望。

在真实世界里,物体之所以是物体,只是因为有人这么说。它不过是用来描述现实之中某些显现的一种语义手法。事实上,物体甚至不必是真实的:“如果我有个妹妹,她叫莫伊拉”;“没有人跟着我”。人们日常就会指称并不存在的物体,而且不只是以反事实或未实例化变量的形式。不管你对宗教怎么看,你都得承认宙斯、耶和华和毗湿奴是彼此不相容的存在,但对某些人来说,它们跟石头一样真实(至少对宙斯来说,曾经如此)。

用虚拟世界的眼光看,所有物体都跟石头一样真实(或者至少跟虚拟的石头一样虚拟)。它们存在,因为玩家就是这样理解自己的环境的。然而,真实世界里的人在灵感来时可以召唤出新的物体,在虚拟世界里这一点做不到。物体只能拥有被赋予的那些属性;组合体不能凭自身的构造就凭空获得任意的涌现属性。你不能发明物体,只能给已有的物体发明新用法。

虚拟世界之所以没有组合体,是因为那只是把问题推远了一层。到了某个阶段,你总得停下。既然反正都得停下,又何必开始?玩家会试着拆解物体,失败,沉浸感受损,然后放弃尝试。如果组合体的先例已经立下,他们就会一直试下去,因为有时行得通、有时行不通。每一次失败都会打击他们对现实模拟的信任。

不过,沿用我先前在 NPC 上用过的那套推理(也就是说,哪怕只是最粗浅的 AI,也比没有强),可以主张:任何在深度上前后一致地实现出来的组合体,都比完全没有要好。一把斧子由一根柄和一个斧头组成;一个斧头由六磅铁组成;六磅铁由两块三磅重的铁熔在一起组成,如此等等。只要把所有物体都定义为由其他物体和数量有限的可识别资源“原子”构成(这些原子又能分解成自身越来越小的版本),组合体就可以实现。这虽然不是一套完美的系统(每一种物体都需要一份“配方”,所以除非事先有了配方,新物体就造不出来),但比起完全没有组合体,这无疑是进步:它能容许更多的玩法,能提供的沉浸感也更好。

尽管如此,那些想用帆布和破桶造出一架滑翔机的玩家,多半是在浪费时间。

固体:集合

有些物体是其他物体的集合或汇集。你可能有一束花、一副牌,或者一沓钞票。按照不拆解的原则,它们都应当被当作单一的物品。不过,这三者照此处理都有问题。

只要世界上任何地方都没有单枝的花,一束花就没问题。可是放进一朵玫瑰,你就等于承认了“没成束的花”这个概念。于是玩家就想从花束里把花拿出来。

一副牌只在没人拿它玩牌时才存在。既然牌本来就是用来玩的,人们想把整副牌发出去,你很难怪他们。可一旦发牌,突然就出现了 52 张单独的牌(外加大小王),而那一副牌没有了。只有等有人把所有牌收齐,你才会重新得到一副牌。

一沓钞票的价值事关重大。你也许愿意允许玩家在海滩上随意捡卵石,但不能让他们那样从一沓钞票里一张张往外抽,否则他们转眼就富了。可是,如果你把一沓里的每一张钞票都做成单独的物体,你又怎么指称那一沓?你能把它一分为二,得到两沓吗?

这些问题之所以出现,是因为玩家很多时候会在某个层次上考虑物体,但碰上相似的物体(尤其是这类物体),他们喜欢把它们堆在一起,当作一个抽象的整体来对待。设计者必须决定要不要容许这种没有实际功能的组合体,如果要,又该如何处理它们。

办法有两种,前几段已经暗示过了。第一种是:把构成一个集合的所有物体都一一枚举出来,但根据持有的数量把它们作为一个集合来呈现。如果你的物品栏里有三张扑克牌,它们就分开显示;如果你有七张,它们就显示为“一手牌”;如果你有 52 张(外加大小王),它们就显示为“一副”。同样,如果你有一朵玫瑰和一朵郁金香,你就是有一朵玫瑰和一朵郁金香;如果你有一朵玫瑰、一朵郁金香和一朵水仙,你就是有了“一束花”。个体何时成为(或不再成为)一个集合,这一标准由设计者定下。

第二种办法是使用生成器。花园里的花、树上的坚果、蝗群里的蝗虫实在太多,把它们一一枚举毫无意义。玩家想要一个,系统就给他一个。数量实际上是无限的。对于这类集合,一个分发函数(dispenser function)会在每次从集合中取出东西时创建一个新实例;当一个实例被归还(或者两个集合合并)时,送进来的物品会被删除,集合则保持原样 1。如果一个图形世界用卵石贴图铺出一片海滩,角色就可以用这种方式把卵石捡起来。贴图不会改变,但角色得到了一个他此前没有的物体。

集合被用作一定数量物体的简写。可以(但并非必须)给它们一些单个物体所没有的属性——比如让一整套泡泡糖收藏卡的价值,远大于其中每张卡片价值的总和。哦,对了,世上所有其他设计者都想到过:把太多铀片凑成一个集合,就会引发一场原子爆炸。


  1. 注意,程序员在这里走错一步,就会碰上复制物品(duping)之类的 bug,而这类 bug 是许多虚拟世界的祸根。 ↩︎

固体:容器

虚拟世界里的物体可以处在各种层级之中。主要的一种是类层级(X 是 Y 的一种),但其他可能还包括组合体层级(X 是 Y 的组成部分)、空间层级(X 在 Y 上面)和容器层级(X 被 Y 容纳)。后两者是相关的,我们马上就会看到。

容器层级很有用,因为它们给了玩家一种物理手段,让他们能在虚拟世界里成批搬运物体。它们并不是必需的:早期计算机操作系统没有子目录或文件夹这类东西,同样,一些早期的虚拟世界(最著名的是《Shades》)也没有容器。不过,它们非常有用。在采用节点式实现的虚拟世界里,这一步其实早就做到了:房间可以容纳角色,角色可以携带(也就是“容纳”)物体,因此,再让物体也能容纳其他物体,并不是多么了不起的想象飞跃。

使用坐标系统处理位置的虚拟世界,通常必须改用节点式系统来处理容装关系。虽然也可以扩展坐标式的做法,让物体能被装在背包、口袋、腰带之类的地方随身携带,但在实践中这对玩家太不方便了。对程序员来说同样不是乐事:他们得把任意物体锁死在角色的坐标系上,好让角色走到哪里、物体就跟到哪里。因此,大多数图形化虚拟世界会为容装关系单独维护一份物品栏,只把坐标系统用在顶层(顶层更容易用图形方式显示)。

图形世界在呈现物体之间的空间关系上没有困难。你能看见瓶子在桌上、椅子在桌边、靴子在桌下,等等。这要归功于坐标系统强加的那种刚性的空间结构。节点式系统没有这种底层结构:如果两个物体都在一个房间里,这丝毫说明不了两者之间的空间关系。就连两个相邻房间之间的连接关系也不是隐含的,必须明确写出来。有些节点式虚拟世界——例如 Skotos 开发的那些——确实在物体之间有一套关系网络。不过,没有绝对坐标就很难做推断:如果 X 挨着 Y、Y 挨着 Z,那么 X 挨着 Z 吗?当然,在对容器的内容物建模时,坐标系统也有同样的问题。幸运的是,大多数玩家不关心“X 在包里”以外的事——他们并不真的在意到底在包里的哪个位置,只要它不会到处移动、想拿的时候拿得到就行。

容器能装的东西通常是有限的。它们只能容纳一定体积(或数量)的物体。有时只有尺寸小于某个限度的物体才装得进去(你没法把一把汤匙塞进啤酒瓶里),有时只有尺寸大于某个限度的物体才留得住(你没法把铅笔存在网兜里)。容器可以是刚性的或柔软的、不透明的或透明的、能合上的或一直敞开的——这些属性与许多其他物体的属性属于同类。不过,容器有一些特殊问题,是其他物体不会遇到的。

大多数容器是内容器(endocontainer),也就是说,它们把东西装在自己里面。箱子、袋子、碗、篮子——它们都把所装的东西包围在内。不过,还有一类较小的外容器(exocontainer):它们把别的东西托在自己外面。谱架、帽架和圣诞树就是外容器的例子。外容器会“穿戴”它们托着的东西。

有些虚拟世界把外容器与内容器当成完全不同的两回事,理由是:靠包围来装载,与靠钩挂、系绑或别的方式来装载,有本质的区别。当然,这两个概念确实互不相交,但它们的共同点足够多,一般来说把它们当成同一种东西更好。“take music from stand” 和 “take stand from case” 本质上是同一种动作,可以用几乎相同的功能来实现。

关键的差别在两个方面。

第一,不透明内容器的内容可以瞒过窥探的眼睛,而外容器托着什么,你总是看得见。这对文字世界不算太糟,但图形世界必须能构造出动画图像,来配合玩家们几乎任意尝试的各种穿戴组合,这可能非常棘手 1。

第二,对于内容器,容器会保护自己的内容物。如果你击打一个内容器,里面所装的东西受到的伤害可能会减少。对外容器则相反:容器自身受到的伤害可能会减少,因为伤害被外容器托着的东西吸收了。铠甲就是靠这个原理起作用的。

这就引出了一个非常特殊的内容器:玩家自己的角色。尤其是在奇幻世界里,角色携带或穿戴的东西对位置很敏感。你不会把头盔戴在胳膊上,也不会把靴子穿在胸口。图形虚拟世界和文字虚拟世界都有这个问题。

图形世界采用了单机电脑角色扮演游戏的一套标准:显示角色的图像,通常还标出各个“装备槽”,玩家像给纸娃娃穿衣一样给它打点装扮 2。这虽说不上多有沉浸感,但与物品栏总体的运作方式是一致的。文字世界要操心的事更多,因为玩家想指称身体部位。“wear socks”“wear cravat” 之类还行,但玩家想要的是 “wear ring on left index finger”。这就意味着,身体应当被当作一种组合体来处理。玩家通常并不想有条不紊地把身体拆成部件,而且除了在恐怖类型里,人们也不会想要用部件重新拼出新身体来。尽管如此,如果玩家想要指称一个组合体的各个部分,这个组合体就必须被构建出来,或者被伪造出来;无论哪种做法,实现起来都非常烦人,而且等于在向玩家暗示:组合体这种玩法是行得通的。先是身体,接着是成套的铠甲,然后是马匹,再然后是马车——不知不觉间,你已经走得比原计划远得多,响应时间也开始吃紧了。如果你确实决定要实现身体,那就当场定下来它是不是一次性的,并坚持到底。你不会被说动的,你的意志坚如钢铁……

那么书呢?书里有页,但那些页按固定顺序排列,所以它们基本上是组合体。如果有人想 “read page 24”,你会允许吗?还是说,你会让书短到永远只有一页?

把容器变成组合体,可能非常有诱惑力。小心。

把容器变成生成器同样很有诱惑力,但危险小得多。一袋坚果无论你拿出多少,里面总还有坚果,这样挺好——只要你不让任何人把它翻个底朝天。商店里的一个衣帽架可以挂有固定数量的外套,每一件都用惰性求值的方式创建(也就是说,只有有人试图取一件外套时,才会创建出一件来)。

关于容器,最后要提的是负重(encumbrance)这个概念。这是桌面角色扮演游戏里的一个老观念(有人会说它已经过时)。一般来说,一个容器 3 能容纳的物体重量取决于它的力量;它能容纳的件数取决于容器本身的尺寸和相关物体的尺寸(不过对外容器来说,这还涉及某种可用接触点的度量——也就是容器的灵巧度)。然而,物体往往很别扭,它们拖慢你的程度比重量或形状相近的另一些物体大得多。撑开的伞比收起的伞更难拿;氦气球比足球更碍事(这两样东西放了气都更好拿)。

负重这一构想,是要量化某个东西凭自身的属性,在多大程度上影响其容器的各项属性。它是一个不完美的抽象,但有时很有用。即便一个虚拟世界把物体的精确尺寸都存了下来,有些计算代价高昂的运算仍然只能近似处理——比如背包问题(把一个装满的背包倒空,再把原来装的东西全装回去,这可不简单——就像玩三维拼图)。


  1. 即便在二维里也很棘手。KiSS 娃娃(Kisekae Set System——电脑上的数字换装娃娃)经常出现问题,比如蓬松的衬衫会从套在外面的夹克上穿出来。 ↩︎

  2. 这又是 KiSS 娃娃。想了解更多关于 KiSS 的内容,可以看看 http://otakuworld.com/kiss/。警告:小孩子特别喜欢这东西。 ↩︎

  3. 因为角色也是外容器,所以这里也包括角色。这就是面向对象编程在发挥作用。 ↩︎

流体:可分割性

虚拟世界里的物体大多是固体,实现时也基本按固体处理。不过,在对真实世界建模时,要完全避开流体——尤其是水——有点难 1。我用“流体”这个词,而不是“液体”,是为了不把那些(在朴素物理学里)表现得像液体的固体排除在外,比如沙子、灰烬和面粉;我这样说,也是为了把玻璃之类的物质排除在外:它们在定义上算液体,但在人类的时间尺度上主要表现为固体。

流体的核心问题是它们可以无限分割。你可以任意把它们拆开、合并 2。如果某人有一个水瓶和一只玻璃杯,他应当能把玻璃杯倒满水,而多出来的水留在瓶子里。这可以用取巧的方式实现:给所有防漏容器配上一对属性,说明里面装的是哪种流体、有多少;也可以“正规地”实现:为每一份流体创建单独的物体,并把体积作为绑在它们身上的属性。后者一般更可取,因为这意味着流体可以被引用,也可以独立于容器存在(比如你把它们倒在地上的时候)。烦人的玩家可能会把一个很大的容器里的东西反复倒进一个很小的容器,从而造出成千上万个流体物体;但只要你意识到存在这种可能,就不难防止它造成问题。

超过一定大小之后,大团的流体可以被当作生成器。你想从海洋里取多少盐水,就取多少,那里总会剩下很多。在实践中,能当作生成器的流体可以小得多;一片海滩的沙子取之不尽,就连池塘和私家游泳池也可以视为实际上是永远装满的。因为虚拟世界不是真的,甚至可以让小小的容器生成无限的流体 3。

流体从容器里倒进环境时,会有一些潜在的困难。如果倒进去的那个表面上已经有流体,就不是问题,因为任何一大团流体都可以放心地假定为会吸收(或以别的方式消散)加入其中的任何一份流体。往一个(虚拟的)淡水湖里倒油,无论玩家倒多少次,结果都只是把油销毁掉。

如果落点表面原本没有流体,那就是另一回事了。在光滑表面上,流体会顺着坡度流走;在粗糙表面上,它可能积成水洼或水坑;在岩石表面或木板路上,它可能马上渗进缝隙里消失;在干燥的土地上,它可能直接被吸收。实际会发生什么,取决于表面和流体。至少,这意味着所有表面类型都需要先分好类,物理才能判断该怎么处理。

最后一个可分割性问题与渗漏有关。渗漏可以看作随时间发生的体积损失。虽然在现实生活中,从渗漏容器里渗出的流体会留下一道痕迹,但要把这一点做进系统里相当难。一般来说,如果一只桶破了个洞,那么它所含的流体量会以恒定的速率减少,直到一点不剩,仅此而已。这并不意味着你可以把桶装满沙子,再倒出来在田野上写自己的名字。


  1. 药水和麦酒也很常见。 ↩︎

  2. 构成组合体的那些“原子”也可以拆开,但把它们再合起来要费更多工夫。 ↩︎

  3. 就像那个笑话里说的:一个人从精灵那里得到三个愿望。他许的第一个愿望是得到一瓶永远喝不完的啤酒。精灵照办了,他喝了个够,确认它确实管用。精灵问他另外两个愿望是什么。“那再给我来两瓶这样的,谢谢,”他答道。 ↩︎

混溶性

互不相溶的流体带来不了多少问题。如果你有一个一品脱的罐子,里面装着半品脱沙子,你可以用水把它添满。虽然在现实生活中你能装进不止半品脱的水(因为沙子是流体,但不是液体),但在实践中,如果你就按正好半品脱来算,不会有多少玩家不满。往已经装着固体的容器里加流体也是如此:你干脆可以按固体全都不浮起来的方式计算体积,因为即便把排开的那部分也算进去,也算不到足够精确、能满足任何较真到会去查验的玩家的胃口。互不相溶的流体对实现很友好。能互溶的流体对实现不友好。

如果你有半品脱酒精,再往里加半品脱水,你得到的就是一品脱 1 变淡了的酒精。如果你往毒药里加水,你会得到更多、更淡的毒药。如果你往酒精里加毒药,你会得到某种一半有毒、一半醉人的东西。混合流体,就是混合流体的属性。要不是有化学 2,这本来不算太糟。

默认情况下,所有固体都不与液体互溶。不过,有些固体会受到流体的重大影响。你也许能把糖装在一个纸做的容器里,但水会很快把它泡烂。这一番折腾的结果会是水和纸浆,而这两者都不再具有纸袋的那些属性。而在流体这边,你可以把酸加到碱里,得到盐和水;盐和水都没有酸或碱的腐蚀性。因此,混合流体不仅可能涉及物体的创建与销毁,还可能涉及物体属性的创建与销毁。

你们当中比较热心的设计者,此时也许正在设想一套漂亮的化学系统:流体可以拥有各种各样的属性,再加上一系列规则,规定两个或更多属性如何组合、从这份属性清单里造出别的属性。这其实可以做得相当好,探索型玩家一定会为此感谢你。当然,在有别的事可做的时候,这套东西值不值得花这些工夫,是另一个问题;何况凡是能配出来的东西,其配方用不了几天就会出现在玩家的网站上,这也许会让它少掉一些乐趣。不过,如果你有时间,嘿,那就放手去做吧!

关于液体,最后一点是:黏性可能很麻烦。苹果和蜂蜜不相溶,但如果你把一个苹果在蜂蜜里蘸一下再拿出来,最后会有很多蜂蜜粘在苹果上。你要不要把苹果做成一个会渗漏、托着蜂蜜的外容器,由你自己决定;但无论哪种做法,都一定要把玩家必然会做的那些实验考虑进去(“为什么蜂蜜从小猫身上滴下来的速度和从苹果上滴下来的速度一样?毛明明应该留住……”)。


  1. 嗯,如果你非要抠这个,是 98% 的一品脱。 ↩︎

  2. 化学是真实世界物理的一部分;炼金术则是它在超物理学里的对应物。 ↩︎

气体

虚拟世界很少实现气体,即便实现,往往也是把它们做成某个地点或别的物体派生出来的属性,而不是自身独立的物体。

原因与气体(以及花粉、烟这类随气体飘浮的颗粒物)的物理属性有关。气体无处不在,它们的混溶性问题和可分割性问题比液体还要严重,而且很难容纳。

角色能做呼吸、闻味这类简单的事,但任何复杂得多的操作都免不了要捕获气体,而气体一旦被捕获,没有合适的器具就无法再接触到它们。有些虚拟世界里,某些怪物死亡时会释放出气体,但结果相当笨拙。

不妨把空气(或者说大气)当成一个生成器物体,它对所有地点和容器都现成可用。不过,有时把一团团具有特殊性质的气体表示为单独的物体是有用的。这样可以表现阵阵狂风、滚滚尘云、爆炸、温度梯度、成群的小虫、恶臭等效果。

不过总的来说,虚拟世界真正需要考虑的气体只有空气,而且只是为了完整性才考虑。图形世界连空气都不需要 1——空气就是“那里没有别的东西时,那里有的东西”——但文字世界应当把它算进去,因为在那种情境下,玩家是用名字来指称物体,而不是用指点设备去点取。


  1. 另一方面,雾和远处的霾…… ↩︎

等离子体

在大多数虚拟世界里,唯一值得注意的等离子体就是火。火通常被当作单独的物体来处理,但处理方式并不总是完全符合现实。把它们建模成会发出虚拟的热与光,这很容易做到,但问题在于:在现实生活中,火会蔓延。在虚拟世界里,火不会。你可以点燃可燃材料,它们会烧起来,甚至会引燃附近的物体。不过,火通常不会蔓延到环境里。

原因有两条。起决定作用的原因是:这件事非常难做!火是会改变世界的事件:如果你把一根点燃的火柴丢进干燥的草原,你就把它变成一片焦黑的景观;树木被烧成发黑的残桩,建筑只剩空壳,到处都了无生机。要预测建筑的任意部分被烧掉之后结构会怎么坍塌,是非常困难的。

第二条原因是:即便失控的火可以建模,容许它存在也是不明智的。现实世界里,所有财物火灾有一半是纵火造成的;在虚拟世界里,用这种方式毁掉一切的诱惑也会让人无法抗拒。就连平时并不热衷破坏的玩家,也可能想:不如就试一次。“哇,你说我要是放火烧了林子,杀掉 200 头熊,会不会拿到经验值?”

状态变化

给水加热,它就变成气体(蒸汽);把水冻起来,它就变成固体(冰)。同样,气体可以凝结,固体可以熔化。这些都是状态变化。你想在自己的虚拟世界里加入状态变化吗?

没有状态变化,一个虚拟世界也可以做到令人满意的可信度。如果你完全没有办法给东西加热或降温,探索型玩家也许能琢磨出原因,然后心里不痛快;但大多数玩家会坦然接受。

另一方面,状态变化实现起来也没那么难,而且能打动玩家。它很容易用一对“销毁/创建”来实现:销毁蒸汽,创建水;销毁熔岩,创建岩石。在现实生活中,状态变化需要能量才能发生(冰箱就是这么工作的),但在没有精确温度计的虚拟世界里,你就不必为此操心了。

属性

属性是物体物理特征的抽象。在虚拟世界里,这种做法常常会延伸到非物理的属性上,我们很快就会看到;但占主导地位的是物理属性(质量、密度、形状、颜色,等等)。

属性常常被实现为函数,这样很少用到的属性就可以在需要时才计算。不过,虽然属性在被读取时不会改变任何值,函数一般而言却会改变值:检查一个气球的“diameter”(直径)属性不会改变它的直径 1,但在气球上调用“inflate”(充气)函数就可能改变它。不过从实现的角度看,两者可以长得一模一样。

属性与对象类之间的相处并不总是顺畅。一个瓶子掉在地上会碎,是因为它作为瓶子属于“fragile objects”(易碎物体)的子类吗?还是因为它继承了一个高取值的“fragile”(易碎)属性?你需要多少封装?也许它碎掉,是因为它有一个值为“glass”(玻璃)的“made of”(材质)属性,而玻璃又有一个高取值的“fragile”属性?

要建立一套分类体系,既让物理系统能实现、又不把设计者变成程序员,这是个棘手的领域(更糟的是,许多设计者本来就是程序员出身)。严格说来,这不是朴素物理学的问题,而是表示方式的问题。

遗憾的是,这里其实还没有什么惯例可循。你只能为了让自己的物理能跑起来而做必须做的事。我唯一建议的是:让属性也可以(在面向对象的意义上)成为对象,这样你就能对它们进行量化。如果你能让虚拟世界引擎回答这样一个问题——“给我这个物体所有属性及其对应取值的清单”——那灵活性就足够了。

顺便说一句,当你在寻找区分物体的新办法时,手头有一份现有属性的清单非常有用。“这面魔法盾除了加上通常的防护加值之外,还该有什么作用?嗯,角色有身高、质量、速度这些属性,嗯……眼睛颜色、体毛浓密程度——嘿,我可以让他们一用这面盾就长出毛来!这肯定能把人吓一跳。我就把它做成矮人盾吧,因为矮人看重胡子,女的也一样,而且……”

在一个理想的世界里,物体的全部功能都能从它们的属性推导出来吗?能——在一个理想的世界里。你可以看出某个物体有一面坚硬、薄、平坦、结实、半锋利的表面,连接着一个长、坚固、轻却不脆的部件,顶上还有一根横杆,并由此推断出这个物体适合在草坪上挖洞。虚拟世界不是理想世界,因为这种程度的功能推导会把它压垮。也正因为不是理想世界,你能用铲子挖洞,靠的是“dig”(挖)这个动作认得铲子(也许还认得铁锹和鹤嘴锄)。除此之外,你没法用一面破盾加一根篱笆桩拼出一把铲子来。

所以,组合体的爱好者们,很抱歉:你们短时间内也不太可能靠这条路得到它。


  1. 朴素物理学没有不确定性原理。 ↩︎

所有权

在讨论物理的时候放进一小节讲所有权,也许显得奇怪,但(正如第 3 章所指出的)对虚拟世界来说,所有权可以看作一种物理性质。要注意,这里说的是虚拟的所有权——也就是虚拟世界情境之内的所有权;虚拟物体在现实世界里的所有权,完全是数据与知识产权的事(虚拟世界的其他许多方面也是如此)。

实现所有权有两种办法。第一种是给所有物体一个“owned by”(归谁所有)属性,它可以为空(比如角色不归任何人所有),也可以指向某个有能力拥有他物的物体(比如一个角色、一个公会)。第二种是让它隐含:你携带什么,就拥有什么。后者适用于持久程度较低的虚拟世界。

对持久程度较高的世界来说,本该优先采用前者;不过那样会变得极其复杂,所以它们把“占有即法律的十分之九”这一观念延伸到存放在玩家自有土地上的物品,但一般不追踪单个物体的归属。

说到这里,你也许会问:为什么不追踪呢?计算机非常擅长记账工作,而这不过就是记账,对吧?

对,但问题出在怎么拟定规则上。

假设角色 A 拥有一瓶香槟,角色 B 拥有一瓶橙汁。两人都把瓶子放在地上;瓶子仍然归他们所有。我把瓶子捡起来;瓶子仍然归他们所有,而我是个贼。我把两个瓶子里的东西倒进一只碗里混起来;现在谁拥有什么?大概不是归我,但归角色 A 还是角色 B?按体积算,大头可能该归 B;按价值算,大头却该归 A。

组合体与集合的组成部分也会出现同样的追踪问题。如果我从五个玩家那里各偷走五个单位的货币,又在一次打赌中输掉 18 单位 UOC,那么我剩下的 7 单位 UOC,谁有权主张?

“谁拿着就归谁”这条简单规则也不能到处套用。你的角色捡起一个物体时,它通常会被放进某个容器里,而这容器通常就是背包 1。不过,它也可能是一只手或一条麻袋,或者……好吧,我们来看看它还可能是什么。

虚拟世界里的固体物体,通常都会归入以下抽象类别之一:

  • 可以穿戴的东西(比如一顶帽子)

  • 单个人可以携带的东西(比如一本书)

  • 几个人一起才能搬动的东西(比如一条长凳)

  • 可以移动但没法拿起来的东西(比如一辆手推车)

  • 能自己行动的物体(比如一匹马)

  • 不能移动的东西(比如土地)

  • 看起来是被携带、实际上并没有被携带的东西(比如硬币)

我可以戴一顶帽子或拿一本书,并确信它是我的。可是,如果我买了一条长凳、想把它搬走,我怎么能确定它还归我?一匹马或一辆手推车呢?就像土地一样,有些东西确实必须追踪其所有权,不管你愿不愿意。

不过,就算追踪了,也并非总能解决问题。如果我偷了一把剑、把它卖成金币,新的主人必须把它交还给原来的主人吗?如果不必须,那太好了:我让我的小号去偷,让我的主号去买。如果必须交还,那也很好:我让小号把剑偷来卖给别人,再把洗白的金币交给我的主号。无论哪种情况,那把剑的下落都还是查得出来的,但偷它的人多半能逍遥法外(至少就虚拟世界而言是如此——玩家们可能另有想法)。

于是,虚拟律师登场了……


  1. 在大多数图形化虚拟世界里,是看不见的那种背包。 ↩︎

时间

时间是玩家与角色共有的唯一一个维度,因此它完全受现实支配。这并不意味着它必须与现实时间完全相同,但确实意味着它必须直接映射到现实时间。

虚拟世界里发生的大多数动作都相当即时(前提是网络不卡)。因为人们常常习惯把一连串复杂的动作当作单条命令来看,所以偶尔会出现需要花时间执行的命令(比如做一顿饭)。此外,朴素物理学有时会要求某个命令的效果在执行之后才发生(比如点着引线之后随之而来的爆炸)。正如我们在火那里看到的,有些命令的效果可能造成混乱,而且可能无限期地持续下去。不过,大多数命令都会立即做出响应,并且除了以严格规定的方式之外不会向外传播(典型的方式是给能察觉到该命令效果的角色生成反馈)。

这样做的一个后果是:移动的速度比它“本该”有的速度要快得多,这在节点式实现的虚拟世界里尤其明显。爬一段楼梯花的时间,可能跟穿过一片森林一样多。速度以每秒节点数来衡量;由于节点不一定对应固定的地面尺度,这让牛顿运动定律成了笑话。幸运的是,玩家不会被这一点惊到:只要两个概念上“遥远”的地点之间的移动比两个“近”的地点之间花的时间更长,他们就随它去了。不过,这一点还是会被注意到的。

在图形化虚拟世界里,速度可以用每秒行进的地面距离这种传统单位来衡量,因此移动不会快得那么离谱,否则看起来就很荒唐。然而,这种程度的真实感会把世界残酷地缩小。在《无尽的任务》里,一个角色慢跑穿过一块“大陆”所花的时间里,现实世界里的马拉松选手也许已经横穿了新加坡。想想把诺拉斯的地图挪到马来西亚的南端,它突然就显得没那么巨大了。

虚拟世界也许与真实时间绑定,但不必使用真实时间。在有些虚拟世界(尤其是持久程度低的那些)里,时间实际上始终是一样的——钟表可能照走,但没有昼夜之分。另一些则采用加速的线性方案:《DikuMUD》系通常把 30 分钟真实时间映射为游戏世界里的 24 小时。对玩家更友好的做法是非线性的,让夜晚(NPC 在睡觉的时候)过得比白天(内容丰富得多的时候)更快。一个虚拟日有多少小时、一个虚拟周/月/年有多少虚拟日,都可以各不相同,但一小时通常还是 60 分钟、一分钟还是 60 秒(如果时间划分细到那一级的话)。年份是否递增取决于情境:如果一个设定在 20 世纪 20 年代的虚拟世界按《DikuMUD》的时间运行,整个十年都用不了现实世界里的 11 周。季节在玩法上可以有它的用处,年份却很少用得上(怎么,你想让角色变老吗?!)。带有故事线的虚拟世界是有原则的例外。

有些虚拟世界会加入与现实时间相关的节令内容。比如《MUD1》备了一批用于圣诞节的节日活动生物和物品,《MUD2》又为复活节、万圣节、愚人节、篝火之夜(11 月 5 日——这是英国特有的)和三月(那里有只疯疯癫癫的野兔)添了更多。《网络创世纪》把这种做法带进了图形世界。虽然在理论上(偶尔在实践中)这些内容会破坏沉浸,但总体上它们很受玩家欢迎,因为它们带来一种恒久感;一个虚拟世界有节令内容这件事本身就表明,它是打算长期做下去的。一些单薄的说辞,比如让一场“亡者之夜”与现实世界的 10 月 31 日重合,就足以替这种做法提供必要的掩护。不过,这只有在不设内部时间的虚拟世界里才行得通。在一个官方季节是春天的世界里庆祝圣诞节,会显得很怪异;同样,如果虚拟圣诞树在现实的七月就冒出来、还挂满装饰,也没多少玩家有那个心情。

还有一些值得关注的问题,与这类庆典中某些活动的宗教性质有关;这些将在第 8 章讨论。

昼夜:区别在哪里?高持久度的虚拟世界必须在这个问题上选边站;任何以现实世界为蓝本的户外环境,昼夜的差异都很难忽略,但总体上说,昼夜之中总有一个对玩家来说更有趣。严格的实现会让大多数 NPC 在夜里睡觉,并让另一批怪物在夜里活动。这就给昼夜带来了玩法上的差异,能让玩家的日子更有意思(当然,这也意味着要创作更多内容——很贵)。至于更偏物理层面的差异,最明显的一条是夜里更暗 1。处理这一点有两种办法:把虚拟世界拖入会改变玩法的黑暗;或者让虚拟世界暗示黑暗、但实际并不黑(例如打上一层蓝色)。完全的黑暗大概总得为实现地下探险而做出来,所以并没有什么实际理由不让夜晚像现实里那样昏暗。许多虚拟世界之所以选择一种看起来更像黄昏的装饰性夜晚,是因为那样对新手更友好(要么这样,要么给他们一盏很快就会弄丢的提灯)。图形世界还有另一个问题:各种显卡呈现低亮度画面的能力不一样——同一幅画面,有的玩家能轻易看见,有的玩家可能完全看不见。

关于虚拟世界里的时间,最后要谈的一点是在时间中旅行。当然,所有角色都在时间中旅行,方向相同,速率与真实时间相关。只要内容做得出来,他们本可以全都回到过去,或者以更快的速率(相对于真实时间)前往未来。不过,单个角色的时间旅行是不可能的:一个角色没法回到昨天,因为对其他角色来说今天就是今天 2。封闭的时间断层(sealed time discontinuities)是可行的(你可以把一个角色放进一个仿造的昨天里,告诉他这就是昨天),但互动是有限的。如果一个角色“回到过去”关上了一扇门,这件事只有在精确、预先设定好的条件下才能对“今天”的某个玩家产生后果。全局尺度上的时间旅行——也就是虚拟世界里的所有人一起——是可能的 3;但在局部尺度上,它在虚拟世界里并不比在真实世界里更有可能。


  1. 仅次于最明显那一条的差异,也就是夜里更冷,很少有人考虑。虚拟世界里的夜晚主要是关于黑暗。 ↩︎

  2. 实际上,有些虚拟世界确实允许单个角色回滚到早先的某个状态,而不影响其他人。我确信这些世界的设计者相信,他们有十足的理由批准这种走投无路之举。 ↩︎

  3. 它也可以很好玩。如果你事先告诉玩家会有一次时间滑移(先保存数据库,让玩家玩上一个小时,再恢复保存的版本),他们会蜂拥而至,利用这段暂时无须承担后果的时间。 ↩︎

主动物理学

在虚拟世界里游玩的人,受这个世界的物理约束,而物理是用计算机代码实现的。无论他们在虚拟世界里采取什么有形的行动,行动的后果都由程序界定。玩家必须把这一点当作世界的一部分来接受,就像在真实世界里必须接受真实世界的物理一样。他们可以对其中某些方面提出异议,甚至也许能说服运营团队去改动,但他们没法退出自己不喜欢的某些规则。如果魔法剑终有一天会磨损这件事让他们恼火,他们要么一边抗议一边继续玩,要么退出。

主动物理学则把这一点用得很激进。假设你不希望玩家在现实世界里互相买卖虚拟物体。你可以给所有物体一个“sold on eBay”(在 eBay 上售出)标记,只要物体以这种买卖的方式易手,这个标记就会被置上(手动或自动)。被这样标记的物体会比没被卖过的物体磨损得更快。运营方可以这样告诉来抱怨的玩家:物体本来就会磨损,磨损快慢取决于怎么使用;而把它卖到另一个世界(也就是真实世界)会给它带来跨维度的应力,从而损害它的完好度。还是会有人觉得这不公平而提起诉讼,他们也许能就“意图”做点文章(这基本上就是常规物理与主动物理的分野);不过,一套自洽的设定是强有力的抗辩。

就我个人而言,除了能增进个人自由的场合,我反对以这种方式用虚拟世界的物理去达到现实世界的目的。话虽如此,我坚定地认为,所有代码与数据都归开发者所有,他们想怎么处置就怎么处置。虚拟世界不是文字处理软件那样的工具——人们用工具创作自己拥有的数据;虚拟世界是人们前去造访的地方。如果你来到我家,在我的纸上用我的颜料创作了一幅画,很抱歉,这幅画不归你所有,除非我同意,你也不能把它卖给别人。

玩家之间无论就虚拟实体的访问权达成什么交易,除非开发者认可,否则都不构成虚拟所有权的转移。如果玩家不喜欢这样,他们要么退出、去玩一个开发者把数据所有权让渡给玩家的虚拟世界(并指望管辖那些虚拟数据变更的现实世界法律严密无缝),要么自己搭建并运营一个虚拟世界。

第 3 章关于玩家与角色权利的讨论,是以开发者的善意(good faith)为前提的。主动物理学可以是这一讨论的延伸,但设计者必须非常小心,不要开一个坏先例。如果玩家利用虚拟世界的物理来让别的玩家日子难过,运营方可以堵上这个漏洞、封禁肇事者;如果是运营团队这么做,那随之而来的就只有反抗或出走。