Game Development Community

dev|Pro Game Development Curriculum

Managed Scripting Post 2

by Johnathon · 07/02/2009 (6:29 pm) · 0 comments

Yesterday I demonstrated how to use the scripting engine to compile users scripts for use during your application/games runtime. Today I will show how to load the assembly during runtime, instance a script/class and invoke it's method.

First we will create an assembly that is stored on the local hard-drive. This assembly will later be loaded when our application/game is being loaded. This assembly could be created within your games script editor, and then loaded during the games runtime.

//Instance a method, property and class via the class generator
            ClassGenerator.MethodSetup method = new ClassGenerator.MethodSetup();
            ClassGenerator.PropertySetup property = new ClassGenerator.PropertySetup();
            ClassGenerator newClass = new ClassGenerator();

            //setup the options.
            property.Name = "Name";
            property.PropertyType = "string";

            method.Name = "GetName";
            method.ReturnType = "string";
            method.Code = new string[] { "return this.Name;" };

            newClass.ClassName = "Billy";
            newClass.Namespace = "Characters";
            newClass.AddProperty(property);
            newClass.AddMethod(method);
            
            //Create a script engine and compile it.
            ScriptingEngine engine = new ScriptingEngine();
            engine.CompileStyle = BaseCompiler.ScriptCompileStyle.CompileToAssembly;
            engine.OutputName = "E:\MyLibrary.dll";

            string code = newClass.CreateClass();
            engine.Compile(code);

The class generated in the above example is shown next.

namespace Characters
{
  public  class Billy
  {
     public string Name
     {
       get
       {
         return this._Name;
       }
       set
       {
         this._Name = value;
       }
     }
     private string _Name;

    public string GetName()
    {
            return this.Name;

    }
  }
}

Now when I go to my root folder on the E drive, there is a MyLibrary.dll file sitting there. Now for our next example, I will show how your game could load the assembly during runtime, and set the property 'Name' to a value, and then invoke the GetName() method to aquire the new name of the object.

//Instance a new script engine
            ScriptingEngine engine = new ScriptingEngine();

            //Load the assembly.
            engine.LoadAssembly("E:\MyLibrary.dll");

            //Instance the script for use. This places a copy of it within a ScriptObject class
            //which the script engine holds until you need to use it.
            engine.InstanceObject("Billy", "Characters", null);
            
            //Aquire the ScriptObject
            ScriptObject script = engine.GetObject("Billy");

            //Set the property to a value of our choosing.
            script.SetProperty("Name", "Billy Bob");

            //Invoke it's method and output it to the console
            object results = script.InvokeMethod("GetName", null);
            Console.WriteLine(results.ToString());

The output will read 'Billy Bob' in the console. The InvokeMethod() always returns an object, which you can use object.GetType() to discover what kind of type it is. For games I try not to return Types other than strings or bools, and you can control what kind of types are allowed within your scripts by checking during compiling.

if (method.ReturnType != "string" || method.ReturnType != "bool")
                return "The selected return type "" + method.ReturnType + "" is not supported.";

As work begins on the Torque X version, developers will be able to add these scripts to game components. So you can have something like a GameType that manages all of the different styles of game types like Death Match or capture the flag, and if a 3rd party user writes a script or series of scripts that inherit from GameType you can easily place that script during runtime within your games GameType component and allow the game to display the new game type in the games menus, and execute it's rules during gameplay.

Till my next post~