单人游戏引擎应如何有力地拒绝无效数据?


11

在单人游戏中,当尝试使用外部脚本中指定的组件构建实体时,您认为在其中一个组件格式不正确时会发生什么更可取:

  • 引擎是否应该跳过该组件,而仅使用编写良好的组件让实体生活在游戏世界中?
  • 还是如果其中一个组件的格式不正确,它是否根本不应该将该实体添加到整个世界?

请注意,我不是在谈论记录错误-不用说-只是关于实体应该发生什么。


我们是在谈论单人游戏还是多人游戏?
o0'。

@Lohoris单人游戏。
Paul Manta

2
正如大多数答案已经提到的那样,您的听众是谁?您是在制作可修改的游戏,还是出于内部开发目的而谈论?
四分

@Tetrad我希望游戏尽可能对modder友好。
保罗·曼塔

Answers:


11

如果您在谈论一款可修改的游戏,那么您可能希望遵循上述建议之一。但是,如果您担心会遇到自己的错误,那就不要这样做。我已经成为失败的拥护者。如果这是创建的错误,并且必须在释放之前解决,则应使该错误显而易见。Wiki页面底部的链接文章很好地说明了为什么快速失败是件好事,以及什么时候应该使用,不应该使用它。


2
我认为这是一个很好的二分法,可以区分用户错误和开发人员错误。出于完全相同的原因,编译器错误通常很容易修复,但是运行时/语义错误才是恶魔,这是有道理的。
2011年

如果游戏开始后引擎提供了一种修改实体的方法,则您至少应给自己一个在失败之前修复错误的机会。
Blecki 2011年

7

用户和开发人员之间的区别在游戏开发中并不总是很清楚。像“快速失败”这样的标准编程技术并不总是有优势的,尤其是随着团队规模的扩大。

例如,也许您的技术美术师为目标轮廓固定了着色器-打破了后备,比如说,它仅在SM4系统上加载,而他并没有注意到,因为他拥有一流的系统。这导致某些动画无法加载。这些动画由您的战斗设计师编写的特定咒语引用。最终,您的关卡设计师试图将这些生成物放置在适当的位置,并且所有生成物都能够施放该咒语-但现在她无法将其中任何一个放置在世界上,因为它们的咒语无效,因为效果没有这是无效的,因为着色器将不会加载,因为设计人员总是拥有最差的计算机。

因此,您的演示在2PM之前还没有准备好,您的投资者想知道为什么您甚至无法在游戏中遇到一个敌人,而您的项目却被关闭了。

或者,您选择记录失败但继续尝试的选项,并且游戏正常进行,除了没有出现一些敌人的咒语效果-但投资者无论如何都不知道应该看起来像什么,所以他们不注意。

因此,我几乎总是提倡第一种选择-产生尽可能多的实体。在某些情况下会出现快速失败的情况-例如,除非应由能够进行构建的人员(例如,程序员和技术生产人员)对数据进行编辑,并且始终在加载时对其进行100%检查,或者您完全确定负责该操作的人员问题是使用编辑器的人-但那不是通常的情况,并且本身就需要很多技术基础架构,您可能不准备投资。


1
我想认为您提出的方案可以通过良好的源代码控制系统来预防。在您的情况下,艺术家已经“破坏了构建”。使用损坏的着色器的其他任何人都应该能够将着色器回滚到以前的版本,直到问题解决为止。
约翰·麦克唐纳

1
@John虽然必须有良好的源代码控制,有时必须进行回滚才能将项目的其余部分恢复到工作状态,直到本地解决故障为止,但它很少用作预防机制,因此不应作为依赖机制。

@John:在大型项目中,构建可能需要几个小时(或一整天)。因此,您实际上需要采用两种方法-您不仅需要源代码控制,还需要二进制控制,因此非程序员可以回滚到整个先前的构建。但是,当然,这有其自身的风险和成本,因为现在您正在针对其他过时的内容开发新的内容,而这些可执行文件可能还存在其他错误。而且,即使找到合适的版本回滚可能也要花费30分钟以上的时间-如果您的设计人员都必须停下来半个小时并弄弄这些版本,那将会浪费大量的钱。

@Joe Wreschnig:很有道理。因此,我想必须要指出的一点是,快速失败不再是一种资产。无论是使用人员的类型,还是在一定规模的项目上。我想应该由团队中的人来决定什么对他们有用。
约翰·麦当劳

2
我不确定快速的硬性失败是否真的是资产,这正是问题所在。即使是一个人的“团队”,也许我也不想处理着色器代码,因为我确实必须完成此级别。当然,可以编写良好的错误处理并记录所有错误,但是与六个月前编写错误代码时相比,我几乎总是比现在更了解当前的重要意义。

1

用户应该能够预览他将要导入的实体,并事先知道是否存在错误。

您应该以某种方式决定哪些错误应该是致命的,以防止将其添加到游戏中,并且可以将其作为警告予以消除。

当然,如果由于某种原因导入的实体可能以某种方式能够不可逆地更改保存游戏数据,则最好要求它无瑕疵。


0

我建议在开发中,它应该对无效数据产生干扰。即将所有内容记录在将被读取的位置。但是,如果您的引擎可以忽略并继续运行,则应这样做。你可以有这样的逻辑

void setValue(int value) {
    if (value < MIN_VALUE) {
       log(value + " is too low, using " + MIN_VALUE);
       value = MIN_VALUE;
    }
    if (value > MAX_VALUE) {
       log(value + " is too high, using " + MAX_VALUE);
       value = MAX_VALUE;
    }
}

即使在多人游戏中,这也是可以接受的,除非您假设一个人试图欺骗系统。

发行软件后,假设玩家不会读取这些日志,则您可能希望默认情况下关闭此日志记录。


假设日志不存在性能问题,则应继续在发行版本中进行登录,并将报告发送回开发团队。(当然,适当地通知玩家。)

您应该能够记录更简洁的日志以供发布。在开发中,您可能会变得更加冗长。
彼得·劳瑞
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.