节点(Nodes):故事的骨架
在互动故事中,节点 (Node) 是构成故事的基本单位。您可以将每个节点想象成故事中的一个场景、一个段落、一个事件,甚至是玩家做出选择后的一个结果。所有这些节点共同构成了故事的完整流程。在 common/data.json 中,所有的节点都定义在 "nodes" 对象内部。
3.1 nodes 对象的结构
"nodes" 对象是一个键值对的集合,其中每个键(Key)都是一个唯一的节点ID,而每个值(Value)则是一个描述该节点属性的对象。节点ID是您在故事中引用该节点的唯一标识符,因此它必须是独一无二的。
{
"nodes": {
"node_id_1": {
"text": "这是第一个节点的内容。"
},
"node_id_2": {
"text": "这是第二个节点的内容。"
}
}
}3.2 节点的基本属性
每个节点对象都可以包含以下核心属性:
"title"(可选,字符串):节点的标题。这个标题会显示在顶栏,帮助玩家了解当前所处的场景或事件。"text"(必填,字符串):节点的主要文本内容。这是故事叙述的核心部分。
至关重要的是,所有交互元素,如链接,都必须通过特殊的文本标记(如
{0},{1})嵌入到"text"中才能显示。
"links"(可选,数组):一个包含链接对象的数组。每个链接对象代表一个玩家可以选择的选项。"actions"(可选,数组):一个包含动作对象的数组。这些动作会在玩家进入该节点时自动执行,用于改变游戏状态、触发事件等。
以下是一个包含这些基本属性的节点示例:
"start_node": {
"title": "宁静的早晨",
"text": "你从睡梦中醒来,阳光透过窗帘洒在你的脸上。这是一个新的开始。\n\n你决定 {0} 还是 {1}?",
"links": [
{ "text": "起床", "target": "wake_up_scene" },
{ "text": "再睡一会儿", "target": "sleep_more_scene" }
],
"actions": [
{ "type": "set", "target": "var.player.energy", "value": 100 },
{ "type": "toast", "message": "新的一天开始了!" }
]
}3.3 链接(Links):故事的岔路口
"links" 属性定义了玩家从当前节点可以做出的选择。每个链接都是一个对象,至少包含 "text" 和 "target" 两个属性:
"text"(必填,字符串):显示给玩家的选项文本。"target"(必填,字符串):当玩家选择此链接时,故事将跳转到的目标节点的ID。
除了 "text" 和 "target",链接还可以包含以下可选属性:
"condition"(可选,字符串):一个条件表达式。如果提供了"condition",则只有当该条件满足时,此链接才可以被点击(否则会变灰)。"actions"(可选,数组):一个包含动作对象的数组。这些动作会在玩家点击此链接时,且在跳转到"target"节点之前执行。"variants"(可选,数组):一个包含变体链接的数组。它允许同一个链接根据不同的条件,显示不同的文本、跳转到不同的目标或执行不同的动作。"random"(可选,数组):一个包含随机选项的数组。如果一个链接包含"random"属性,点击它会随机决定跳转的目标和执行的动作。
以下是包含可选属性的链接示例:
"links": [
{ "text": "向东走", "target": "forest_east" },
{
"text": "打开宝箱",
"target": "treasure_chest_open",
"condition": "var.player.hasKey"
},
{
"text": "捡起地上的金币",
"target": "path_continue",
"actions": [{ "type": "add", "target": "var.player.gold", "value": 10 }]
}
]再次强调: 无论您定义了多少链接,都必须在节点的
"text"属性中使用{0},{1},{2}... 这样的标记,才能让它们在屏幕上显示出来。
3.4 节点ID的命名规范
虽然节点ID可以是任何唯一的字符串,但遵循一致的命名规范将极大地提高 data.json 的可读性和可维护性。建议采用以下策略:
- 描述性:ID应该能够简要地描述节点的内容或功能,例如
forest_path_crossroads。 - 小写和下划线:使用小写字母,并用下划线
_分隔单词,例如chapter_1_start。
3.5 节点间的跳转
故事的流程是通过节点间的跳转来实现的。除了玩家通过点击链接进行跳转外,还可以通过以下方式实现自动跳转:
动作中的
jump类型:在节点的"actions"数组中,可以定义一个"jump"类型的动作,使其在进入该节点时自动跳转到另一个节点。json"linear_path_node": { "text": "你别无选择,只能继续前进。", "actions": [ { "type": "jump", "target": "next_scene" } ] }监听器触发的跳转:更高级的跳转机制可以通过监听器实现。我们将在后续章节中详细介绍。
理解节点的定义和它们之间的连接方式是构建任何互动故事的基础。在下一章节中,我们将深入探讨 "text" 属性中使用的各种文本格式和标记。