变量部分|The Vars Section
Chapbook 允许你处理状态的主要方式是通过 变量 (vars) 部分。这些部分总是出现在段落开头,并且通过两个短杠(--)与普通文本分隔开。
延续上一节的例子,一个极其刻板的地牢探险的第一段可能看起来是这样的:
力量:18
敏捷:7
体质:14
智力:9
感知:8
魅力:11
--
在村中酒馆度过一个纵情狂欢的夜晚后,你踏上了前往最近地下城的小径。这是个阳光明媚的日子,心中有了明确的目标让你倍感愉悦。
当玩家访问该段落时,Chapbook 会在故事状态中添加六个变量:力量、敏捷、体质等,并将它们设置为所列出的数值。
变量区块永远不会向玩家显示任何内容;这样,例如,你可以设置一个名为 doomedToDieInFiveMinutes 的变量,而除非你希望让玩家知道,否则玩家将对此一无所知。
每个段落中只能有一个变量区块,但实际上也只需要一个。状态变量的命名也必须遵循一些规则。它们必须以字母(大写或小写)、下划线(_)或美元符号($)开头;第一个字符之后可以是前述类型的字符以及数字的任意组合。1
遗憾的是,你不能在变量名中使用空格。因此,一种被称为 驼峰命名法(因其产生的单词形似驼峰)的常见做法是使用大写字母将短语连接在一起,就像上面那个 doomedToDieInFiveMinutes 的例子一样。另一种命名风格,蛇形命名法,则倾向于使用下划线;例如 doomed_to_die_in_five_minutes 。两种方式都完全可以。选择你觉得最舒服的使用即可。
另一种常见做法是,当变量的值仅在当前段落中使用时,在变量名前加一个下划线。这种做法只是给自己一个提示;Chapbook 并不强制要求这样使用。2
变量名唯一会向玩家显示的时刻,是在他们游玩你的故事时发生错误的情况下,因此请选择易于记忆且具有描述性的名称。既然可以使用 sawFootprintsInVault,就没有必要使用 clueF 这样的变量名。
变量具有类型|Variables Have Types
本节开头的例子为变量分配了数字,但变量也可以保存其他类型的值。
字符串 是字母、数字、空格和其他符号的集合。字符串由撇号(')或引号(")包围,以明确其起始和结束位置,这与文本参数值的用法相同。你可以使用任一标点符号来标记字符串的开头和结尾,但就像 Markdown 的斜体和粗体一样,每次使用必须保持一致。如果需要在字符串内部使用分隔符字符,请在其前面键入反斜杠(\),例如 'Don\'t, just don\'t.'。
字符串非常适合用于存储事物的名称。例如,如果您想让玩家在故事开始时为主角命名,字符串将是最佳变量类型。您还可以使用字符串来存储模糊类型的值。例如,您可以将两个角色之间的关系状态记录为“友好”、“中立”、“警惕”或“敌对”。
布尔值 简单地记录真或假的值。与数字类似,你不需要在布尔值周围添加任何符号来表明它是什么;只需输入 true 或 false。布尔值非常适合记录故事中是否发生了某事;例如,主角是否找到了线索。
还有其他更复杂的值类型将在后面讨论,但数字、字符串和布尔值已经足够你使用很长一段时间了。作为回顾,这里有一个示例段落,其变量部分包含了所有三种类型的变量。
dollarsInPocket: 12
openedPortalToAlternateDimension: true
名字: 'James'
--
你的冒险旅程即将抵达终点。
变量可以被计算|Variables Can Be Calculated
你不必将变量设置为某个单一的值——也就是说,当主角在地上发现一美元时,变量部分可以这样写:
dollarsInPocket: dollarsInPocket + 1
此变量部分通过表达式将 dollarsInPocket 变量增加1。您可以将表达式理解为公式或计算过程,即任何能通过求值转换为单一值的元素。例如,您可以使用基础数学运算——加法、减法、乘法、除法——来处理数值变量。您还可以使用加法连接两个字符串,例如 fullName: first + ' ' + last,但不可对字符串使用其他数学运算符。
您还可以比较两个数字或字符串,得到一个布尔值。
===,“等于”
如果两侧是相同的数字或字符串,则为真。字符串必须完全相同:'DOE'不等于'DOE','DOE '(注意末尾的空格)也不等于'DOE'。!==,“不等于”
如果两边不相同,则为真。>, “大于”,以及>=,“大于或等于”
如果左侧大于右侧,则为真。如果使用>=,则当两边相等时也为真。<,“小于”,以及<=,“小于或等于”
当左侧小于右侧时为真。如果使用<=,那么当两侧相等时也为真。
一般来说,如果一个字符串在字母顺序中排在另一个之后,就认为它更大。例如,'b' > 'a'。但这些比较可能会令人困惑且不直观。'+' 是否大于 '&'?实际上是的,但你能一眼看出来吗?你可能会惊讶地发现 'A' < 'a'。3因此,通常最好不要对字符串使用大于或小于运算符。
以下是一个变量部分的示例,展示了如何使用这些变量。
correct: guess === 3
nighttime: hour >= 18
--
主持人向后靠在椅子上,咧嘴一笑。
布尔变量有自己独立的一套运算符。
!,“非” 将真值变为假,反之亦然。&&,“和”
仅当两侧都为真时,结果为真。||,“或”
当一侧或两侧为真时,结果为真。
用括号澄清表达式|Clarifying Expressions With Parentheses
表达式常常很复杂。例如,在一个简单的角色扮演场景中,你可能决定一个手持锤子的角色造成力量 * 2 + 4 的伤害。但如果力量是 12,这个表达式是得出 28(12 乘以 2,再加 4)还是 72(2 加 4,再乘以 12)?
你可能记得数学课上学过数学运算符有优先级规则;具体来说,乘法在加法之前进行。但你很可能从未学过布尔逻辑的规则——例如,!true || false 会得出什么结果?4——即使你知道这些规则,在复杂表达式中正确应用它们也可能很棘手。
在这些情况下,你可以使用括号来帮助表达式更易于理解,甚至可以覆盖正常的运算顺序。(力量 * 2) + 4 清楚地表明了表达式将如何被求值——如果你确实希望上面的答案是 72,你可以通过写成 力量 * (2 + 4) 来指定。
求值仅发生一次|Evaluation Only Happens Once
关于将变量设置为表达式,需要记住的一个重要点是,求值只发生一次,即在你设置变量的时候。想象一下这个场景:
- 在一个段落中,你将变量
牙齿打颤设置为温度 < 0。 - 在后续段落中,主角进入室内并设置温度:
温度 + 20。
变量现在不一致了:牙齿打颤为真,但温度高于 0。避免此问题的最佳方法是避免让一个变量完全从另一个变量派生。如果牙齿打颤这个变量所做的只是反映温度是否大于 0,那么你就不需要一个单独的名为牙齿打颤的变量。更好的用法是设置感冒: 温度 < 0 && !穿着夹克,以反映主角因未穿夹克在室外而感冒了。他们随后可能会进入室内或穿上夹克,但显然这些变化都不会影响主角已经感冒的事实。
表达式可用于插入语句中|Expressions Can Be Used in Inserts
在插入中,表达式可以替代值使用。例如,以下段落:
目标: '另一个段落'
--
{embed passage: 目标}
将显示名为“另一个段落”的段落内的内容。请注意,这种用法与将变量名放在引号内不同,Chapbook 会将引号内的内容视为字符串。也就是说,这个段落:
目标: '另一个段落'
--
{embed passage: '目标'}
会显示文字“目标”,而非变量值。这当然可能造成混淆。最简单的记忆规则是:单引号或双引号始终用于包裹字符串。如果某个内容没有引号包裹,它就会被求值。
正如标题所示,插入可以使用整个表达式而不仅仅是将变量作为值。例如:
宠物类型: '猫'
活动: '走路'
--
{embed passage: 猫 + 走路}
将显示段落内容为“猫走路”。
1. 变量名中可以使用非拉丁字符,例如sabiduría或мудрость,但请注意,不完全支持 Unicode 标准的旧版网页浏览器——实际上是指如今使用率极低的旧版 Internet Explorer——可能会因此产生严重混淆。(王洛木:真的还有人在用 IE 上网冲浪么……) ↩
2. SugarCube 故事格式推广了这一做法,并且事实上确实会在玩家导航到另一个段落后丢弃以下划线开头的变量。(王洛木:也就是临时变量。) ↩
3. 字符串中字符排序的最终依据是 Unicode 标准。字符通过其 Unicode 码点进行比较;数值更高的码点意味着一个字符大于另一个字符。 ↩
4. 如果你好奇的话,!true || false 会得出 false。“非”运算符的优先级高于“或”运算符。 ↩