Saturday, April 19, 2014

Interpretted Scripting in Unity

I spent a little while earlier this year trying to devise a good way to handle attack scripting in Phantom Mansion in an extensible, designer-friendly, mod-friendly way.

I decided to look into interpreting scripts at run-time. This would put a little bit more faith in the people who will use this system than I generally like to, but I think it compares favorably with the other options, where I either have to anticipate everything this tool might be used for or be on-call 24/7 for the lifetime of the project implementing tiny changes because a designer wanted, say, a slightly different targeting behavior on an attack.

I made some progress on this recently. There's a wonderful library called Jurassic that allows a C# program to compile and execute Javascript code at run-time. You can expose C# functions and objects to Javascript with a little boilerplate code, which isn't too much work, and this keeps it properly encapsulated.

Initialization looks like this:

 ScriptEngine engine; 

 engine = new ScriptEngine(); 

 engine.EnableExposedClrTypes = true; 

To register a function, the code looks like this:

 engine.SetGlobalFunction("SetState", new System.Action<string>(jsSetState)); 

 #region JS Functions 
      public void jsSetState(string newState) 
      { 
           state = newState; 
      } 
 #endregion  

The jsSetState function is a C# function that sets a C#-side member variable string called State. The engine.SetGlobalFunction call hooks that function to a JS-side function called SetState. We can call that function with Engine.Execute(); which executes an arbitrary string as Javascript code. This code will set the state variable to "This is the new state string."

 engine.Execute("SetState("This is the new state string.");"); 

There's still a lot of work to do on this system. Right now the extent of the supporting architecture for it is a very simple state machine setup, which is what I intend to base the attack system on, but it's very rudimentary right now. I need to write a lot more gameplay hooks, and probably do about seven polish passes to make this really usable. Unfortunately, all of those gameplay hooks are in a really grizzly part of the Phantom Mansion code that I'm never going to touch again unless I'm rewriting it, and rewriting the entire attack system of Phantom Mansion was a little beyond scope. This was, after all, primarily a research/experimentation project.

I think I've found something that can, one day, be the foundation of a really good attack scripting system for Phantom Mansion, but we've got a long road ahead of us, and I am very, very tired.

No comments:

Post a Comment