Best scripting language for my game


  • Winner of the 2016 Presidential Election

    Disclaimer: It's not my intention here to spark a flame war, but if that happens I won't be too upset. The "best" anything is always controversial.

    For a for-fun side-project I want to develop a simple game, and I've decided to do the engine in C# and the game logic in a scripting language running inside that engine. My question is, which scripting language would work best here?

    Right now my prime candidates are Javascript (I'm familiar with it, and free libraries exist to embed it), and Lua (I know little about it but it's supposedly faster, and the "industry standard" game scripting language).

    Which of these, if either, is better for thiis, or is there another candidate I should consider besides?

    Right now, this what I know:

    Javascript
    ProsCons
    Familiar (to me)
    Popular
    Flexible
    Lacks a good "import" or module mechanism
    Prototypical rather than classical inheritance
    Lua
    ProsCons
    Fast
    "Industry standard"
    Unfamiliar (to me)

    Clearly I don't know enough about Lua at the moment to know if it has other strengths or weaknesses, and right now I'm trying to determine if learning it would be a complete waste of time or if it would actually prove to be useful. I probably won't ever need it in a professional capacity.



  •  If you didn't have 918 posts, I would make thought that you're trolling for fun.


  • Winner of the 2016 Presidential Election

    What, that means I can't troll for fun?


  • Discourse touched me in a no-no place

    @joe.edwards said:

    Lua (I know little about it but it's supposedly faster
    I have limited experience with Lua in that I've only written one script for a dissector for two in-house protocols for Wireshark/tshark, and get the impression that it really isn't that fast. My script basically parses a (dually) delimited string using the function:

    function nextdata(buffer, ptr, delimiter)
            data="";
            local count = 0;
            while (ptr+count < buffer:len()) do
                    char=buffer(ptr+count, 1); 
                    count = count +1
                    if char:uint() == string.byte(delimiter, 1, 1) then
                            return data, ptr+count, count
                    end
                    data = data .. string.char(char:uint())
            end
            return data, 0, count
    end
    


    Usage is basically:
            -- buffer contains the data from the packet
            ptr = 0
            data, newptr, count = nextdata(buffer, ptr, ":")
            while true do
    
                -- do stuff with data; insert it into the tree, have an inner loop doing this if it's comma delimited etc.
    
                if newptr == 0 then
                        break
                end
                ptr = newptr; 
                data, newptr, count = nextdata(buffer, ptr, ":")
        end
    
    Knowing next to nothing about lua (like yourself) I'm sure there's a more efficient way of doing this. (The data in question is largely : delimited, bit some of the data within a pair of : is itself comma delimited.) I find it takes ages to decode any reasonably sized packet capture containing relevant packets.

    Individual data items are on the order of 1-2 characters (except the comma delimited ones, which are about 8 items long each themselves 1-2 characters)
    An example I've just pulled off a box is:
    7:0:0:016:1366459169318:::::::.06:.16:.12:1171468:52.8:5:80:15175071:228:5081392:57::7,1,1,2,26,20M,153,232/392:7,0,0,0,-12,0,,0/0:7,1,1,2,24,13M2,119,1K44/1K92:7,1,0,2,0,0,,0/0:7,0,0,2,0,0,,0/



  • Joe, do you mean "fast (execution time)" or "fast (development time)"? JavaScript has been so fucking optimized to shit over the last 5 years that I'd be shocked if Lua is anywhere near as fast (execution time) as the top 3 JS engines.



  • Going to agree with blakey here. JS engines nowadays are completely uncomparable with JS engines from two to thee years ago, let alone before that. They are really, really fast nowadays.

    If you need scripting support in C# then go for an embedded V8 engine using JavaScript.NET. Interop between C# and JS is easy, including the creating and exposing of custom host objects to the JS engine. While JavaScript as a language itself does not have support for a module/import syntax, you could implement either the CommonJS require/exports syntax (as used by Node.js) or the AMD require/define syntax (as used by RequireJS) as an API based on earlier mentioned host objects. A bigger challenge, if not the biggest, would be the attachment of a JavaScript debugger to debug your game's scripts properly.

    (As for prototypal vs. classical languages: classical inheritance can be expressed in prototypal inheritance. Lots and lots of JavaScript frameworks exist that have 'class factory' patterns to make this easier...)



  • I'm curious. Why do you need to have the logic run in a scipting language? Why not expose relevant game engine objects and do the scripting in C#?

    I did a bot type thing for an MMO some years back, injecting asm compiled code into the running game, and from there hand over data to a C# core. Further from there I'd just expose a few top level objects for scripters to work with, also in C#. Granted I had very few speed requirements, and scripts were not that large as to really strain my machine.


  • Winner of the 2016 Presidential Election

    @Cenan said:

    I'm curious. Why do you need to have the logic run in a scipting language? Why not expose relevant game engine objects and do the scripting in C#?

    I want a clean separation of the engine from the game logic, for a number of reasons. First, reuse; I think it could be repurposed and used again for other projects. Second, collaboration; I want it to require less domain knowledge to develop game stuff than to work on the engine, that lowers the barrier to who can make content for the game. Third, modularity; I want players to be able to add in and mix content packs, either first-party or third-party. Finally, I think it's a good design principle to separate concerns into layers, this is sort of an n-tiered architecture applied to gaming.

    I think the benefits are fairly widely recognized by the gaming industry, which I'm not seriously trying to break into but just dabble with for fun.


  • Winner of the 2016 Presidential Election

    @Ragnax said:

    Going to agree with blakey here. JS engines nowadays are completely uncomparable with JS engines from two to thee years ago, let alone before that. They are really, really fast nowadays.

    If you need scripting support in C# then go for an embedded V8 engine using JavaScript.NET. Interop between C# and JS is easy, including the creating and exposing of custom host objects to the JS engine. While JavaScript as a language itself does not have support for a module/import syntax, you could implement either the CommonJS require/exports syntax (as used by Node.js) or the AMD require/define syntax (as used by RequireJS) as an API based on earlier mentioned host objects. A bigger challenge, if not the biggest, would be the attachment of a JavaScript debugger to debug your game's scripts properly.

    (As for prototypal vs. classical languages: classical inheritance can be expressed in prototypal inheritance. Lots and lots of JavaScript frameworks exist that have 'class factory' patterns to make this easier...)

    Awesome, I was feeling iffy about Lua, but those two limitations of JS were almost dealbreakers for me (especially the modules thing). It seems my Google-fu was weak (or just outdated) because every benchmark I was able to find had Lua way ahead.

    You've given me good leads to follow up on, thanks.



  • Might I suggest IronPython? It's a full-fledged .NET language, so it will integrate nicely with your C# code.


  • Winner of the 2016 Presidential Election

    Having done a little bit of exploration, I want to throw up one more candidate: JScript.NET

    It's very Javascript-like, but with the power of the .NET Framework at its back. Also, I believe I can use built-in .NET code emission APIs to JIT-compile it.


  • Winner of the 2016 Presidential Election

    Jinx!

    What are some other strengths you see in IronPython?



  • @joe.edwards said:

    Awesome, I was feeling iffy about Lua, but those two limitations of JS were almost dealbreakers for me (especially the modules thing). It seems my Google-fu was weak (or just outdated) because every benchmark I was able to find had Lua way ahead.

    If you search for benchmarks, most are around 3 years old, some even older: horribly outdated! While Lua sent through LuaJIT may still be slightly faster, JavaScript nowadays is absolutely fast enough for game scripting, or even writing entire games in it. (E.g. stuff like Cut the Rope.) Also; Mozilla recently showed off their new ASM.js project by revealing Epic's working port of the Unreal 3 engine to JavaScript in Firefox. That should be telling you something about the interest going into making JavaScript engines fast enough for games; even commercial ones...

    @joe.edwards said:

    Having done a little bit of exploration, I want to throw up one more candidate: JScript.NET

    It's very Javascript-like, but with the power of the .NET Framework at its back. Also, I believe I can use built-in .NET code emission APIs to JIT-compile it.

    JScript was developed against .NET 1.1 and has been pretty much dead since then. It apparantly also has some rather serious issues left in the compiler which may cause it to choke on perfectly valid code and produce archaic stack traces in the process. One of the main reasons Microsoft developed the DLR with .NET 4.0 was to provide better support for dynamic languages, something JScript.NET seems to have utterly failed at.

    Besides, the intention behind using JavaScript.NET is to have complex logic that actually warrants use of the .NET framework's full power be implemented host side; in C#, and then have its public API be easily exposed as host objects to JavaScript.


  • Winner of the 2016 Presidential Election

    Thanks for your input. I saw Fiddler using JScript.NET and thought, oh, hey; now I see that that's a dead end, I will go with a more mature and robust Javascript framework.

    Lua has basically been eliminated from consideration at this point, it's looking like a port of the V8 engine is the way to go with this. I like the look of this one, except it looks like it hasn't been touched in nearly a year and is still in beta (dead project?).



  • @joe.edwards said:

    I like the look of this one, except it looks like it hasn't been touched in nearly a year and is still in beta (dead project?).

    The codeplex repository is discontinued. The project itself was open sourced and then further development was moved to GitHub. See this commit message that sums up nicely why the project's activity is low: the 'shell' around V8 is complete, so no-one is really touching it anymore. It's now only a matter of producing a build against the latest V8 sources. (Also 0.x versions don't necessarily mean unstable beta. Just look at Node.js for an example.)

     



  • There is also edge.js, which seems to be in active development. It's a bridge between node.js and C# (and apparently python too).

    It seems more built for embedding C# modules in nodejs scripts than the other way around, but if you're fine with building a JS "launcher" for your game, this might not be that much of a problem. (You could still keep game scripts from abusing the nodejs API/knowing they run on nodejs at all by e.g. sandboxing them with contextify.)



  • @Ragnax said:

    The codeplex repository is discontinued. The project itself was open sourced and then further development was moved to GitHub. See this commit message that sums up nicely why the project's activity is low: the 'shell' around V8 is complete, so no-one is really touching it anymore. It's now only a matter of producing a build against the latest V8 sources. (Also 0.x versions don't necessarily mean unstable beta. Just look at Node.js for an example.)

    Should probably have mentioned it before, but I'll add it now: there is a NuGet package, should you want to go that route. Also; I snooped around a bit more and found ClearScript, which may be something to keep an eye on for the future.



  • @Ragnax said:

    Also; I snooped around a bit more and found ClearScript, which may be something to keep an eye on for the future.

    Hmm... From the looks of things, with the recent round of patches/improvements that went into ClearScript, it seems that it is actually a better choice by far.

    (Amusing how these things slip by under the radar some times.)


  • Winner of the 2016 Presidential Election

    @Ragnax said:

    ClearScript

    Fancy. I think we have a winner.



  • Lua is actually pretty good, but its C/C++ interop functions are a bit painful.



    For every C function you want to call from Lua, you have to create a wrapper as a static function which manipulates Lua's

    internal stack... basically loads of boilerplate code to fetch your arguments and pass them into your actual function. Its not

    exactly difficult, but it is quite dull, and if you accidentally miss something and your pushes/pops don't match up its a bit of

    a bugger to fix.



    Once you get the hang of it its pretty good though. No idea about benchmarking... but if you're seriously worried about

    performance in your scripts, then what you're trying to achieve should probably be implemented natively instead, regardless of

    your choice of scripting scripting engine.


  • Discourse touched me in a no-no place

    @eViLegion said:

    For every C function you want to call from Lua, you have to create a wrapper as a static function which manipulates Lua's
    internal stack... basically loads of boilerplate code to fetch your arguments and pass them into your actual function. Its not
    exactly difficult, but it is quite dull, and if you accidentally miss something and your pushes/pops don't match up its a bit of
    a bugger to fix.
    Can't you use a tool like SWIG to do the boilerplate generation job?


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.