C# scripting (Roselyn) vs LUA vs IronPython - scripting with MonoGame

Apologies if this question is slightly off-topic :smiley:

I want to add scripting to my current project (for mods, quests, and custom levels), and after a quick research I narrowed down my options to LUA, C# scripting and IronPython.

I was hoping to get your opinions and personal experience of the choices, and which one I should go with…
I’m interested in the following aspects:

  1. Integration with MonoGame projects and / or content pipeline - any advantage / disadvantage to one of them here?
  2. Ability to execute untrusted user scripts without worrying about malicious codes - I know LUA inherently provide that, IronPython got restricted mode, can C# scripting par with them?
  3. How easy it is to integrate, how easy it is to provide an API (eg the host game to provide a set of API calls for the scripting to use.
  4. How much is it cross platform - less critical but still useful to know…

And in general your thoughts on them and if any of these ever gave you nightmares and I should avoid at all cost… They all look good on paper so I seek opinions based on actual experience :slight_smile:


1 Like

Advantage of C# scripting is that you could integrate your scripts into your visual studio project after game development state.

Is this for end users? You probably don’t want integration for content pipeline. Scripting is generally interpreted at runtime, ie you write API calls in your compiled program that can then run script text files in a certain directory etc.

If you want it so the scripts are compiled along in the content pipeline then C# is definitely the best way to go. Lua/IP probably will mean writing your own importer and processor.

I think it depends on your scripting implementation, if as you say you just expose an API of calls it should be relatively safe.

Again I think this is implementation based, either Lua/IP/C# won’t matter; in the end you are basically going to write a text parser.

Any scripts should really be cross platform, as mentioned above they are basically going to be text files interpreted by your game engine.

tldr; scripts are just going to essentially be flat text files that your game interprets.

p.s. if anyone can tell me the MD to make the numbers appear literal. (seems to interpret as a list and defaults to 1)

I am aware, but they are both for end users and myself (internal game stuff), and having the built-in game scripts managed by the content pipeline will be much more convenient, I imagine. (letting the Content manager load them for me, potential optimizations that MG team might implement, maybe some settings I can play with via the content manager, and having MG object wrapping them up and providing nice API). MG team did some pretty awesome job with the content management, and I want to take advantage of that wherever possible.

BTW you could say the same things about XML files (C# can easily load them from plain files in your game dir and on the paper there’s no justification of having them in the content pipeline) yet I found that using MG content for XMLs proved to be much more convenient and efficient in the long run.

Didn’t find any built-in support in C# scripting nor a ready third party lib that implement an importer for that. Did I miss something? :open_mouth: That’s part of the reason I asked, maybe someone knows a neat way to integrate that I missed or implemented his own code and willing to share.

Perhaps you didn’t understand what I meant by safe. I don’t care about cheating the game, I care about a user script installing malware on innocent player’s computers. And that’s very language dependent. For example, if I somehow integrated with and used Python 2 it would have been very hard to prevent users from accessing filesystem and doing nasty stuff, since Python 2 sandbox is known to be broken (as stated by Python dev team).

At the bottom line clearly there are solutions for everything, but keep in mind I’m trying to implement simple scripting support for a game, I don’t want to start spawning processes and VMs with different privileges and do crazy platform-specific stuff just to make sure the user scripts can’t access filesystem or install evil stuff on the unsuspecting player’s machine…

But if I chose LUA, for example, I know all of this isn’t a problem because LUA is built in a way that you choose which APIs and objects scripts can access. Its part of the language.

PS I also know there’s a thing called AppDomain I can use in C# but I’m not sure about integration with different scripting languages and how much extra work it will take to wrap scripting in (if possible).

I disagree. For example, if I use C# scripting I might be able to pass a whole C# object into the script and let the user play with it as-is, without writing any serializers etc (I don’t know if I really could, that’s why I’m asking). But maybe if I use LUA there is this awesome lib I’m not aware of that do that awesome thing that will totally change my life. That’s why I’m asking about personal experience with integration, not guessing around.

Also some scripting languages integration can be as easy as setting up a callback, while others might require to write bloated classes with crazy API and add long and useless config files or whatever.

And why would I write a text parser?? Part of the idea of using an existing scripting language instead of developing my own is that I don’t need to go through the hell of writing a text parers for a scripting language… I’ve been there. :joy:

Not true… IronPython for example is not supported on IOS (as far as I know, maybe it changed recently). at the moment it doesn’t bother me too much, but its still a factor I’m taking into consideration.

I hope I didn’t sound rude or anything in my response. I do appreciate your comment I just strongly disagree with most of it :slight_smile:

I have written that one a bit funny. I merely meant “C# scripting” as hard coding classes etc. as types in your game, therefore compiled (not by the pipeline though).

I have misjudged the scale of your request as well, I have answered on side of a lighter solution (ie parsing text files into basic commands). Seems you are going much larger with scripts as objects etc.

It’s an odd comparison but RunUO (a popular emulator/server for Ultima Online) was all C# based but I spent a fair bit of time with, each script/.cs file was usually an object or npc in game and worked well.

Sorry if I have just added more confusion :stuck_out_tongue:

Now I understand the context of your response and why I found it so strange :slight_smile:

This console project might be useful to you, but I don’t know how well it will work cross platform… I imagine iOS in particular would not be able to support runtime scripting due to limitations on reflection: https://github.com/discosultan/quake-console

Not exactly what I meant by scripting but looks like a very useful tool. I’ll check it out, thanks.

The quake console repository seem to have a interpreter for Roslyn and Python if your question was regarding integrations.

Also, this might be of interest to you if you’re considering LUA.

C# scripting is an actual thing now, in the 4.6 framework. https://blogs.msdn.microsoft.com/cdndevs/2015/12/01/adding-c-scripting-to-your-development-arsenal-part-1/

I’m going through the same decision process as you right now and am trying to decide between LUA and C# Scripting. So far, I’m leaning LUA.

I’m leaning towards LUA as well (check out the link @Olivierko posted), mainly because it feels the safest and I worked in the past with CPP and LUA and was quite happy with it. Second choice is C# scripting, IronPython seems to have too much noise with it, reading it’s tutorials and about restricted mode which I’ll need, it just feels less of a smooth integration. Also I think since LUA and C# are more common in gamedev it somehow make more sense to use one of them (even though I love Python).

What are the reasons for you to lean towards LUA if may I ask?

Moonsharp is at the top of my list if I end up going with LUA; it seems to have the best performance when inter-operating with .NET.

My main reason for favoring LUA right now is performance and the sandbox security. My game is multiplayer, with script running both on the server, and being send down to, and run on the client computers. I want to keep both the server and the client safe from malicious scripts.

I’m considering some game mechanics where players will actually write scripts in-game, to be executed on the server, so there are potential attack vectors coming from many directions.

Server side, there could potentially be several thousand calls per second in to scripted objects, so I need something with low overhead.

On the other hand, I really like the idea of being able to write scripts in C# and .NET, but the scripting part of it doesn’t seem to be well documented. Almost everything I can find makes it seem like it really isn’t geared for being used in my kind of scenario, so I’m worried about performance with it.

I still have a lot of engine code to write before I can bring in the scripting aspect, so I’m not in a rush to choose just yet. I need to do some bench-marking and other tests to see how the different libraries hold up to performance and security needs.

“LUA” is not an acronym. It’s “Lua” (portuguese word for Moon).