Advertisement

Using Lua in a OO-way?

Started by September 23, 2004 12:08 PM
15 comments, last by TonyFish 19 years, 10 months ago
I was thinking of implentning a scripting language into our engine, so I downloaded Lua and tried to understand it. I played around with it for a couple of days, and learned the basics (calling C Functions from Lua, and the other way around). But I have encountered a problem: Let's say I have several classes in my game, for all the npc's:

class
CNpc
{
public:
    virtual void AttackPlayer(); // Can be called from the script file.
    virtual void Die(); // Can be called from the script file.
    virtual void GoToWaypoint(); // Can be called from the script file.

    void Damaged(); // Will call the function within the script file.
    void TalkedTo(); // Will call the function within the script file.

    CNpc(){ /* Load "npc.lua" here */
};


class
CAlien : public CNpc
{
public:
    CAlien(){ /* Load "alien.lua" here */
    CAlien(string filename){ /* Load "alien.lua" AND filename here */
};


class
CHuman : public CNpc
{
public:
    CHuman(){ /* Load "human.lua" here */
    CHuman(string filename){ /* Load "human.lua" AND filename here */
    virtual void Die(); // Can be called from the script file.
};

Let's say that I create a CHuman object (with the parameter "scientist.lua". First, it enters the constructor of CNpc, and loads "npc.lua". Then, it enters the constructor of CHuman, and loads "human.lua". And last, it loads "scientist.lua". Everytime it loads a new script file in this object, it should be able to override functions. So if Damaged() only is defined in npc.lua (not human.lua or scientist.lua), it should enter THAT function upon call. It should also work the other way around. If Die() is called from a script-file, it enters Die() in CHuman. If GoToWaypoint() is called from a script-file, it enters GoToWaypoint() in CNpc. There's several problems with this: 1. How am I supposed to store the (lua-)functions in each object separateley from each other? Having one VM for each object sounds like a bad idea. 2. Calling member-functions from within the lua-scripts doesn't work as I thought it would do. Does Lua (or the standard Lua C API) have support for this, or do I have to use something like luaBind or toLua? (And what are they for?) 3. Maybe Lua isn't a good choice for me? Is there any better scripting language that suits my needs? /Orca
Look at luabind or possibly python if you need a more OO language. Squirrel is another possibility, it is quite like Lua and I think it is object orientated.
Advertisement
Ok build luabind and then try this out. It's a messy test but it show the kind of sharing between script and engine which you seem to want. It looks like you're after an UnrealScript native(engine)-script sharing of classes which is something I'm working on too. Although in the long run you'd want to design your own VM and compiler as lua would prove to slow for anything serious.

[Edited by - algorhythmic on September 23, 2004 2:37:47 PM]
[email=algorhythmic@transcendenz.co.uk]algorhythmic[/email] | home | xltronic | whatever you do will be insignificant, but it is very important that you do it - mahatma gandhi
algorhythmic: Didn't get your example to work - many of the functions you used didn't exist in luaBind. :(




Shard: Yes, I have been playing around with luaBind for a while, and even if it would be possible to do what I want to do - I don't know _how_. Havn't found so much documentation/examples.


And btw, is it anything special to want a script-language that can handle OO? I mean, almost everyone uses some sort of OO in their programs nowadays, right?


Why would this be so hard to accomplish with a scripting-language? Anyone?
Object orientation is generally viewed as a way to help manage large amounts of code more effectively. As such many people would consider it to have little or no benefit on a small scale, and hence it's not a priority when developing scripting languages.

Possibly you are expecting too much of Lua. Alternatively, you can get a lot of what you want if you work on a slightly lower level. Just as inheritance and the like can be hacked into C, so it can be done for Lua.

A Simple Object System For Lua (PDF)
Lua Object Orientation Tutorial (HTML)
Lua Inheritance Tutorial (HTML)
Simple OO in Lua (HTML)
an OO example using an interesting hack (HTML)
A note on Luabind. I've used it for a long while on a puzzle project and found that it carries more overhead than i expected.

Our puzzle game is 99% Lua code with just some low level stuff (image loading, rendering, sound objects,etc) written in C++. It was a risk as Lua is generally accepted to be a 10x perf hit to C/C++ code, but i felt it was an appropriate project to test the limits of Lua. I used Luabinds-oo system for all my pure lua classes and exported stuff that i thought would be faster in C++ like point2 and rect2 classes. When i tested it on my low end system (P2 266MHz) i was getting dismal performance... 10 to 15fps. So this set me out on looking for places to improve it.

Originally i thought... hey if some Lua code is slow i'll replace it with a fast C++ function. That doesn't quite work out if your using Luabind. The overhead of the Luabind calls plus using luabind::object to query lua variables made most of my "fast C" versions of Lua functions very slow... slower than the originals sometimes. Since i had alot of per-frame temporaries in my Lua code (like point and rect obects) the instantiation overheads from Luabind were murder.

I've since switched to my own pure-Lua OO system and it's at least twice as fast as Luabind's. I moved my point2 and rect2 classes to pure Lua classes with one or two functions overloaded in C++ (without using Luabind). On my low end i get over 50fps and on the high end (P3 2.8GHz) it hits ~600fps... really.

So my message is Luabind is good and easy to use and works great for most projects, but it can bite you if your game is heavy on Luabind derived objects. Learn to use Lua via it's C-API. There is a learning curve to it, but it's a well designed and fast interface.

You can find some more info on what exactly the bottlenecks were if you search for my posts on the Luabind list.
Tom Spilman Co-owner | Programmer www.sickheadgames.com
Advertisement
Has anyone uised squirrel? I was looking at it recently and I thought it looked pretty good. I think it was based on lua, and the author worked on the scripting system for Far Cry, I think he has an account on gamedev too. Another possiblity.
That was me, I accidentally hit enter.
Quote: algorhythmic:
Although in the long run you'd want to design your own VM and compiler as lua would prove to slow for anything serious.

Actually i don't believe that's true. Sweeney has said that UnrealScript is a 20x perf hit compared to C++ code. This is more than what is said of Lua code, 10x.

Still i didn't want to go just on some offhand approximation, so i started to benchmark UScript vs. Lua (http://lua-users.org/wiki/LuaVersusUnrealScript). This is a work in progress still as i've had a hell of a time getting good timing results i can trust from UnrealScript, but i've finally found a reliable method and i'm going to be updating it today.

So far i've found that Lua *is* faster than UnrealScript.
Tom Spilman Co-owner | Programmer www.sickheadgames.com
One thing i should mention is that it's not always faster. I haven't tested it, but i'm fairly certain that UnrealScript would beat Lua on slower platforms like P2s. This is because internally Lua treats all numbers as floating point values and these older CPUs handle them much slower than newer processors.
Tom Spilman Co-owner | Programmer www.sickheadgames.com

This topic is closed to new replies.

Advertisement