两种语言的故事

作者:Daniel Bartholomew

自从互动小说(或文字冒险)类型随着 Will Crowther 的 Advent 于 1975 年问世以来,人们一直在努力寻找使其创作更容易的方法。

最初的 Advent 是用 FORTRAN 编程的。Don Woods 创建的扩展版本使用了 PL/1。这两种语言都是通用的计算机语言,非常适合许多任务,但不太适合创建互动小说。许多早期的 Advent 爱好者都想创建自己的游戏版本,但使用 FORTRAN 或 PL/1 很困难甚至不可能,这取决于他们移植到的计算机平台。

许多早期的实现者意识到,互动小说的大部分内容只是文本,而游戏的操作系统特定部分仅占总体大小的 10% 甚至更少。许多人得出的解决方案是将所有操作系统无关的文本和逻辑放入一个故事文件,然后创建一个解释器或虚拟机,可以播放或运行该故事文件。这些故事文件最初是用一种专为创建冒险游戏而设计的自定义语言编写的,然后编译成适当的格式。这种方法使得最流行和商业上最成功的类 Advent 游戏 Zork 能够适用于 23 个不同的平台,这证明了“虚拟化”的力量,早在它成为热门流行语的几十年前就已如此。

Infocom,像所有商业发行商一样,有自己的语言。Infocom 的语言被称为 ZIL(Zork 实现语言)。它不是公开的,必须在大型机上编译。编译后,它将在 Z-Machine(Zork-Machine)内部运行。Z-Machine 的端口是为 Infocom 支持的每个平台构建的。ZIL 语言功能强大,功能丰富,但其专有性质,以及编译需要大型机的事实,使其业余爱好者无法企及,因此社区创建了自己的语言。Six/Fant、DDL(Dungeon Definition Language)、ADL(Adventure Definition Language)、TADS(Text Adventure Development System)、AGT、Hugo 等被创建出来,使任何人都可以编写互动小说。

在 Infocom 短暂的生命周期中,创建了几个版本的 Z-Machine。这些版本在它们支持的故事文件的复杂性方面有所不同。例如,Z-Machine 的版本 3 最多支持 255 个对象、32 个属性和最大故事文件大小为 128K。Z-Machine 的版本 5 可以处理多达 65,535 个对象、48 个属性和最大故事文件大小为 256K。Z-Machine 的版本 8 与版本 5 相同,只是增加了支持高达 512K 大小的故事文件的功能。版本 5 是 Infocom 用于其大多数高级游戏的版本。

到 1990 年代初期,所有商业发行商都已倒闭,因此如果您想玩新的互动小说,您要么必须自己编写,要么在专门讨论互动小说的新闻组中闲逛。来自 Infocom 和其他公司的经典游戏仍然可以在各种重新发行和收藏版中找到。互动小说类型并没有消亡,但许多人认为 1989 年到 1990 年代中期是“黑暗时代”。

尽管取得了进展,但 Infocom 游戏仍然被视为互动小说的最高水平,创作者很难使用各种社区开发的系统来接近它们。它们的功能不够强大,或者缺少重要的功能,或者缺少像样的解析器,或者以上所有情况都存在。

直到 Graham Nelson 成功地逆向工程了 Z-Machine,并创建了一种语言和编译器,可以生成与任何支持 Z-Machine 版本 5(和 6 和 8)的解释器兼容的故事文件,互动小说的第二个黄金时代才开始。他称他的作品为 Inform,并且他将语言的设计基于 ZIL。

说到 ZIL,这是一个简单的例子

<OBJECT SERVER
        (LOC SERVER-ROOM)
        (DESC "an ancient server")
        (FLAGS NODESC)
        (SYNONYM SERVER COMPUTER MACHINE ANCIENT OLD)>

基本上,当在 ZIL 中创建某些东西时,您有对象,这些对象具有属性和特性。这种格式证明了自己对于 Infocom 游戏来说非常灵活,并且随着新版本的 Z-Machine 的开发,该语言得到了修改和改进。

Inform 也遵循了类似的路径。与它旨在兼容的 Z-Machine 一样,Inform 语言在过去几年中经历了多次改进。Inform 的当前版本是 6 和 7。在这两个版本中,Inform 版本 6 与 ZIL 非常相似。这是一个 Inform 6 中的 ZIL 示例

Object server "server" server_room
    with
        description "an ancient server",
        name 'server' 'machine' 'computer' 'ancient' 'old',
    has scenery;

一切仍然是一个对象,它们之间的大部分差异(至少在上面的示例中)都在于命名。FLAGS 已重命名为 has,SYNONYM 已重命名为 name,NODESC 已重命名为 scenery 等等。这并不是说没有实质性的差异——是有的。目前可能主要的区别在于,Inform 6 可以创建比 Infocom 用 ZIL 创建的任何游戏都更大更复杂的游戏。

然而,即使有了功能强大且经过改进的语言,许多顶级的互动小说作家——包括 Graham Nelson、Emily Short、Andrew Plotkin、Sonja Kesserich 等——也觉得用 Inform 6 编写互动小说不够自然。用 Inform 6 写作感觉像编程;这是无法避免的。对于这种说法,轻率的反驳是,“好吧,是的。你正在创建一个电脑游戏。你期望什么?”他们的回应是,创作互动小说应该更像是创作普通的“非互动”小说。

Inform 7 与 Inform 6 的区别有多大?好吧,这是上面 Inform 7 中的相同示例

The ancient server is scenery in the server room. Understand 
"machine" and "computer" and "old" as the ancient server. 
The description of the ancient server is "an ancient server".

所以,我们没有语句,而是有自然语言段落。然而,当 Inform 7 处于规划阶段时,就做出了决定,即使它朝着一个全新的方向发展,它仍然应该建立在 Inform 6 之上。Inform 7 在编译期间在幕后所做的是解析您编写的内容并将其翻译成 Inform 6。翻译是由机器完成的,所以它看起来不像人类会写的那样,但它是有效的 Inform 6,可以由常规的 Inform 编译器编译。这使得开发人员可以专注于语言的设计,而不是全新编译器的设计。

为了说明 Inform 6 和 Inform 7 之间的差异,我用两种语言创建了一个示例游戏。由于空间限制,我们无法在此处打印完整的游戏,但它们可以在我们的 FTP 站点 ftp://ftp.linuxjournal.com/pub/lj/issue174/10130.tgz 上找到。

每个游戏的编译版本也可以从 Linux Journal FTP 站点下载(可在上面列出的相同地址获得)。即使源代码非常不同,但它们的游戏玩法是相同的。

当我引用这两个程序时,我将使用 Inform 版本(i6 或 i7),后跟冒号 (:) 和行号。因此,如果我引用 cd-tray 对象的 Inform 7 版本,我将写成 i7:094-095(列表 1)。

列表 1. 在 Inform 7 中描述 CD 托盘

094  The CD Tray is part of the old server.
095      The description is "It's a CD tray."

从第一行就可以看出两种语言之间的差异。当在 Inform 6 中开始一个故事时,需要在开头 (i6:001-007) 和结尾 (i6:172-193) 完成一些必要的内务处理,以便故事能够编译(列表 2)。

列表 2. 用于编译 Inform 6 的基本代码

001  !% -SD
002  
003  !========================================================
004  Constant Story "The Server Room";
005  Constant Headline
006      "^An Interactive Fiction by Daniel Bartholomew.^";
007  Release 1; Serial "080625"; !for keeping track of releases
.
.
172  !========================================================
173  ! Entry point routines
174  
175  [ Initialise;
176      location = break_room;
177      "^^^^It's Saturday, a nice one at that, and you've been
178          called to fix a server. Again.^^You've had it. This
179          server is going to run Linux starting today! The process
180          will be easy, just put the disc into the server go.
181          Now where is that Ubuntu CD?^";
182  ];
183  
184  [ Deathmessage;
185      if (deadflag == 5) print "You have won";
186  ];
187  
188  !========================================================
189  ! Standard and Extended Grammar
190  
191  Include "Grammar";
192  
193  !========================================================

在 Inform 7 中,唯一绝对需要的是第一行 (i7:001)。公平地说,Inform 6 中的初始化例程还包括在游戏开始时显示的消息。在 Inform 7 中也存在这种情况 (i7:007-011),但这不是成功编译所必需的(列表 3)。

列表 3. Inform 7 的初始程序代码

001  "The Server Room" by "Daniel Bartholomew"
002  
003  Include GNU GPL v3 by Free Software Foundation.
004  
005  The maximum score is 6.
006
007  When play begins, say "It's Saturday, a nice one at that,
008      and you've been called to fix a server. Again.
009      [paragraph break]You've had it. This server is going to
010      run Linux starting today! The process will be easy, just put
011      the disk in the server and go. Now where is that Ubuntu CD?"

变量的定义在两个版本中都很相似——例如,最大分数变量(i6:009,i7:005)。主要区别在于 Inform 6 版本使用类似 C 的语法

Constant MAX_SCORE = 6;

而 Inform 7 使用的句子读起来类似于人们大声朗读 Inform 6 版本的方式

The maximum score is 6.

版本之间的一些差异同样很小。一个例子是在长文本段落中插入段落分隔符的方法,例如在服务器机房的描述中(i6:114-118,i7:082-086,列表 4)。在 Inform 6 中,使用两个插入符号 (^^),而在 Inform 7 中,语句段落分隔用方括号 ([]) 括起来就可以完成工作。

列表 4. 描述房间的语法

Inform 6 Version:
114  description "The fans, the lights, the chill... yep, it's a
115      server room. Full of servers from a dozen vendors,
116      each with their own quirks.^^Your attention is
117      immediately drawn to a server 2/3 of the way up rack 7.
118      The indicator light is blinking red and beeping.",

Inform 7 Version:
082  The Server Room is a room. "The fans, the lights, the chill...
083      yep it's a server room. Full of servers from a dozen
084      vendors, each with their own quirks.[paragraph break]Your
085      attention is immediately drawn to a server 2/3 of the way up
086      rack 7.  The indicator light is blinking red and beeping."

当我刚开始时,我犯的一个大错误是首先在 Inform 7 中创建所有内容,然后在创建等效的 Inform 6 代码。这在某些情况下被证明是棘手的——最值得注意的是,当您在服务器机房时,每次转弯都会出现的随机蜂鸣声消息(直到您修复服务器并赢得游戏)。在每个版本中,对此类逻辑进行编程都非常不同。在 Inform 7 中,编写这个几乎不需要思考 (i7:097-103)。基本上,我描述了我希望每次转弯发生的事情,Inform 7 使其发生。Inform 6 代码执行相同操作的功能不如 Inform 7 先进 (i6:120-134)。它基本上是一个 case 语句,但相比之下,编写起来要困难得多(列表 5)。

列表 5. 编程游戏逻辑

Inform 6 Version:
120  daemon [;
121      if (location ~= server_room) return;
122      beeping = random(7);
123      switch (beeping) {
124          1: "^The beeping is driving you crazy.";
125          2: "^It's hard to think, with all of the beeping.";
126          3: "^The monotony of the beeping is maddening.";
127          4: "^You can't stand the beeping.";
128          5: "^The beeping reminds you of your alarm clock.";
129          6: "^beep . . . beep . . . beep . . . beep . . . beep
130               . . . beep . . .";
130          7: "^If you don't stop the beeping soon, you'll lose
132               what little hair you have left.";
133      }
134  ],

Inform 7 Version:
097  Every turn while in the server room, say "[one of]The beeping is
098      driving you crazy.[or]It's hard to think, with all of the
099      beeping.[or]The monotony of the beeping is maddening.[or]You
100      can't stand the beeping.[or]The beeping reminds you of your
101      alarm clock.[or]beep . . . beep . . . beep . . . beep . . .
102      [or]If you don't stop the beeping soon, you'll lose what
103      little hair you have left.[purely at random]"

评分是 Inform 7 简化的另一件事。在 Inform 6 中,您可以为对象赋予 scored 属性,但对于自定义情况,例如奖励 2 分而不是默认的 1 分,您需要自己跟踪事情 (i6:150-156)。在 Inform 7 中,这个过程要容易得多 (i7:105-106,列表 6)。

列表 6. 评分的语法

Inform 6 Version:
150      before [;
151          Open:
152              if (openedtray == 1) {
153                  score = score + 2;
154                  openedtray = 2;
155              }
156      ],

Inform 7 Version:
105  After opening the CD tray for the first time: award 2 points;
106      say "You press the button and the CD tray pops out."

那么,哪个版本最好?如果我必须在两者中选择我最喜欢的,那肯定是 Inform 7。

我更喜欢 Inform 7 不是因为我发现 Inform 6 难以使用,也不是因为它是一种令人不快的体验。恰恰相反——Inform 6 设计精良,并为初学者和高级用户提供了出色的文档。它也有一些明显的优势——主要的优势之一是精确性。Inform 6 将完全按照您告诉它的那样做。另一方面,Inform 7 的精确度较低,有时您需要摆弄它才能使其完全按照您的意愿执行。这种缺乏精确性是 Inform 7 在编译之前将您的代码翻译成 Inform 6 的结果——它有时必须猜测您的意思,并且偶尔会出错。

尽管存在一些缺点,但我更喜欢 Inform 7 而不是 Inform 6 的原因是,我更像是一个作家而不是一个程序员。我定期进行编程的最接近的方式是 bash 脚本,偶尔会加入一些 PHP。用 Inform 7 编写东西的自然句子结构比 Inform 6 的类 C 语法对我来说更直观。作为一名作家,我有时会想,“如果我在阅读代码时将 'somevar=42' 发音为 'somevar gets 42',为什么我不能那样写呢?”我意识到并接受计算机语言之所以如此简洁和精确是有许多原因的,但我也认为应该赞扬和尽可能地复制像 Inform 7 这样的努力。

Inform 6 的精确性,与其他编程语言一样,在某些情况下是好的,但在其他情况下是坏的。例如,一个放错位置的逗号或分号或括号会阻止您的游戏编译。Inform 7 在这方面也不是完全宽容,但我发现自己犯的错误更少,因为允许您以灵活和自然的方式编写。

Inform 7 的另一个巨大优势是它附带的出色的集成 IDE,其中包含出色的内置文档、调试器和其他工具。对于 Inform 6,编译是一个命令行操作,可能难以正确设置。我不会在此处介绍 Inform 7 IDE,但如果您有兴趣,请参阅 Linux Journal 网站上的两部分系列文章“Gnome Inform 7 简介”。

有了 Inform 7,现在是创建您自己的互动杰作的最佳和最轻松的时刻。所以,找到栅栏的钥匙,加入我,到地下世界去吧。我将在一个曲折的小通道迷宫中,一切都一样,试图找到偷走我金子的胡子海盗——如果矮人没有先杀了我。XYZZY!

资源

示例游戏: ftp://ftp.linuxjournal.com/pub/lj/listings/issue174/10130.tgz

Gnome Inform 7 简介,第 1 部分: www.linuxjournal.com/content/introduction-gnome-inform7-part-1

Gnome Inform-7 简介,第 2 部分: www.linuxjournal.com/content/introduction-gnome-inform7-part-2

Inform 6: www.inform-fiction.org/inform6.html

Inform 7: www.inform-fiction.org/I7/Welcome.html

Frotz: frotz.homeunix.org/frotz

Zoom: www.logicalshift.co.uk/unix/zoom

Fortran: en.wikipedia.org/wiki/Fortran

PL/1: en.wikipedia.org/wiki/PL/I

ADL: adl.sourceforge.net

Six/Fant: www.graysage.com/cg/Compilers/SixFant

TADS: www.tads.org

AGT: www.markwelch.com/agt.htm

Hugo: www.generalcoffee.com/hugo.html

The Interactive Fiction Archive: www.ifarchive.org

Baf's Guide to the IF Archive: wurb.com/if

互动小说新手指南: www.microheaven.com/IFGuide

Daniel Bartholomew 自从多年前在 Apple IIe 上第一次接触到互动小说以来,就一直是互动小说的爱好者。他和他的妻子以及孩子们住在北卡罗来纳州。

加载 Disqus 评论