Skip to main content
GameDev.net gamedev.net
🔒 Locked

Moving from Lua (LuaPlus) to Squirrel (SqPlus)

Started by John Schultz Sep 10, 2005 at 1:56 PM 0 replies 3.5k views
Original Post
John Schultz
John Schultz
I recently switched from Lua (LuaPlus) to Squirrel (SqPlus). While Squirrel does not yet have a powerful template wrapper, using SqPlus only requires simple stubs to be created to exchange arguments (type checking is automatically performed (set up during binding (one line of code)). While Lua and Squirrel are faster/slower for different operations (tables/arrays, etc.), Squirrel will be much faster if scripting is complicated/large enough that garbarge collection comes into play: standard Lua will grind to a halt during garbage collection. LuaPlus, in addition to adding an excellent template system, adds reference counting. Squirrel's author ((commercial game) FarCry scripting engine developer) started modifying Lua to add reference counting but went on to create a new language (uses Lua's excellent table design/code). Syntax and language-design-wise, I much prefer Squirrel over Lua (closer to C/C++, has native class support (similar to Java/&#106avascript), and many other advanced features). Lua's advantage is that it has been around longer (Squirrel is only 2 years old), and has a great deal of documentation (and many template wrappers available). My decision to switch to Squirrel was based on the improved language design over Lua, reference counting, and (relative) ease of understanding/tracing the core compiler/runtime code (including making quick tweaks in a short amount of time). I have written some code to make integrating Squirrel easier: see SqPlus here. Comparison of LuaPlus and SqPlus binding:

// LuaPlus:

    LPCD::Register_GlobalPropertySetFunction(state->GetGlobals(),"var1",&var1);
    LPCD::Register_GlobalPropertySetFunction(state->GetGlobals(),"var2",&var2);

    globalsObj.Register("func1",&func1);
    globalsObj.RegisterDirect("func2",*classPtr,&ClassType::memberFunc2);
    globalsObj.RegisterDirect("func3",*classPtr,&ClassType::memberFunc3);
    globalsObj.RegisterDirect("func4",*classPtr,&ClassType::memberFunc4);
    globalsObj.RegisterDirect("func5",*classPtr,&ClassType::memberFunc5);
    globalsObj.RegisterDirect("func6",*classPtr,&ClassType::memberFunc6);
    globalsObj.RegisterDirect("func7",*classPtr,&ClassType::memberFunc7);

/*
LuaPlus creates all the necessary hooks/callback so that Lua script can access vars & call functions via the names in quotes. No other code is required: it's very fast/easy to bind objects (type checking is also automatically performed).
*/

// Squirrel (with SqPlus):

    bindVariable(root,var1,"var1");
    bindVariable(root,var2,"var2");

    SquirrelVM::CreateFunctionGlobal("func1",func1Stub,"t"); // table arg
    SquirrelVM::CreateFunctionGlobal("func2",func2Stub,"s"); // string arg
    SquirrelVM::CreateFunctionGlobal("func3",func3Stub,"si"); // string, int args
    SquirrelVM::CreateFunctionGlobal("func4",func4Stub,"ssbf"); // strings, bool,float
    SquirrelVM::CreateFunctionGlobal("func5",func5Stub,"sssf"); // strings, float
    SquirrelVM::CreateFunctionGlobal("func6",func6Stub,"ssiff"); // strings, int, floats
    SquirrelVM::CreateFunctionGlobal("func7",func7Stub); // no args.

// SqPlus currently requires small stubs be created. Examples:

// Named arguments passed via table:

  static int initTerrain(HSQUIRRELVM v) {
    StackHandler sa(v);
    HSQOBJECT htable = sa.GetObject(2);
    SquirrelObject table(htable);
    flt cellSize = 7000.f;
    int cellWidth=6,cellHeight=12;
    if (table.Exists("cellSize"))   cellSize   = table.GetFloat("cellSize");
    if (table.Exists("cellWidth"))  cellWidth  = table.GetInt("cellWidth");
    if (table.Exists("cellHeight")) cellHeight = table.GetInt("cellHeight");
    GridSystem::gridSystem->init(cellSize,cellWidth,cellHeight);    
    return sa.Return(true);
  } // initTerrain

// Fixed arguments: automatically type checked (set up during binding):

  static int setEventTriggerTimeSequence(HSQUIRRELVM v) {
    StackHandler sa(v);
    const char * rigidBodyEventTrigger = sa.GetString(2);
    const char * rigidBodyControllee   = sa.GetString(3);
    int repeatCount                    = sa.GetInt(4);
    float startTime                    = sa.GetFloat(5);
    float endTime                      = sa.GetFloat(6);
    int res = r4d->setEventTriggerTimeSequence(rigidBodyEventTrigger,rigidBodyControllee,repeatCount,startTime,endTime);
    return sa.Return(res);
  } // setEventTriggerTimeSequence







Squirrel's author is currently working on a cross platform, portable remote debugger using Java and Eclipse (Squirrel should work on all platforms (tested on Win32/*nix)). I have been experimenting with scripting languages since 2000 (starting with Lua): once the remote debugger is available, Squirrel will be one of the best scripting languages for game applications (a good/complete template wrapper would make it even better).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.