Data structures RPG对话引擎/结构

Data structures RPG对话引擎/结构,data-structures,Data Structures,我一直对RPG(角色扮演游戏)中涉及的数据结构感兴趣。特别是,我对对话和基于事件的行动感到好奇 例如:如果我在游戏中的x点接近NPC,带着项目y和任务z,我将如何计算NPC需要说什么?分支对话和响应玩家输入似乎与定义脚本一样简单,用户输入会导致脚本读取器跳转到脚本中的特定行,该行有一组相应的响应行(很像选择自己的冒险) 然而,将逻辑与玩家是否拥有某些物品和完成某些任务联系起来,似乎真的破坏了这种基于脚本的模型 我正在寻找如何处理所有这些对话和逻辑的想法(不一定是编程语言示例),并将其分离出来,这

我一直对RPG(角色扮演游戏)中涉及的数据结构感兴趣。特别是,我对对话和基于事件的行动感到好奇

例如:如果我在游戏中的x点接近NPC,带着项目y和任务z,我将如何计算NPC需要说什么?分支对话和响应玩家输入似乎与定义脚本一样简单,用户输入会导致脚本读取器跳转到脚本中的特定行,该行有一组相应的响应行(很像选择自己的冒险)

然而,将逻辑与玩家是否拥有某些物品和完成某些任务联系起来,似乎真的破坏了这种基于脚本的模型

我正在寻找如何处理所有这些对话和逻辑的想法(不一定是编程语言示例),并将其分离出来,这样就可以很容易地添加新的分支内容,而不必钻研太多代码


这确实是一个悬而未决的问题。我不相信有一个单一的解决方案,但最好能提出一些想法。与其说我是程序员,不如说我是一名设计师,我总是对内容和代码的分离方式感兴趣。

我敢说,大多数现代游戏(无论是RPG、动作游戏,还是基本纸牌/棋盘游戏以外的任何游戏)通常由几个组件组成:显示引擎、核心数据结构,以及通常的辅助脚本引擎。Lua就是一个很受欢迎的例子(也许现在仍然如此;我已经好几年没有和游戏开发者谈过了)

您正在谈论的决策(事件、对话分支等)通常由辅助脚本引擎处理,因为脚本语言更灵活,并且通常更易于游戏设计者使用。同样,大多数真实的故事驱动或游戏驱动逻辑实际上都会发生在这里,在这里可以相对容易地交换和更改。(至少,与运行所有代码的完整构建相比!)


主要游戏引擎将与世界(几何体等)相关的数据结构、与玩家和所需其他参与者相关的数据结构以及驱动遭遇战的脚本结合起来,并使用所有这些来显示最终的集成环境。

您当然可以使用脚本语言来处理对话。基本上,脚本可能如下所示:

ShowMessage("Hello " + hero.name + ", how can I help you?")
choices = { "Open the door for me", "Tell me about yourself", "Nevermind" }
chosen = ShowChoices(choices)
if chosen == 0
    if hero.inventory["gold key"] > 0
        ShowMessage("You have the key! I'll open the door for you!")
        isGateOpen = true
    else
        ShowMessage("I'm sorry, but you need the gold key")
    end if
else if chosen == 1
    if isGateOpen
        ShowMessage("I'm the gate keeper, and the gate is open")
    else
        ShowMessage("I'm the gate keeper and you need gold key to pass")
    end if
else
    ShowMessage("Okay, tell me if you need anything")
end if
这对大多数游戏来说都很好。脚本语言可以很简单,您可以编写更复杂的逻辑分支。您的引擎将具有对脚本语言公开的世界的一些表示。在这个例子中,这意味着英雄的名字和清单中的物品,但是你可以公开任何你喜欢的东西。您还可以定义脚本可以调用的函数,以执行诸如显示消息或播放某种声音效果之类的操作。您需要跟踪脚本之间共享的一些全局数据,例如门是否打开或任务是否完成(可能作为地图和任务类的一部分)

然而,在某些游戏中,脚本编写可能会变得单调乏味,特别是如果对话更具动态性,并且取决于许多条件(例如,角色情绪和统计数据、npc知识、天气、项目等),那么可以将对话树存储为某种格式,以便轻松指定前提条件和结果。我不知道这是不是一种方法,但我曾经问过一个问题。我发现这种方法对我的游戏是有效的(其中对话严重依赖于许多因素)。特别是,将来我可以很容易地制作一个简单的对话编辑器,它不需要太多脚本,并且允许您使用图形用户界面简单地定义对话和分支

例如:如果我在 游戏中的x点,带有项目y和 任务z,我该怎么做 人大需要说什么?分支 对话与回应 输入似乎和拥有一个 定义的脚本和用户输入原因 脚本读取器将跳转到 脚本中的特定行 有一组相应的响应 线条(很像一个选择你自己的 (冒险)

然而,将逻辑联系起来,以确定 玩家拥有某些物品,并且 完成了某些任务似乎很重要 真的毁了这个基于脚本的模型

一点也不。您只需将条件因素考虑到数据中

假设你有你的对话列表,编号为1到400,或者类似的,选择你自己的冒险书例子。我假设每个对话可能包括NPC所说的文本,然后是玩家可以得到的回答列表

因此,下一步是在其中添加条件,只需将条件附加到每个响应。最简单的方法是使用脚本语言来实现这一点,因此您有一段简短的代码,如果玩家可以使用此响应,则返回True,否则返回False

例如(XML格式,但可以是任何格式)


你能冒险出去杀我10只老鼠吗?
真的!没有什么比杀死你的害虫更好的了。十鼠
我要把尸首带给你。
不,兄弟!如果你只剩下十只老鼠,我的剑就是你的了,
但事实并非如此。
在脚本语言中,您需要一个“rats\u left\u In\u world”函数,您可以调用该函数来检索有问题的值

如果没有脚本语言怎么办?好吧,你可以让程序员为你的对话中的每种情况编写一个单独的条件——有点乏味,如果你的对话是事先写的,那么就不那么困难了。然后在对话脚本中按名称引用一个条件

更高级的方案仍然不需要脚本语言,可能会对每个条件使用标记,如下所示:

<response>
  <condition type='min_level' value='50'/>
  Sadly squire, my time is too valuable for the likes of thee. Get thyself a
  farm hand or stable boy to do thy bidding!
</response>

可悲的乡绅,我的时间对你这样的人来说太宝贵了。给自己找一个
农场工人或马童
<response>
  <condition type='min_level' value='50'/>
  Sadly squire, my time is too valuable for the likes of thee. Get thyself a
  farm hand or stable boy to do thy bidding!
</response>