将Lua纳入C ++游戏的利弊是什么?


37

我有一本C ++游戏编程书,其中有Lua部分。我已经开始阅读Lua一节,这听起来很有趣,但是我无法确定在我的C ++游戏中使用Lua的优缺点。我目前能想到的唯一好处是,您可以通过Lua进行一些编码更新,而无需重新编译。除此之外,我什么都没想到。那么将Lua添加到C ++游戏中的利弊是什么?

示例将不胜感激。




同意这与那些问题相似,但是重要的是“缺点”。
乔纳森·迪金森

@JonathanDickinson答案虽然没有指向那个方向...但是它们的陈述基本上与链接的问题相同。
bummzack 2011年

Answers:


33

我目前能想到的唯一好处是,您可以通过Lua进行一些编码更新,而无需重新编译。

不要轻易地贬低它的效用。除非您不执行重新编译步骤,否则您将永远无法理解自己的生产力。

“流”是一个相当容易理解的心理学概念,当涉及到的工作。流程就是那种当您专注于一项活动时,当您几乎不加思索地分析和解决问题时所得到的感觉。当您“流动”时,您的工作效率最高。

编译时间搞砸了所有这些。如果您在两次测试之间进行10秒钟的编译,则很难停留在流程中。

在开发游戏玩法时,通常会遇到“紧密循环”。您有一个想法,您编写了一个测试代码以查看它是否有效,然后尝试一下。如果它不起作用,请对其进行修改,然后重试。“代码测试”时间对于保持流程非常重要。使其尽可能小至关重要。

Lua(或任何嵌入式脚本语言)允许您做的是测试更改,而不仅仅是在不进行“编译”的情况下,而是在游戏中进行测试。根据您构建游戏的方式,您可以运行将使用新脚本重新启动游戏的命令,而无需停止和重新加载数据等。您不仅不必重新编译,也不必重新运行。

在适当的发动机支持下,执行此操作的能力可以大大提高生产率。


脚本编写的另一个主要好处是不必关心。如果您花了很长时间编写C ++,那么您花了多少时间花费分钟的时间就会感到惊讶。删除内存的位置。在哪里得到释放。即使您shared_ptr随处使用,输入所有这些变量类型名称的操作也会使您减速。

在动态类型的脚本语言中,您不必关心。范围很简单。函数是一流的对象;您不必手动构建函子。做一些事情是如此容易

如果您不是训练有素的程序员,那么现在确实有负面影响。在Lua中使用全局变量非常容易(尽管有很多方法可以防止这种情况)。不关心意味着您编码时会很草率。

但是话又说回来,很马虎可以有好处


Lua的另一个优点是,它提供了一种很好的数据描述语言。就像JSON只是一个生成并返回数组/表的JavaScript文件一样,您可以制作返回表的Lua脚本。

这对于配置文件很有用;Lua的表格格式比.ini格式要好得多。格式仍然很干净,紧凑和可扩展。

哦,它仍然是Lua脚本,因此它可以执行实际的逻辑。不利之处是……这是一个Lua脚本,因此它可以执行实际的逻辑。这在游戏中可能是灾难性的,因为用户可能会开始搞砸事情。

但是实际上,这很容易解决。Lua是为嵌入而设计的,这意味着隔离实际上非常容易。实际上,默认情况下,新的Lua状态不提供任何内容。您实际上必须做一些事情来公开最基本的标准Lua库。文件访问,游戏状态访问等都是选择加入,而不是选择退出。每个Lua状态彼此独立。用于AI脚本的Lua状态不必是用于配置文件的Lua状态。

实际上,我有一些代码可以允许您注册许多Lua标准库,但是会删除所有文件IO。归根结底,基于Lua脚本的配置文件可能会发生的最糟糕的情况是,由于运行不足,导致游戏运行时立即崩溃。而且由于您不是手动共享这些配置文件,所以对于黑客来说并没有太大的乐趣。


我会说所有脚本语言的最大缺点是调试。大多数脚本语言没有调试器,Lua也不例外。Lua确实拥有构建调试工具所需的所有工具。但是它实际上没有内置调试器。你必须把一个放在一起。这将需要合理的工作量。

或者,您可以使用“ printf调试”进行调试。这实际上取决于您编写了多少Lua代码。


1
流动并不总是一件好事;自动执行操作有时意味着不花时间浏览其他设计方案。
lurscher 2011年

10
@lurscher:设计是您坐下来编写代码之前要做的。在开始编写,测试和调试代码之前,您应该已经解决了所有这些设计选择。
Nicol Bolas

23

我在哪里工作:

优点:

  • 迭代时间的改善。我们的游戏设置为轮询主机文件系统中的更改并自动“吸取”更改。(它们仅在下次打开文件时生效,但实际上,这是一个重大改进:重新加载级别,新的lua更改将立即生效。)
  • 控制台集成。任何调试功能都可以通过REPL连接到传统Quake风格的控制台。对于内部版本,我们甚至可以将lua REPL挂接到一个讲远程登录的简单套接字上,并且我们可以对游戏进行网络控制。
  • 减少api降低学习曲线。非技术艺术家和设计师可以参加某些通常是程序员遇到的瓶颈的任务。
  • 专业的静态代码分析。解析luac -l字节码的输出并查看字节码以进行一些分析很容易;解析大多数lua源文件也非常容易,尤其是在您具有编码约定的情况下。我们可以执行当地惯例。您也可以在此处查看metalua,以获取更多功能。
  • 错误处理。如果我们的API没有崩溃,即使lua做了一些愚蠢的事情,我们也可以捕获它并使用恢复lua_pcall
  • 简单的API扩展。为Lua <-> C ++ API编写新函数并不难。也有一些软件包可以帮助实现此目的。
  • 简单来源。进行更改以例如避免在lua解释器中使用浮点数学运算(在某些嵌入式平台上很重要)或针对特定系统进行优化并不难!
  • 元表。这些真棒。在运行时做有趣事情的潜力很大。我们有实际上没有内容的“虚拟表”,并在游戏的C ++端对复杂的数据结构进行了查找。
  • 协程。能够停止和继续执行例如AI行为脚本的功能令人惊叹。不过,在lua脚本编写者方面需要更多的知识-我们仍在研究如何使引擎更加“安全”。

缺点:

  • 不可预测的GC。调整我们step应该做什么,每场比赛都会发生巨大变化。在每帧全GC(较小的工作集)下,某些方法会更好地工作。有些人在很少通过的情况下表现更好,而很少。请注意,在更新的lua版本和某些修补程序中,还有很多工作要做(您不应该害怕使用它!)
  • 更高的开销。为了避免每个表项的内存开销,我们将大量数据结构保留在C端。C ++,C和汇编语言通常会产生更快的代码。因此,对于性能要求不高的游戏引擎,保留了90%的资源,有时我们确实将东西从lua迁移到C(反之亦然)。
  • 碎片化。也许是小型存储系统上最大的问题。我们通常使用小对象池和完全独立的大对象堆来存储lua。我们将完整的GC通行证放在游戏的战略要点中。lua_State在某些情况下,我们卸载脚本或完全丢弃脚本。而且有时候我们还是有问题。调整小型对象池的大小(为简化和降低开销,它们是固定的)和lua专用大型对象堆的大小​​可能很麻烦。但是在大于约4MB的系统上,我们还没有为专门的堆和池而烦恼。
  • 缺乏类型安全性。如果您没有构建好的静态代码分析工具集,那么您将大量使用运行时错误检查(也许使用__index__newindex)。最好在编译时捕获错误。您可以采取多种措施来减轻这种情况。

Lua极力推荐,只要愿意就可以使用它!您可能还想看看Squirrel,尽管我相信它的用户群较小。


我希望我可以多次投票。非常全面,非常有见地,结构清晰。+1
Koarl 2012年

5

实际上有3大优势:

这些因素使您作为游戏开发人员能够启用可加快开发速度并提高游戏质量的功能。

例如:

  • 您只需通过从文件或网络套接字更新游戏就可以更改游戏逻辑。
  • 您可以允许用户创建自己的脚本(适用于漫游器或Mod)
  • 您的游戏设计师和美术师将能够在不使用编译工具集的情况下更新和测试游戏的各个部分。
  • 每次更改一些脚本时,您都不必重新编译。
  • 如果您更改平台/引擎/语言,则无需重写整个游戏。

1
“如果您更改平台/引擎/语言,则无需重写整个游戏。” 除非您从Lua更改为其他语言。而且,如果您要用Lua编写“整个游戏”,那么如果您更改引擎,则该更改必须向Lua公开(或者您需要在Lua和引擎之间进行某种抽象以隐藏细节)。所以我看不到Lua在这些情况下如何提供帮助。
Nicol Bolas

3

从我的经验来看,归结为一点。

优点

  • 初始集成真的很容易。存在一些工具来帮助生成绑定,但是绑定机制非常简单,您可以立即编写具有自己的自定义功能的自己的版本
  • 您可以在游戏逻辑上获得更快的迭代速度(假设您实现了运行时重载)
  • 您将获得一个自由的环境进行试验:您将尝试更多的事情,因为这样做的开销会大大降低
  • 熟悉的语法:尽管有种种差异,但作为C程序员,您很难在几个小时内适应它
  • 更好地将游戏逻辑与“引擎”分开:您的引擎成为服务提供商,必须向Lua客户端公开一个不错的API。语言障碍使您考虑更多,而不仅仅是进入那里并摆弄成员变量

缺点

  • Lua内存管理不是游戏的理想选择。你应付它,你不喜欢它
  • Lua调试开箱即用。您必须努力改善体验
  • 将数据保存在Lua中意味着您需要在Lua中进行调试:从C进行检查最初会很棘手
  • Lua对脚语法有很多了解,就像默认情况下所有变量都是全局变量一样
  • 和其他语言一样,Lua是一种编程语言。不要指望非程序员会因为删除了编译器而神奇地变成了程序员
  • 擅长集成和支持Lua是一项很大的工作。不要指望它会立即开箱即用。可以假设您实际上必须在几款游戏中分摊这笔费用

最终的,个人的结论:如果您要开发一款尺寸合适的游戏,并且还没有脚本语言,请使用Lua。这是值得的。


1

Garry的Mod是使用Lua和C ++的游戏的一个示例。他们将Lua用于所有mod,这使人们更容易制作它们。C ++用于所有内部构件。我唯一想到的缺点是Lua不如C ++快。

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.