用于脚本的领域特定语言


12

众所周知,Lua和Python等语言的嵌入式解释器被广泛用于编写游戏逻辑脚本,但是我没有看到有关使用特定于领域的语言编写脚本的人们的大量信息,例如构建一些逻辑脚本“方言”。在游戏其余部分使用的语言之上,使用宏或流畅的编程等。

所以我的问题如下:

  • 您在现实游戏中看到过哪些此类DSL的示例?
  • 遇到什么问题?
  • 您会在其他情况下向其他游戏开发商推荐这种方法吗?
  • 您是否认为随着游戏开发向更易于元编程的语言(例如Boo)发展,这种情况变得越来越普遍?

为了回答现实世界中的DSL使用问题,《战地风云1942》使用了它们。尽管弹出了很多mod;从程序员(我)的角度来看,这太可怕了,我很快就失去了兴趣。
乔纳森·迪金森

Answers:


6

我的建议是“不要”。

我已经为游戏数据使用了特定于域的标记语言。真痛苦。我花了几天的时间来设计它,然后每两到一周我需要对其进行调整以添加更多功能。有一次,我意识到我需要自动生成一些游戏数据,最后我写了一个小程序,以标记语言解析输入文件,对其进行按摩,并以标记语言输出不同的文件。

老实说,我不知道我在想什么。如果我只是使用Lua,那么整个过程将变得更简单,更高效,更不易出错,并且耗时更少。

如果您在无法启动Lua环境的受限系统上工作,那么也许应该使用DSL,但要为痛苦做准备。否则,我坚信您应该只使用Lua。Lua最初被设计为一种简单的数据标记语言,但仍然非常有利于使用它,当(如果不是)您意识到自己需要更复杂的东西时,您就已经掌握了它。我目前所有的游戏开发工作都是在Lua上完成的,而我从来没有像现在这样效率高或容易出错。

我不能强烈推荐DSL。


嗯,为什么不呢?您刚刚使用过Lisp,我认为这将是一个更加愉快的体验。:)星际争霸II具有脚本语言Galaxy,这确实是针对非技术人员/女孩的领域特定语言。
jacmoe 2010年

3
Lisp不会比Lua或Python更像是DSL。这将是别人花了很长时间设计的一种完全形成的语言,您可以避免浪费时间。
coderanger

2

对于使用特定领域语言编写脚本的人,我还没有看到太多信息,例如,在游戏其余部分使用的语言之上,使用宏或流畅的编程等等,构建了一些逻辑脚本“方言”。

脚本语言在游戏中往往是昂贵的命题。即使是非常快的Lua,也仍然比本地代码慢很多。游戏团队通常只愿意承受重击,因为它为他们带来了两个非常大的收益:

  1. 无需重新编译和重新加载游戏即可更改脚本的功能。
  2. 非程序员编写脚本的能力。

不幸的是,DSL并不能为您提供。


我认为2)是一条红鲱鱼。对于任何足够有趣的脚本,非程序员都将需要比它更有价值的手持或调试帮助。那里有优秀的程序员设计师,他们不需要帮助,但是您不能在普通的关卡设计师的桌子上拍Lua For Dummies,并期望他们能从中获得乐趣。
tenpn

我同意。我认为#2在实践中效果不佳,但是我已经看到这被用作整合脚本语言的表面原因。
优厚

有很多具有良好游戏想法的人可以编写Lua脚本,但是我永远都不相信malloc / sprintf /他们不得不选择数据结构等任何地方。这实际上就是#2的含义-“不良的程序员能够造成最少的损害并仍然完成工作的能力。”

它们可能不会通过脚本导致内存泄漏,但是不良的程序员仍然可以编写错误的,无法维护的缓慢代码。不好的程序员不应该被允许在您的游戏附近。聘请具有成熟脚本编写经验的设计师,您会没事的。
tenpn 2011年

2

我很好奇您的问题仅限于内部 DSL,因为我宁愿提倡使用外部 DSL,以便能够在运行时加载脚本,尤其是允许非开发人员在DSL中编写游戏逻辑。

例如,我当前的项目是使用一个(现在)简单的外部DSL来指定游戏逻辑的一部分,该逻辑允许游戏设计师在没有开发人员干预的情况下进行平衡测试。

当然,您需要编写一个解析器。为此,我认为最推荐的工具是ANTLR,它针对多种语言。在我的项目中,尽管我们使用jParsec(我们的后端是Java,还有其他语言的变体)来进行解析器组合器路由,但由于它与BNF的紧密联系,这很好,但可能记录的文献较少。


2

我的建议是:

但前提是您有用途。

如果您要自己内部使用,则无需创建DSL。

Galaxy是Startcraft II编辑器使用的脚本语言。这是特定领域语言的典型示例。

它针对的是游戏设计师而不是程序员:

Timer - Start Raise Lava Timer as a One Shot timer that will expire in 20.0 Game Time seconds
Variable - Set Raise Lava Timer = (Last started timer)
Timer - Create a timer window for (Last started timer), with the title "Lava will raise in: ", using Remaining time (initially Visible)
Variable - Set Lava Timer Window = (Last created timer window)
Timer - Show (Last created timer window) for (All players)
Variable - Set Lava Death? = false

示例教程

Lisp是用于创建领域特定语言的理想语言,但是当然还有其他选择。像布

这样,您的设计师/修改者不必学习编程,即使只是Lua,它仍在编程。

编辑:让我补充一点,DSL可以用脚本语言实现-它与不使用脚本语言同义。特别是如果您使用的是Lisp或类似的语言,因为它非常适合创建特定领域的语言。



0

可以说UnrealScript是DSL。尽管我认为可以使游戏脚本语言甚至更“特定于域”,但似乎可以完成工作。如果有特定于领域的内容可以从语言更改中受益,我会建议使用DSL-我在这方面有一些想法,但是目前还没有完全形成的想法。

您是否认为随着游戏开发向更易于元编程的语言(例如Boo)发展,这种情况变得越来越普遍?

但是,我认为没有一种支持语言的相当新的引擎可以证明游戏开发朝着特定方向发展。还很早


0

如果您真正需要的是通用编程语言,那么几乎可以肯定,自己滚动是一个错误。如果您的语言似乎需要变量,表达式求值,循环,条件,类,函数等,那么最好使用Lua,Lisp,Python,JavaScript等已知语言。[Unreal放弃了它们。]

但是,如果您需要的主要是定义数据;也许是声明性的而不是命令性的;可能定义状态和规则(例如GDL);并且不需要GP语言能很好地完成大部分工作,然后考虑使用DSL。

但是要当心:创建语言和编译器可能会非常困难,并且以前的经验会对您有很大帮助。我会建议基于EBNF语法(另一个DSL)的PEG解析器(本身是DSL),如果问得太大,最好不要尝试。

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.