首页 文章

向.NET应用程序添加脚本功能

提问于
浏览
64

我有一个用C#编写的小游戏 . 它使用数据库作为后端 . 这是trading card game,我想将卡的功能实现为脚本 .

我的意思是我基本上有一个接口, ICard ,卡类实现( public class Card056 : ICard )并包含游戏调用的函数 .

现在,为了使事物可维护/可修改,我想让每张卡的类作为数据库中的源代码,并在第一次使用时实际编译它 . 因此,当我必须添加/更换卡时,我只需将其添加到数据库并告诉我的应用程序刷新,而无需任何组件部署(特别是因为我们将讨论每个卡的1个组件,这意味着数百个组件) .

那可能吗?从源文件注册一个类,然后实例化它,等等 .

ICard Cards[current] = new MyGame.CardLibrary.Card056();
Cards[current].OnEnterPlay(ref currentGameState);

如果可以用任何.NET语言编写脚本,那么语言就是C#但是额外的奖励 .

9 回答

  • 8

    Oleg Shilo's C# Script solution (at The Code Project)真的是在应用程序中提供脚本功能的一个很好的介绍 .

    另一种方法是考虑专门为脚本编写的语言,例如IronRubyIronPythonLua .

    IronPython和IronRuby今天都可以使用 .

    有关嵌入IronPython的指南,请阅读How to embed IronPython script support in your existing app in 10 easy steps .

    Lua是一种常用于游戏的脚本语言 . 有一个用于.NET的Lua编译器,可从CodePlex获得 - http://www.codeplex.com/Nua

    如果您想了解在.NET中构建编译器,那么该代码库是一个很好的读物 .

    一个不同的角度是尝试PowerShell . 有很多将PowerShell嵌入到应用程序中的示例 - 这是关于该主题的详尽项目:Powershell Tunnel

  • 6

    您可能可以使用IronRuby .

    否则我建议您有一个放置预编译程序集的目录 . 然后,您可以在DB中为程序集和类提供引用,并使用反射在运行时加载正确的程序集 .

    如果你真的想在运行时编译你可以使用CodeDOM,那么你可以使用反射来加载动态程序集 . MSDN article which might help .

  • 5

    您可以使用任何DLR语言,它们提供了一种非常容易托管您自己的脚本平台的方法 . 但是,您不必使用脚本语言 . 您可以使用C#并使用C#代码提供程序对其进行编译 . 只要您在自己的AppDomain中加载它,您就可以加载和卸载它的内容 .

  • 38

    如果您不想使用DLR,您可以use Boo (which has an interpreter)或者您可以考虑使用the Script.NET (S#) project on CodePlex . 使用Boo解决方案,您可以在编译脚本之间进行选择或使用解释器,Boo通过其开放式编译器架构提供了一种很好的脚本语言,具有灵活的语法和可扩展的语言 . 尽管如此,Script.NET看起来也很不错,你可以轻松地扩展该语言以及它的开源项目并使用非常友好的编译器生成器(Irony.net) .

  • 6

    我建议使用LuaInterface,因为它已经完全实现了Lua,看起来Nua不完整,可能没有实现一些非常有用的功能(协同程序等) .

    如果你想使用一些外部预先打包的Lua模块,我建议使用1.5.x的内容,而不是构建完全托管代码的2.x系列,并且不能公开必要的C API .

  • 5

    是的,我考虑过这一点,但我很快发现另一个特定于域的语言(DSL)会有点过分 .

    从本质上讲,他们需要以可能无法预测的方式与我的游戏状态进行交互 . 例如,一张牌可以有一条规则“当这张牌进入游戏时,你的所有亡灵爪牙都会对飞行的敌人获得3次攻击,除非敌人受到祝福” . 由于交易卡游戏是基于交易的,GameState Manager将触发OnStageX事件并让卡以任何方式修改其他卡或GameState .

    如果我尝试创建DSL,我必须实现一个相当大的功能集,并可能不断更新它,这将维护工作转移到另一个部分而不实际删除它 .

    这就是为什么我想继续使用“真正的”.NET语言,基本上只能触发事件并让卡以任何方式操纵游戏状态(在代码访问安全性的限制范围内) .

  • 5

    我正在使用LuaInterface1.3 Lua 5.0作为.NET 1.1应用程序 .

    Boo的问题是每次你解析/编译/评估你的代码飞,它创建了一组boo类,所以你会得到内存泄漏 .

    另一方面Lua不这样做,所以它非常稳定并且工作得非常好(我可以将对象从C#传递给Lua并向后传递) .

    到目前为止,我还没有把它放在PROD中,但看起来很有希望 .

    I did have memory leaks issues in PROD using LuaInterface + Lua 5.0 ,因此我使用Lua 5.2并直接链接到C#和DllImport . The memory leaks were inside the LuaInterface library.

    Lua 5.2:来自http://luabinaries.sourceforge.nethttp://sourceforge.net/projects/luabinaries/files/5.2/Windows%20Libraries/Dynamic/lua-5.2_Win32_dll7_lib.zip/download

    一旦我这样做,我的所有内存泄漏都消失了,应用程序非常稳定 .

  • 4

    我部门销售的主要应用程序非常类似于提供客户端自定义(这意味着我无法发布任何来源) . 我们有一个加载动态VB.NET脚本的C#应用程序(尽管可以轻松支持任何.NET语言 - 选择VB是因为定制团队来自ASP背景) .

    使用.NET的CodeDom,我们使用VB CodeDomProvider 从数据库编译脚本(如果你想支持将函数"CompilerVersion" = "v3.5"传递给它的构造函数所需的3.5特性,那么它很可能默认为.NET 2) . 使用 CodeDomProvider.CompileAssemblyFromSource 方法编译它(您可以传递设置以强制它仅在内存中编译 .

    这将导致内存中有数百个程序集,但您可以将所有动态类的代码放在一个程序集中,并在任何更改时重新编译整个程序集 . 这样做的好处是,您可以在测试时使用PDB添加一个标记以在磁盘上进行编译,从而允许您通过动态代码进行调试 .

  • 3

    下一个版本的.NET(5.0?)已经有很多关于打开“编译器即服务”的讨论,这将使得直接脚本评估成为可能 .

相关问题