Managed Scripting Engine Beta
by Johnathon · 11/12/2009 (9:56 pm) · 4 comments
Managed Scripting Beta 1 is finally available for download, providing support for source compiling, batch script compiling and runtime code generating with the help of its code building classes. The scripts can be compiled during your applications runtime, and it provides instancing of classes, method invoking and property access during runtime as well.
What does this have to do with Garage Games? This was implemented to allow Torque X users to have a scripting engine that they can build scripts and just execute their game without needing to do any pre-compiling within visual studio. The engine works how the Torque Game Engine works, compiling the scripts during the apps startup, with the exception that the compiled scripts can be held in memory during runtime and dropped after the game is closed.
At the moment the engine can compile any script passed to it, but the Code Building classes will provide support for XNA based projects (allowing for GameComponent and DrawableGameComponent objects to be created during runtime), when it is released, which will allow developers to develop visual editors for their script editors similar to that of Unreal's Kismet.
The engine is easily implemented into existing projects, with the following example showing the engine compiling the scripts during it's startup, holding the compiled scripts in memory, and instancing the class.
The following example shows the engine compiling source code provided to it via a text box.
and this is the code contained within the text box
The end result is a message box being displayed showing 'Billy Bob'.
Next I have an example of how the engine would be used with a Torque X project. The Game scans a 'scripts' directory for all of it's scripts, adds them to an array and passes the array of scripts to the compiler for compiling. Once compiled, each Type within the newly compiled assembly is scanned to see if it inherits from GameComponent, and if it does it is added to the games component list. You can also check if it inherits from DrawableGameComponent or any of the Torque X components if you want. This is supported in Beta 1. Generating dynamic classes that inherit from GameComponent and DrawableGameComponent during runtime however is not until Beta 1.1.
With that example, each one of the scripts that where compiled and inherited from GameComponent will be included in your games components list and act like any other game component. This makes it nice for quickly exiting your game and making a change to the script file, then re-starting your game.
At the moment the engine allows for compiling scripts into memory or locally to an assembly file. If developers compile their scripts into memory, then they can easily add the functionality for re-compiling and re-instancing scripts during runtime, allowing you to edit your scripts while your game runs, re-compile during your games runtime and see it's re-compiled results. If the developer chooses to compile the scripts to a local assembly, then the game will need to be shut down before re-compiling the assembly, as the assembly is placed within the same domain as the game, and thus can't be over-wrote until the domain is released (game shut down). Beta 1.1 should have assemblies being generated within their own domains, allowing for runtime re-compiling with local assemblies as well, however local assemblies shouldn't really be needed with game development.
Managed Scripting is available and runs on Windows via .NET 3.5 and on Linux with Mono.NET 2.4. I have an XBOX360 and Zune version of the engine under development and they will be ready when the next version is completed over the next month or so, and this will allow you to develop your Torque X projects using the scripting engine, and deploy your game to both Windows and Xbox platforms with no re-scripting needed, however XBox games will need their scripts pre-compiled into a local assembly using the scripting engines compiler. At which point the assembly is loaded during runtime on the xbox and treated as it would normally be on windows. It just wont be able to compile the scripts during runtime due to Compact Framework limitations. Documentation will be provided on the 360 and XNA part of the engine when they are released.
What does this have to do with Garage Games? This was implemented to allow Torque X users to have a scripting engine that they can build scripts and just execute their game without needing to do any pre-compiling within visual studio. The engine works how the Torque Game Engine works, compiling the scripts during the apps startup, with the exception that the compiled scripts can be held in memory during runtime and dropped after the game is closed.
At the moment the engine can compile any script passed to it, but the Code Building classes will provide support for XNA based projects (allowing for GameComponent and DrawableGameComponent objects to be created during runtime), when it is released, which will allow developers to develop visual editors for their script editors similar to that of Unreal's Kismet.
The engine is easily implemented into existing projects, with the following example showing the engine compiling the scripts during it's startup, holding the compiled scripts in memory, and instancing the class.
The following example shows the engine compiling source code provided to it via a text box.
ScriptingEngine engine = new ScriptingEngine();
engine.CompileStyle = ScriptCompileStyle.CompileToMemory;
string results = engine.Compile(txtSource.Text);
engine.InstanceObject("MyScript", "MyNamespace", null);
ScriptObject obj = engine.GetObject("MyScript");
//Invoke the method and convert
//the returning value into a string
string name = (string)obj.InvokeMethod("GetMyName");
MessageBox.Show(name);and this is the code contained within the text box
namespace MyNamespace
{
public class MyScript
{
public string GetMyName()
{
return "Billy Bob";
}
}
}The end result is a message box being displayed showing 'Billy Bob'.
Next I have an example of how the engine would be used with a Torque X project. The Game scans a 'scripts' directory for all of it's scripts, adds them to an array and passes the array of scripts to the compiler for compiling. Once compiled, each Type within the newly compiled assembly is scanned to see if it inherits from GameComponent, and if it does it is added to the games component list. You can also check if it inherits from DrawableGameComponent or any of the Torque X components if you want. This is supported in Beta 1. Generating dynamic classes that inherit from GameComponent and DrawableGameComponent during runtime however is not until Beta 1.1.
ScriptingEngine engine = new ScriptingEngine();
string[] files = System.IO.Directory.GetFiles("Content/Scripts", "*.cs");
string results = engine.Compile(files);
Type[] types = engine.GetAssembly.GetTypes();
foreach (Type t in types)
{
if (t.BaseType.Name == "GameComponent")
{
engine.InstanceObject(t, new object[] { this });
ManagedScripting.ScriptObject obj = engine.GetObject(t.Name);
GameComponent gc = (GameComponent)obj.Instance;
this.Components.Add(gc);
}
}With that example, each one of the scripts that where compiled and inherited from GameComponent will be included in your games components list and act like any other game component. This makes it nice for quickly exiting your game and making a change to the script file, then re-starting your game.
At the moment the engine allows for compiling scripts into memory or locally to an assembly file. If developers compile their scripts into memory, then they can easily add the functionality for re-compiling and re-instancing scripts during runtime, allowing you to edit your scripts while your game runs, re-compile during your games runtime and see it's re-compiled results. If the developer chooses to compile the scripts to a local assembly, then the game will need to be shut down before re-compiling the assembly, as the assembly is placed within the same domain as the game, and thus can't be over-wrote until the domain is released (game shut down). Beta 1.1 should have assemblies being generated within their own domains, allowing for runtime re-compiling with local assemblies as well, however local assemblies shouldn't really be needed with game development.
Managed Scripting is available and runs on Windows via .NET 3.5 and on Linux with Mono.NET 2.4. I have an XBOX360 and Zune version of the engine under development and they will be ready when the next version is completed over the next month or so, and this will allow you to develop your Torque X projects using the scripting engine, and deploy your game to both Windows and Xbox platforms with no re-scripting needed, however XBox games will need their scripts pre-compiled into a local assembly using the scripting engines compiler. At which point the assembly is loaded during runtime on the xbox and treated as it would normally be on windows. It just wont be able to compile the scripts during runtime due to Compact Framework limitations. Documentation will be provided on the 360 and XNA part of the engine when they are released.
About the author
#2
Thanks for the comment, I was worried I spent my time working on it and no one found interest in it lol
11/15/2009 (1:00 am)
The idea behind it is for Torque X users who have to compile all their scripts within C# can now omit using C# and just write their scripts like they would with Torque Game Engine, launching the game and letting the game compile it's scripts and execute them. It also allows for making changes to scripts with out the need to re-start the game, if the functionality is wrote properly into the game.Thanks for the comment, I was worried I spent my time working on it and no one found interest in it lol
#3
Normally, what I would like to do with an scripting engine is to define the behaviors of my objects, but in your description this usage is not explained. I figure that I could easily achieve what I said above by creating a class with my desired behavior inside a method, but please give us a sample project with some "real world" usage of it - I mean, create a small game that uses it in a meaningful way.
You also talked about adding GameComponents to Torque X, but the main component mechanism of Torque X 2D (I'm not sure about Torque X 3D) is to extend "TorqueComponent", which works differently and (from what I know) cannot be added or removed from an object at runtime (I know, this limitation sucks!). This way, it wont matter if I can create a Component at runtime, because I wont be able to use it.
In your examples, although you create objects at runtime, you end up calling something like "engine.GetObject(t.Name);" which got me confused for a while, but then I saw that you normally get a list of all the types you have compiled and only then you create them.
I'm already getting it, but those who are not in desperate need of scripting like me (yet) could use more pretty pictures and videos to get invested XD
11/17/2009 (7:46 am)
Johnathon, your scripting engine seems really cool but I'm still not totally understanding how to use it in a game. Normally, what I would like to do with an scripting engine is to define the behaviors of my objects, but in your description this usage is not explained. I figure that I could easily achieve what I said above by creating a class with my desired behavior inside a method, but please give us a sample project with some "real world" usage of it - I mean, create a small game that uses it in a meaningful way.
You also talked about adding GameComponents to Torque X, but the main component mechanism of Torque X 2D (I'm not sure about Torque X 3D) is to extend "TorqueComponent", which works differently and (from what I know) cannot be added or removed from an object at runtime (I know, this limitation sucks!). This way, it wont matter if I can create a Component at runtime, because I wont be able to use it.
In your examples, although you create objects at runtime, you end up calling something like "engine.GetObject(t.Name);" which got me confused for a while, but then I saw that you normally get a list of all the types you have compiled and only then you create them.
I'm already getting it, but those who are not in desperate need of scripting like me (yet) could use more pretty pictures and videos to get invested XD
#4
It is viewable HERE if you would like to review it some.
As for the TorqueComponent, can you add or remove a TorqueComponent from the Components list during runtime? I'm not sure how that works as I don't own Torque X at the moment. If it supports it, then you can use this in the same manor as you would an XNA GameComponent.
Lastly, the copy you downloaded from my site doesn't have XNA support built into it. You will see the difference between the XNA supported version and the Windows version of the engine when you see my examples. I uploaded a very beta version of the XNA version of the script engine tonight on my codeplex site, and there is a link to it in the example blog post I shared in this reply.
Thansk for the comments.
11/18/2009 (1:52 am)
Diego, I'm not very good at the game side of things, as I struggle with the math part of it all, but I was able to put together a small sample showing how the engine changes the games window title during runtime, and demonstrates the ability to recompile your game scripts and see the changes on the fly.It is viewable HERE if you would like to review it some.
As for the TorqueComponent, can you add or remove a TorqueComponent from the Components list during runtime? I'm not sure how that works as I don't own Torque X at the moment. If it supports it, then you can use this in the same manor as you would an XNA GameComponent.
Lastly, the copy you downloaded from my site doesn't have XNA support built into it. You will see the difference between the XNA supported version and the Windows version of the engine when you see my examples. I uploaded a very beta version of the XNA version of the script engine tonight on my codeplex site, and there is a link to it in the example blog post I shared in this reply.
Thansk for the comments.

Torque Owner Scott R. Plaumann
Ok, so you define and assign engine, files and results. You build an array of types and loop through types checking if it's a GameComponent. If it is...
I read through it but I don't think I'm up to speed with run-time dynamic compilation. Well written article even still.