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

我有一个用C#编写的小游戏。它使用数据库作为后端。它的 一个交易卡片游戏,并且我想将这些卡片的功能作为脚本来实现。

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

现在,为了使事物可维护/可修改,我希望将每张卡片的类作为数据库中的源代码,并在首次使用时进行基本编译。所以当我不得不添加/更换卡片时,我只需将其添加到数据库并告诉我的应用程序刷新,而不需要进行任何程序集部署(特别是因为我们将讨论每张卡片1个程序集,这意味着数百个程序集) 。

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

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

该语言是C#,但如果可以用任何.NET语言编写脚本,则额外奖励。

0
额外 编辑
意见: 1
@mattytommo不,没有剩下的东西,它处于真正的早期阶段,基本上就像我上面概述的那样工作。今天,我会考虑Roslyn做C#编译: blogs.msdn.com/b/csharpfaq/archive/2011/10/19/… - 或者,使用Jint的JavaScript - jint.codeplex.com
额外 作者 Michael Stum,
这很有趣,我和一个朋友正在考虑用C#编写一个交易卡游戏,但是不要以为你还有这个源代码?对你如何处理这件事感兴趣。
额外 作者 mattytommo,
啊谢谢,但我更期待交易卡游戏本身的实现和你使用的结构,而不是脚本引擎。不管怎么说,还是要谢谢你 :)
额外 作者 mattytommo,

9 答案

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

实质上,他们需要以可能不可预知的方式与我的游戏状态进行交互。例如,一张牌可以有一条规则:“当这张牌进场时,除敌人被祝福之外,你的所有不死生物都会对飞行的敌人造成+3攻击。”由于交易卡游戏以回合为基础,GameState Manager将发起OnStageX事件并让卡片以卡片所需的任何方式修改其他卡片或GameState。

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

这就是为什么我希望保持“真正”的.NET语言,以便能够仅仅触发事件并让卡片以任何方式(在代码访问安全性范围内)操纵游戏状态。

0
额外
(不需要标记这个;虽然这应该是一个评论/回答更新,但是在这些选项之前已经盛行)
额外 作者 Will,

Oleg Shilo's C# Script solution (at The Code Project) really is a great introduction to providing script abilities in your application.

另一种方法是考虑专门为脚本编写的语言,例如 IronRuby ,< a href =“http://en.wikipedia.org/wiki/IronPython”rel =“noreferrer”> IronPython 或 Lua

IronPython和IronRuby今天都可用。

有关嵌入IronPython的指导阅读 如何通过10个简单步骤在现有应用程序中嵌入IronPython脚本支持

Lua is a scripting language commonly used in games. There is a Lua compiler for .NET, available from CodePlex -- http://www.codeplex.com/Nua

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

A different angle altogether is to try PowerShell. There are numerous examples of embedding PowerShell into an application -- here's a thorough project on the topic: Powershell Tunnel

0
额外
顺便说一下,我选择这个作为公认的答案,因为我想要在Python和IronPython上运行,所以IronPython方法最适合
额外 作者 Michael Stum,
LuaInterface是一个lua解释器,它也很棒。
额外 作者 RCIX,
我在09年11月在工作流系统中实现了C#Script。它为我们表现得非常好。
额外 作者 David Robbins,

您可能可以使用IronRuby。

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

如果你真的想在运行时编译,你可以使用CodeDOM,然后你可以使用反射来加载动态程序集。 可能有帮助的MSDN文章

0
额外

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

使用.NET的CodeDom,我们使用VB CodeDomProvider 编译脚本,但是如果你想支持3.5特性,你需要传递一个字典到“CompilerVersion”= “v3.5”给它的构造函数)。使用 CodeDomProvider.CompileAssemblyFromSource 方法编译它(您可以传递设置以强制它仅在内存中编译。

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

0
额外

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

0
额外
是。尽管Roslyn仍在使用,但 Mono.CSharp(NuGet上可用)包装所有相同的功能。
额外 作者 Eric Falsken,
添加更新以保持选项的相关性:.NET编译器平台(“Roslyn”)可用。所以它是所有其他人可行的替代方案。 github.com/dotnet/roslyn
额外 作者 Riv,
我相信这是指罗斯林? en.wikipedia.org/wiki/Microsoft_Roslyn
额外 作者 Stephen Kennedy,

如果你不想使用DLR,你可以使用Boo(有翻译),或者您可以考虑使用CodePlex上的Script.NET(S#)项目 。使用Boo解决方案,您可以选择编译后的脚本或使用解释器,Boo通过其开放式编译器体系结构提供了一种很好的脚本语言,具有灵活的语法和可扩展的语言。尽管Script.NET看起来不错,但您可以轻松扩展该语言以及其开源项目,并使用非常友好的Compiler Generator( Irony.net )。

0
额外

您可以使用任何DLR语言,这些语言提供了一种真正轻松托管自己的脚本平台的方法。但是,您不必为此使用脚本语言。您可以使用C#并使用C#代码提供程序进行编译。只要你将它加载到它自己的AppDomain中,你就可以加载和卸载它到你的内心。

0
额外

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

如果你想使用一些外部预装的Lua模块,我建议使用1.5.x版本的东西,而不是建立完全托管代码的2.x系列,并且不能公开必要的C API。

0
额外

I'm using LuaInterface1.3 + Lua 5.0 for a NET 1.1 application.

Boo的问题在于,每当您在运行时解析/编译/评估您的代码时,它会创建一组boo类,这样您就会得到内存泄漏。

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

到目前为止,我还没有把它放在PROD中,但似乎非常有前途。

I did have memory leaks issues in PROD using LuaInterface + Lua 5.0, therefore I used Lua 5.2 and linked directly into C# with DllImport. The memory leaks were inside the LuaInterface library.

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

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

0
额外