Why You Should Use C# For Your Scripting Language

October 29, 2009

I’ve used a lot of scripting languages over the years when developing games.  For my latest engine, I decided I’d use C# as the scripting language.  I’ve been amazed by how well C# works as a scripting language so I thought I’d share my experiences.  The technique I’m about to discuss gives game designers access to a fully-featured language and IDE with compile-time checking all while allowing run-time changes.  I use run-time compilation to achieve the flexibility of a scripting language combined with the power of a .NET language.

Advantages

There are a number of key advantages to using C# as a scripting language in your game engine.  I’ll list these first then describe how I achieve them.

  • Designers use Visual Studio. Most designers are stuck using notepad (or similar) when writing their scripts.  With my technique, designers can use Visual Studio, gaining the full power of the IDE.  Including:
    • Intellisense. Letting them know what functions exist on all of the objects you’ve exposed, as well as documentation you’ve provided in code.
    • Compilation. Designers can compile their scripts while making changes to catch any compile-time problems.
    • Full Debugging Support. Another area lacking in most scripting languages is the debugging support.  Designers have access to all of Visual Studios debugging functionality to help them find and fix issues with their code.
  • Run-Time Changes. Designers still have complete control to change their scripts at run-time.  Scripts can be reloaded automatically when files are changed, or (more likely) a “reset” button can be exposed in the game engine that allows them to reset the level and reload all scripts.
  • Compile scripts into the executable for release. You have the option to use the scripts compiled into the executable if you prefer, protecting your files.
  • Complete Access to game objects, or whatever you want designers to access. Designers are working in the same language you are developing in.  They have full access to the game objects or to a subset you decide on.  I use an interface and expose what I want them to use.
  • FAST Run-time performance. The C# code is compiled not interpreted meaning the run-time performance is as good as the rest of the engine.  The slight performance bottleneck of reflecting the function can be removed by compiling scripts into executable if required.
  • No Binding Required. Binding is automatic between the game engine and the script.  You don’t need to write any plumbing and exposing a new function is as easy as adding it to the engine.

How It Works

The setup is surprisingly easy, designers follow these steps and their up and running:

  1. Add the script file to the Visual Studio project (preferably in its own directory)
  2. Create an Init() function in the script class which will automatically be called by the engine
  3. Create callbacks for events and implement the game logic
  4. Run the game and make changes to scripts in real-time as needed

I use the run-time compilation functionality of the .NET framework to compile and run the code on- the-fly.  This has a small performance hit during compilation however the run-time performance is excellent.

Some Examples

Below are a few examples I put together today to show the power of the system.

The first script below creates an entity at the beginning of the game and then sets up a callback that will fire every 5 seconds.  The TestScript object’s lifetime is until the scripting system is reset allowing stateful object creation.

public class TestScript : BaseScript
{
    int team = 1;
    int xPos = 15;
    int yPos = 2;

    public void Init()
    {
        script.CreateEntity("Healer", team, xPos, yPos);
        script.CallEveryXSeconds(MyCallback, 5);
    }

    public void MyCallback()
    {
        script.CreateEntity("Tank", team, xPos, yPos++);
    }
}

The next script shows how simple customizing a game entity can be.  Whenever an effect is added or removed from a game entity, the following two functions are called allowing designers complete control over gameplay.  Notice the designer is given access only to what they need while still having complete control to change any settings or values of the entity.  An interface could be used to restrict what operations can be performed on entities as required.

class SpeedUpEffect
{
    public void AddEffect(GameEntity entity)
    {
        entity.Speed += 1;
    }

    public void RemoveEffect(GameEntity entity)
    {
        entity.Speed -= 1;
    }
}

Conclusion

As I said, I was amazed both at how simple all of this was to set up (only a few hours) and how powerful the system is.  If anyone is interested I’d be happy to share the source code for how I achieved this.  As I continue development of my engine I will be experimenting more with this scripting system and will release more information as I develop it.

  • Greg

    It is worth checking out V8, Google’s Javascript embeddable VM. It has nice native / script interface and the language is like dynamic C. http://code.google.com/p/v8/

    Is of the main reasons you are preferring C#, compatibility with XNA? That is great until you later want to port beyond the world of MS.

    I’m hoping there is value beyond runtime compilation and linkage. I recall Carmack years ago admitting that he’d written a embeddable C compiler for C scripts then realized he hadn’t achieved more than duplication with limited features.

  • http://www.doolwind.com Doolwind

    Thanks for the link Greg. I’m a big fan of Google’s new javascript vm.

    No, the main reason for using C# is because it’s a fully featured language with the .NET framework as support and automatic compatibility with any .NET language. I’m going to look into portability with MONO in the future.

    I agree simply having C or C++ would not suit as a scripting language, however C# is at a good level for game designers to use.

  • Leader247

    I would like to look at your source code, I could learn a lot from it. Because I am developing a game engine.

  • http://www.gameblox.net Diego

    This came from heaven! I had this need to alter my XNA game in real time and coincidentally I was already looking into using a text file with C# code as “script” to do it. With your testimonial I will definitely try it.

    Please send me your source sample so I can start playing with it quicker. I’ll post here my experience ;)

  • Pingback: Using C# For a Commercial Game – Doolwind's Game Coding Blog

  • http://activeengine.wordpress.com David Robbins

    Just wanted to share something I’ve used in the past. CS Script is great platform for creating scripting features for your apps. It may not be germane to XNA, but it’s still a nice implementation.

    http://www.codeproject.com/KB/cs/cs-script_for_cp.aspx

    Enjoyed the post.

  • ProtheonX

    Man I wish I had thought of this at the start of my team’s current project. We are working with a short cycle of 4 months for our last project before we graduate.

    We chose to not use any scripting because we didn’t know if we would have the time to learn a scripting language like Lua or Python. Using C# would have been amazing.

    If you will I would love to see your source example. Great post.

  • http://www.andr0meda.com a0a

    We’ve actually done the same for a ps2 title ones, running a Java VM and coding gamelogic in java. Worked pretty well. Downsides were garbage collection thread which soaked quite some performance, and the issue of knowing Java to be able to script. Still. Strict language syntax checking by compiler beats the crap out of any debug cycle.

  • Hypnotron

    Hello,

    Thanks for writing this article. I’ve decided to go with c# scripting instead of lua. If you’re still sending out the sample source to people requesting, please send me a copy!

    Thanks again.

  • Neil

    Hi,

    I find this t be very interesting as i am currently reseraching on how to use C# for scripting. Currently i have developed a custom GUI that does does all the basics but obviously nothing near as good as Visual Studio,

    if your still offering the source i would love to have a look at it.

    Thanks!

  • Brian

    Yes, interesting article!, but could u be more specific or give more inputs/information for this scripting developing how you did and thinking etc. That would be very interesting and great.

    Thanks brian

  • Ryan

    I was wondering if I could get the source code. I’m trying to implement scripts in my system primarily for in engine cut scenes and I’m trying to find the best possible method to go about it. This seems like it would be perfect!

  • Michael Pitkin

    Hi I was wondering if this would be useful to create like a C# Command Prompt as I think it would be useful for creating a special debugging console that attaches to the application as well as a standalone console for just doing stuff.

    If it might be useful, could you possibly send the source code please. I don’t know if you’ll be able to find my e-mail address so if you can’t just let me know and I’ll send you it.

    Thanks, Michael.

  • Mario Mars

    This is exactly what I was looking forward, and just found it at first google search.

    Really thanks, I would also like to have a look at your source code.

  • http://brandste.squarespace.com/ Billy

    I am also interested in seeing the source code. I’ve written entire games before in c# that call into a c++ engine. It works great.

  • Jardeth56

    Hi
    I know its been a long time since you posted this but would it be posable to get a copy of ur souce code

  • Pingback: Separation of Gameplay – Doolwind's Game Coding Blog

  • Meh

    I gave up on Unity when I could not refer to an object instance directly, I had to ‘find’ it first or keep my own array of everything in the scene
    Recently someone on a forum suggested that a utility script written in C could provide this functionality – true?

  • http://doolwind.myopenid.com/ Doolwind

    Can you email me (alistair@doolwind.com) with the specifics, this should be relatively easy to do. There are a bunch of ways to reference an object instance directly depending on your situation.

  • http://doolwind.myopenid.com/ Doolwind

    Can you email me (alistair@doolwind.com) with the specifics, this should be relatively easy to do. There are a bunch of ways to reference an object instance directly depending on your situation.

  • http://doolwind.myopenid.com/ Doolwind

    Can you email me (alistair@doolwind.com) with the specifics, this should be relatively easy to do. There are a bunch of ways to reference an object instance directly depending on your situation.

  • meh

    Email sent-Cheers
    I found that there was no way to refer to a specific object at run time without keeping your own dynamic array of everything that exists.
    http://forum.unity3d.com/threads/79169-Syntax-for-a-game-object-component-variable-on-a-transform-in-an-FBX-hierarchy
    http://forum.unity3d.com/threads/63548-Activating-and-deactivating-children-of-an-object
    http://forum.unity3d.com/threads/42105-Instantiate-a-prefab-amp-access-child
    http://forum.unity3d.com/threads/24646-Finding-Child-Object/page2

    “Regarding the navigation of transform hierarchies: It seems unfortunate that most of those posts you linked only show you how to use the Find() methods. You actually *can* walk through the hierarchy manually, but because of the C-like languages Unity uses the syntax is quite convoluted. Actually, c-like languages make working with all of the GameObject/Component/Transform paradigm convoluted. Such is life in game engine world. Actually, if you really want to address transforms using “root/childA/childC/childX” syntax (instead of root.getcomponentsinchildren and whatnot endlessly), you could probably write a couple of utility functions that allow you to do that.”

  • Meh

    No response?

  • Kebab

    I want the source code pleeeasee <3