EzDev.org

moonsharp

moonsharp - An interpreter for the Lua language, written entirely in C# for the .NET, Mono, Xamarin and Unity3D platforms, including handy remote debugger facilities. MoonSharp


Passing a C# object into a lua function with moonsharp.

I'm having issues using Moonsharp in Unity3d. I'm trying to pass 'AppletMessage' objects:

[MoonSharpUserData]
public class AppletMessage {
    public string Name;
    public string[] Args;

    public AppletMessage(string _name, string[] _args) {
        Name = _name;
        Args = _args;
    }
}

into a function in lua and I'm not sure how to do that. What I'm currently doing is this:

//In a start function
UserData.RegisterType<AppletMessage>();

//Later on, after popping the latest message from a stack as 'LatestMessage'
result = applet.Call( applet.Globals["OnCatchMessage"],new AppletMessage[] {LatestMessage});

this is giving me this error coming from the applet class when it tries to call the function and pass the AppletMessage in:

cannot access field  of userdata<AppletMessage>

Source: (StackOverflow)

Moonsharp pairs(...) raises exception "bad argument #1 to 'next' (table expected, got string)"

I don't get the point why this is happening. I am using Moonsharp to run LUA scripts in my application an I created a LUA function IN(v, ...) and I'd like to itterate over the ... parameter with pairs.

IN('param1', 'param2', 'param1') -- expected it to return true
function IN(v, ...)
    local args = ...
    local res = true
    for i, v in pairs(args) do
        if valueIn == v then
            res = true
            break
        end
    end
    return res
end

If it gets called I recieve the folowing exception:

"MoonSharp.Interpreter.ScriptRuntimeException" bad argument #1 to 'next' (table expected, got string)

So I decided to check if there is a string instead of a Table in my ... variable.

function args(v, ...)
    return ...
end

The return value in C# is a Tuple of 2 values with 'param2' and 'param1', so it should work with pairs or ipairs, shouldn't it?

Thanks in advance.


Source: (StackOverflow)

Lua: Concise expression of table scope

I'm working on a game where a bunch of characters will be generated on the fly, based on some constraints defined either in the project or externally via mod files. I am using MoonSharp Lua (5.2) interpreter for interfacing with my C# code, and Lua tables to store the constraint presets. As an example:

require "Defaults"
AgePresets = {}

-- Single value
AgePresets.Newborn = 0

-- Simple ranges
AgePresets.Default = defaultAgeRange --referring to the Defaults require
AgePresets.Child = {1, 12} 
AgePresets.Teenager = {13, 19}
AgePresets.YoungAdult = {20, 29}
AgePresets.Adult = {30, 40}
AgePresets.MiddleAge = {40, 60} 
AgePresets.Senior = {61, 80}
AgePresets.Elder = {81, 99}
AgePresets.Methuselah = {100, 150}  
AgePresets.Methuselah2 = {150, 200}

-- Weighted ranges // again referring to previously defined elements to keep things concise
AgePresets.Tween = {
            {weight = 1, minmax = AgePresets.Teenager },
            {weight = 1, minmax = AgePresets.YoungAdult }
         } 

This works fine, but from an end-user point of view, there's a lot of unnecessary typing involved. We are clearly working on AgePresets here but it is still mentioned as a prefix before every member name.

I could of course define AgePresets as an array, like AgePresets = { Child = {}, Teenager = {} } but the problem with that is then I cannot refer to previously defined elements in the array.

This doesn't work:

AgePresets = {
    Child = {1,12},
    RefToChild = Child, //attempt to index a nil value exception
    Teen = {13,19}
}

What I ideally want to achieve is a clean, concise way for users to enter this data in, like in the first example but without having to put AgePresets. prefix before everything. How do I go about declaring a scope in a file such that all succeeding members defined in the file will be within that scope, while maintaining the ability to refer to other members defined previously in the scope?


Source: (StackOverflow)

Accessing a struct using MoonSharp Lua

I am having problems changing members of a struct, wich is a member of a class via the Lua interpreter MoonSharp.

My current test setup looks something like this:

class VectorClass
{
    public float X;
    public float Y;

    public Vector2(float X, float Y)
    {
        this.X = X;
        this.Y = Y;
    }
}

struct VectorStruct
{
    public float X;
    public float Y;

    public Vector2(float X, float Y)
    {
        this.X = X;
        this.Y = Y;
    }
}

For testing I have the vector object as a class and as a stuct.

[MoonSharpUserData]
class MyClass
{
    public VectorClass VClass;
    public VectorStruct VStruct;

    public MyClass()
    {
        VClass = new VectorClass(0,0);
        VStruct = new VectorStruct(0, 0);
    }
}

This is the class wich contains the struct/class.

class Program
{
    static void Main(string[] args)
    {
        Script script = new Script();
        MyClass classic = new MyClass();


        string scriptString = @"
                function changeVelocity()
                    MyClass.VStruct.X = 10
                    MyClass.VClass.X = 10
                end";

        UserData.RegisterAssembly();
        UserData.RegisterType<VectorClass>();
        UserData.RegisterType<VectorStruct>();

        script.Globals["MyClass"] = classic;
        script.DoString(scriptString);
        script.Call(script.Globals.Get("changeVelocity"));

        Console.WriteLine("Class: " + classic.VClass.X);
        Console.WriteLine("Struct: " + classic.VStruct.X);

        Console.ReadKey();
    }
}

In my main program I try to change the value of the struct and the class (only x) but it only works with the class.

I think there is some problem with the class being a Value-Type and not a Reference type. The API I'm working with uses a struct, wich forces me to get the struct access to work but I can't even use a MoonSharp ProxyType.

Does anyone know a workaround without rewriting the code completely?


Source: (StackOverflow)

How can I use MoonSharp to load a lua table?

After looking through various Lua interpreters for C#, it seems that only one is truly pure c# - MoonSharp. LuaInterpreter (defunct from 2009) which later became NLua depends on one of two other c# librariers KeraLua or another lib, and requires a customized lua52.dll (you can not use the one from lua.org, and). They have a bug report which is closed that says look at the readme for the download location of their customized lua52.dll, however it is absent. You are forced to download these libs from various sources and pray they work together in addition have a multi-file distribution which may have/cause compatibility issues with other programs due to several lua52.dll variations on the end users computer (assuming they will use more than just your program).

The one shining beacon of light on NLua is it's apparently popularity, however the project has not received any significant update in several years. MoonSharp on the other hand appears to be completely self-contained, yet is lacking in documentation for common tasks such as loading a table that was built with lua and working with it.

I have come up with the following code based on the singular example they provided on Git, and then duplicated on their site at moonsharp.org (whichever came first, i am unsure, but having 1 example is not sufficient) :

using System;
using System.IO;
using MoonSharp.Interpreter;

class Foo {

       function Bar( string accountName, string warcraftPath ) {
             string datastore = Path.Combine(warcraftPath, "WTF", "Account", accountName, "SavedVariables", "DataStore_Containers.lua";

             DynValue table = Script.RunString( File.ReadAllText( datastore ) );

             Console.WriteLine( table.Table.Keys.Count().ToString() );
       }
}

Results in the following (code in picture is slightly different as I adjusted the pasted code here for cleanliness and to make it easier for you to reproduce the problem using the table data in the pastebin link below.)

MoonSharp.Interpreter Table Load Lua Failure

The table I am trying to read looks like the following (simplified had to paste on pastebin due to the size exceeding 30,000 characters):

World of Warcraft - Datastore_Containers Lua table sample data

I sort of have something sort of working, it's a bit hackish, but doesn't seem to be away to loop through the values or explicitly get the subtables / values or key of the value.

    Script s = new Script(CoreModules.Preset_Complete);

    // hacked by appending ' return DataStore_ContainersDB ' to return the table as DoString seems to only work to run a function expecting a result to be returned.
    DynValue dv = s.DoString(luaTable + "\nreturn DataStore_ContainersDB;");
    Table t = dv.Table;
    foreach(var v in t.Keys)
    {
        Console.WriteLine( v.ToPrintString() );
    }

The problem is that there doesn't seem to be any way for me to enter the sub-table result sets or to explicitly access those like t["global"] or t.global.


Source: (StackOverflow)

Can Roslyn execute complex scripts?

We have a scenario where using a scripting language will enable us to avoid coding too many client-specific custom features in our software. We've identified an area where scripting might be helpful:

  1. Data Import: Here a file (text file, excel, etc.) is selected, parsed and validated against business rules and the data is then imported to the db.

In the above area, within the script we need to:

  1. Access our other assemblies (eg. POCO assembly), create classes and call methods
  2. Connect to a db to retrieve and write back data

Does Roslyn enable us to achieve the above or should we look into other solutions such Moonsharp?


Source: (StackOverflow)

C# MoonSharp passing custom class as UserData to function

I have a program that needs to send a "Row" (custom class) of data to the executing script function ProcessRow which then does some processing on this row

ProcessRow function in script:

ProcessRow = function (direction, mode, row, rowNum)

if direction == READ then 
    if row ~= nil then
        return row["state_id"] == 0
    end
end

end

C# Method who calls this script function

        public void CallRowProcessor(string mode, Row row, int rowNum)
    {
        UserData.RegisterType<Row>();

        //engine.Globals["row"] = row;

        DynValue res = engine.Call(engine.Globals["ProcessRow"], mode, row, rowNum);
        bool resVal = res.Boolean;
    }

Row Class:

[MoonSharpUserData]
public class Row
{
    Core instance;

    object[] data;
    public Row(Core instance)
    {
        data = new object[instance.FieldCount];
        this.instance = instance;
    }

    public object this[string key]
    {
        get { return data[instance.GetFieldIdx(key)]; }
        set { data[instance.GetFieldIdx(key)] = value; }
    }

    public object this[int idx]
    {
        get { return data[idx]; }
        set { data[idx] = value; }
    }

    public int Length { get { return data.Length; } }
}

If I remove the 'row' argument from ProcessRow and instead set it as a global I can access Row, but if I pass it as an argument to ProcessRow I get exception:

An unhandled exception of type 'MoonSharp.Interpreter.ScriptRuntimeException' occurred in MoonSharp.Interpreter.dll

Additional information: attempt to index a number value


Source: (StackOverflow)

How can I wrap my class with V8.NET and MoonSharp

I'm dealing with another challenge in .NET technology. My task is to embedde V8.NET and MoonSharp into a Windows Forms app. And I've come across a bit of a problem. Basing on: https://v8dotnet.codeplex.com/discussions/456763%20 , and exacty this fragment:

jsServer = new V8Engine(); jsServer.WithContextScope = () => {
    jsServer.RegisterType(typeof(SamplePoint), null, true, ScriptMemberSecurity.DontDelete);
    jsServer.GlobalObject.SetProperty(typeof(SamplePoint));
    jsServer.GlobalObject.SetAccessor("print", YourPrintGetter, null, V8PropertyAttributes.Locked); };

I've tried to add similar scope to my V8Engine but what's obvious I've misconfigured something becouse WithContextScope does not exist in jsServer. Of course I've added references to V8.Net.dll and V8.Net.SharedTypes.dll into my VS project. Also I have directive:

using V8.Net;

in my form.

Important fragments of my form:

using V8.Net;

[...]

private V8Engine jsServer;

[...]

private void Form1_Load(object sender, EventArgs e)
{
    jsServer = new V8Engine();
    Connect_to_db connect = new Connect_to_db();
    jsServer.WithContextScope = () => //Here is mentioned error
    {
        jsServer.RegisterType(typeof(SaleObject), null, true, ScriptMemberSecurity.DontDelete);
        jsServer.GlobalObject.SetProperty(typeof(SaleObject));
        jsServer.GlobalObject.SetAccessor("print", YourPrintGetter, null, V8PropertyAttributes.Locked);
    };
    if (connect.ShowDialog(this) == DialogResult.OK)
    {
        sqlite = new SQLiteConnection("Data Source=" + connect.getPath());
    }
    else
    {
        this.Close();
    }
    dataGridView1.DataSource = src;
}

And SaleObject class:

public class SaleObject
{
    public Double productionPrice;
    public Double salePrice;
    public Double stock;
    public String name;
    public String unit;
}

From what I've understood setting this up like this and setting up WithContextScope should give me class accesible from script, but context scope does not exist.

Also I'd like to avoid inherition from V8BaseObject becouse I'd like to use this class for both engines. How to wrap it properly in both engines so they not bother each other?

If this is important I'm planning on to use engine.Execute(String script) to run script recieved from RichTextBox


Source: (StackOverflow)

Unity + Moonsharp : iOS release version > Not work

We are using Moonsharp (Lua Interpreter) con our Unity new Game (Unity v.5.4.1)

On Android works well. And... thats de key...

However in iOS in the DEV version there are no problems, but in the RELEASE version it does not run correctly.

We have the following error:

"ScriptRunTimeException: Can not convert clr type System.MonoType"

What kind of differences between ios develop or release version?

I repeat. We only get that error once it is released to the iTunes Store, not in Dev mode.

Any solution?


Source: (StackOverflow)