Archive

Archive for October, 2010

rScript now supports Visual Basic and runtime instancing

October 18, 2010 8 comments

I made a lot of progress today with the rScripting engine, much more progress than I had anticipated actually.

The Script engine now instances objects into a wrapped class that provides methods for invoking the scripts methods and accessing their properties. The instancing occurs by using a new ScriptFactory class; the factory will instance the script into the wrapper class which has been called a ScriptObject.

Aside form adding runtime support for scripts, I also fully implemented the .NET Visual Basic 3.5 compiler, providing support for users who want to write scripts via the VB language. I’m currently using the C# 4.0 language compiler with the engine, and wasn’t sure what the latest version of the VB compiler was. I looked around on MSDN and found references to 3.5 which sounds about right, so that’s the currently supported version in the engine.

I also wrote several example scripts for developers to see how the engine can be used. The example implements the compiler and compiles the scripts without any issues.
I also wrote two example compiler classes that are included. At the moment they just wrap the C# and VB compilers in them, but the idea behind it is to demonstrate how you can provide scripting support to your own language compiler of choice (provided it’s .NET) due to rScript providing a way for you to wrap your custom compiler in a Compiler class that can be used by the Compiler Engine.

The following example demonstrates how to implement the rScripting engine into your existing .NET projects. The example instances the engine, defines the compiler to use, then compiles the scripts. Note that the VB example needs to change the ScriptExtension property due to the engine defaulting to .cs

//Instance the rScripting compiler.
CompileEngine compiler = new CompileEngine();
            
//Set the compiler to use the built in C# compiler.
compiler.Compiler = "C#";

//Compile the the Examples TestScript.cs file
//Compiler will check the root directory since a 
//
different source repository was not supplied. Boolean compiledSuccess = compiler.Compile();

Implementing a Visual Basic version of the scripting engine is just as easy. The example is shown in C# but the engine can be wrote in Visual Basic. Once I get VB re-installed I will demonstrate the engine using VB itself rather than showing C# code using a VB script engine.

//Instance the rScripting compiler.
CompileEngine compiler = new CompileEngine();
            
//Set the compiler to use the built in C# compiler.
compiler.Compiler = "VB";
compiler.ScriptExtension = ".vb";

//Compile the the Examples TestScript.cs file
//Compiler will check the root directory since a different 
//
source repository was not supplied. Boolean compiledSuccess = compiler.Compile();

Next I will demonstrate how to access a compiled script, instance it and invoke a method. In this example, the TestScript contains a method called ‘CreateFile’

//Instance the rScript Script Factory. This is used to
//
generate Script Objects that provide //runtime access to the scripts,
//their methods and their properties.
ScriptFactory factory = new ScriptFactory(compiler.CompiledAssembly); //Creates a Instance of the TestScript, wraps it in a
//ScriptObject Type that provides //helpers methods for accessing properties and invoking methods.
ScriptObject obj = factory.GetScript("TestScript"); //Invoke the CreateFile method found inside
//out TestScript.cs file.
obj.InvokeMethod("CreateFile");

Lastly the C# TestScript file and the VB TestScript files

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestNamespace
{
    public class TestScript
    {
        public void CreateFile()
        {
            System.IO.File.Create(System.IO.Path.Combine(
Environment.CurrentDirectory, "TestCSharp.txt")); } } }
Public Class TestScript
    Public Sub CreateFile()
        System.IO.File.Create(System.IO.Path.Combine(
System.Environment.CurrentDirectory, "TestVB.txt")) End Sub End Class

With how I wrote rScript, you can add scripting support to any of your .NET applications regardless of language. If you want to use IronRuby or IronPython, implement a wrapper class using ICompiler and you can easily implement scripts for your app with the ability to quickly access their methods and properties.

I’m planning on adding Ruby/Python support at a later date, but for now I’m going to setup a Codeplex site and release rScripting 1.0 with just C# and VB support. I will also provide a complete set of documentation on the site for how to use the engine in your applications. Hopefully I can get this all setup and published by the end of the week.

Categories: Programming

Proper .NET Script Engine…Finally

October 17, 2010 Leave a comment

Over the last two years, I’ve wrote several itterations of a Managed scripting solution for the .NET Framework, beginning with DotScript, then I built Managed Scripting, a more robust and simplified version of DotScript. It didn’t take off very well and I assume more or less because I didn’t really go around advertising it much.

After the lack of interest in the previous two script engines, I decided that I might receive more interest in the product if I wrote it for the XNA Framework, and so I migrated Managed Scripting into another product called BlitScript which died off due to my lack of knowledge with the XNA Framework and how it uses Components. After spending time messing with various game engine’s and frameworks over the last week, I decided I wanted to get back to the things I enjoy the most, and that’s utilities development. Since I had simi-finished three scripting engine’s in the past and a fully functional one within the Mud Designer project I decided I’d go ahead and focus on a complete script engine solution. More or less to see if I’d do anything differently this time around from my past learning experiences.

I created rScript (temporary name), and had it put together in just a couple hours tonight. The Scripting Engine is more of a Compiler Engine at the moment, with a complete C# Raw Compiler implemented as well as a Interface for allowing custom compilers from 3rd party being wrote and used with it. It works pretty good at the moment and can be used in .NET applications that want to add some extensibility to their software. Assuming you have a .cs file in your applications root directory, you can use the following code to compile the file.

static void Main(string[] args)
{
    rScripting.CompileEngine com = new rScripting.CompileEngine();
            
    com.Compiler = "C#";
    com.Compile();
}

Pretty simple and straight forward, the engine will automatically check for .cs files and compile them. If you want to use a custom file extension or change the path to your script files, you can do so as well.

The engine also supports the creation of custom compilers provided they implement the ICompiler interface. Below shows a application using it.

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RuntimeExample
{
    public class SampleCompiler : rScripting.ICompiler
    {/// <summary>
        /// The location where the Script files are stored. rScript will compile them within that directory.
        /// </summary>
        public String ScriptRepository { get; set; }

        /// <summary>
        /// The file extension used for the script files.
        /// </summary>
        public String ScriptExtension { get; set; }

        /// <summary>
        /// Provides a collection of Assemblies that the compiler will add to its reference list.
        /// </summary>
        public List<String> AssemblyReferences { get; set; }

        public System.CodeDom.Compiler.CompilerResults Results { get; set; }
        
        public String[] Source { get; set; }

        public Boolean Compile(System.CodeDom.Compiler.CompilerParameters param)
        {
            Source = new string[] {
                "namespace RuntimeExample { public class MyClass {} }"
            };

            Microsoft.CSharp.CSharpCodeProvider code = new Microsoft.CSharp.CSharpCodeProvider();
            Results = code.CompileAssemblyFromSource(param, Source);

            if (Results.Errors.HasErrors)
                return false;
            else
                return true ;
        }
    }
}

While the example implements the CSharpCodeProvider to do the actual compiling, you can write your own compilers and perform the compiling from within your ICompiler class, providing support to your 3rd party users for scripting with your custom compiler.

The example demonstrates hard-coded source code, but your ICompiler implemented class can pull source from either the user during your applications run-time or via source code files.

Next on the agenda, run-time script instancing, method invoking and property access.

Manufacturing Objects

October 16, 2010 Leave a comment

I managed to get a primitive manufacture class wrote. A structure can have Unit classes dropped onto it within the designer, and during run-time the manufacture class will see what units are assigned to this structure and will be able to present a list of them to the UI for the user to select. I was attempting to store the objects in a List<T> but ran into a issue of my version of Unity not supporting Generic Collections I guess. I checked their site out and saw that they had recently released Unity 3D 3.0 with a huge amount of new features, one being the support of .NET 3.5 which is a huge plus.

Once it’s finished downloading and installed, I’ll migrate my project over to it and button up on my manufacture class, and look into generating game objects during runtime, allowing Unit creation to be finished.

On a side note, I wrote a quick little function in my manufacture class that lets me pull properties dynamically via reflection. Using reflection isn’t something new to me, as Mud Designer relies heavily on it, but it’s neat that I can create a BaseUnit type and allow others to extend off it, and get their properties dynamically within the game.

object GetProperty(object obj, string field)
    {
        FieldInfo info = obj.GetType().GetField(field);
        if (info != null)
            return info.GetValue(obj);
        else
            return "Failed to get property";
    }

RTS Development using Unity3D

October 16, 2010 2 comments

I spent some time back in September working on a RTS skeleton, just a barebones minimum RTS style game. I had a scrolling camera, with auto-height adjustment depending on the elevation of terrain the camera was currently over, along with proper collision detection and object selection. I ended up pausing from the project, as it was a collaboration project, with myself and a few other people planning on working on it together. The team needed more time to prepare for it, so I spent my time focused on Mud Designer and my wedding.

Things have calmed down now, and the main point of contact for the team looking to work with me on a 3D RTS game has resumed discussions with me regarding the project, so I thought I’d use this blog as an output to my thoughts and progress made. Not so much content related to the game, but rather how I achieved certain tasks that I was attempting to get working.

The first order of business for this morning was looking at what I had already developed. I had a working camera, and object selecting was implemented, so the next step would be creating units.
I figured the best solution would first create the units, then work on writing a manufacturing class that would perform the actual unit creation during run-time.

The Unit creation went pretty quickly, I created a BaseUnit class that all Units will inherit from. This way, as designers want new Unit Types (Marines, Monsters, etc.) they can create an extended class, edit a couple minor things (such as 3D model and sound) and the actual unit creation would be handled by the base type along with the AI.

I’ll probably end up moving the creation of the unit out of the BaseUnit class and into the Manufacturing class at some point, but for now this gets the job done.

It wasn’t difficult to get the unit created, albeit nothing is actually visually created on-screen. Basically I check for how much time has passed, and when the BaseUnit.ManufacturingTime has passed, the unit is flagged as created, at which point the user will have access to them.

//How long in seconds it takes to manufacture this unit.
    public int ManufactureTime = 15;
    private float manufactureStartTime;
    private float currentTick;
    private bool manufacturingCompleted = false;

    // Use this for initialization
    void Start () {
        manufactureStartTime = Time.time;   
        currentTick = manufactureStartTime;
    }
 
   // Update is called once per frame
    void Update () {
        float manufactureTick = Time.time – manufactureStartTime;

        if (!manufacturingCompleted)
        {
            if ((manufactureTick >= ManufactureTime) && (!manufacturingCompleted))
            {
                manufacturingCompleted = true;
                print("Manufacturing completed.");
            }
            else if ((int)currentTick < (int)manufactureTick)
            {
                print ("Unit Manufacturing in process…");
                currentTick = manufactureTick;
            }
        }
    }

The next order of business is to create the manufacturing class itself. I’ll probably move this code into that class, but for now this works out alright.

Bubble Breaker – Day 1

October 16, 2010 Leave a comment

Tonight I began seriously working on my first XNA game, a simple bubble breaking game. The concept behind it? Click the bubble on the screen to pop them.

I really should have learned how to manually draw primitives in XNA, but I ended up using a snippet from someone else that works very nicely.
I have a primitive Circle class that performs the actual bubble rendering, drawing the vertices out on the graphics device. I also have a Bubble class that wraps the Circle rendering into a nice package that will ultimately support selection and deletion (for popping).

Tonight I got a basic bubble field created. It’s broken into “Grid Slots”, allowing me to easily find what grid the mouse is over and deleting the bubble in that grid. Tomorrow I’ll work on the selection & deletion code.

Categories: Programming