Hello! This website doesn't really support IE that well... might I suggest you give Firefox a try?
David Carrigg
One thing we've been asked over and over is what our lua scripting support is like. I'm not going to go into the details on how to call lua functions from C++ (However, if you are interested in a tutorial on this then let me know in our IRC channel here). It's pretty easy to get up and going with it.

Image

In a nutshell, using lua in a game engine is sort of like handing the keys to the car you built over to another driver. They can drive it however fast or slow they want to now instead of just sitting in the back seat giving you directions. Eventually they'll take the car off of some sick jumps that you probably would have just driven around otherwise. It'll be a ton of fun and you'll be happy to see just what your car can do! Then one day they'll slam your car right into a tree. Yeah, that's exactly what it's like.

Click Read More to here how we use lua in RAE...

RAE allows us to add lua scripts to any game objects we place in the game. When we add a script like this, the engine automagically gives us a bunch of callback functions:

function onInit(me)
onUpdate(me, dt)
onDestroy( me )
onCollide( me, other, xNormal, yNormal, force, gibName )
onPaste( me )

In these callbacks, the parameters "me" and "other" are game objects passed from the engine.

There are a few other callbacks that the scripts give, but generally these are the ones used most often. One of the beauties of having a flexible interface with lua is that you can add whatever callbacks you want to the game. If we make an object that needs to know when PIC's X velocity is exactly 1.453, we could throw that in with 3 lines of code.

Here's an example on how we'd use those callbacks:
In the game there's are small floaty stars that you can collect. When PIC gets close enough to them, they accelerate and fly into him. This then causes an audio chime to play, the star is removed from the game, and we increase PIC's collected variable by 1. There were originally all scripted using lua like so:

function onUpdate( me, dt )
local data = getObjectTable( me:getGOId() );
local player = getPlayer();
local pic = player:getGameObject();

data.soundPlayer:setPosition( me:getXPos(), me:getYPos() );

if ( data.grabbed ) then
-- move the collectable towards PIC
local dX = pic:getXPos() - me:getXPos();
local dY = pic:getYPos() - me:getYPos();
local distance = point_distance( me:getXPos(), me:getYPos(), pic:getXPos(), pic:getYPos() );

-- Check if we are going to move past the player
if (distance <= data.speed*dt) then
collected(me, pic);
return;
end

dX = dX / ( distance );
dY = dY / ( distance );

me:setPosition( me:getXPos() + (dX * data.speed * dt), me:getYPos() + (dY * data.speed * dt) );

data.speed = data.speed + (.01 * dt);

elseif ( point_distance( me:getXPos(), me:getYPos(), pic:getXPos(), pic:getYPos() ) < 200 ) then
-- If we are close enough to PIC, fly to him
data.grabbed = true;
data.speed = 0.1;

else
data.timer = data.timer + dt;
local newX, newY = spirograph_motion( data.originX, data.originY,
data.spiroR, data.spiroL, data.spiroK,
(data.timer + data.offset) / 300);

local newA = data.startA * scale_clamp(math.sin((data.timer+data.offset) * 0.001), -1, 1, 0.5, 0.8);
local newS = data.startS * scale_clamp(math.sin((data.timer+data.offset)*0.001), -1, 1, 1, 2);

me:setUserDataFloat("myAlpha", newA);
me:setUserDataInt("myTimer", data.timer);
me:setPosition(newX, newY);
data.rotation = data.rotation + data.rotationSpeed * dt * 0.001;
data.textureGib:setColorR(newA);
data.textureGib:setXScale(newS);
data.textureGib:setYScale(newS);
data.textureGib:setRotation(data.rotation);
end
end

function onStartCollide( me, go, xNormal, yNormal )
if ( go:getName() == "PIC" ) then
collected(me, go);
end
end

function collected( me, pic )
local picData = getObjectTable( pic:getGOId() );
local data = getObjectTable( me:getGOId() );

picData.collected = picData.collected + 1;
kill(me);
print ("Collected: " .. picData.collected);
instance_create("./resources/objects/global/flash01/flash01.go", true, me:getXPos(), me:getYPos());

data.soundPlayer:setPitch((picData.starpitch + 50)* 0.01); -- Should be values between 0.5 and 2.0
picData.starpitch = picData.starpitch + 5;
print(picData.starpitch);
data.soundPlayer:play();
end

...I'll mention at this point that we add semicolons at the ends of our lines in lua. They complained when we told them they weren't welcome, and threatened to boycott the C++ code as well if they were excluded. That, and we enjoy them.

So lets check out what this code is actually doing. Remember that this is a script tied to an individual game object.

The onUpdate function callback is the brains of the operation here, as the engine makes this function call over and over. The dt parameter is short for deltatime, and tells us how long it has been since the last time the function was called. The logic here basically shows:
If the star is "grabbed" then move it closer to PIC.
If the star isn't grabbed but is close enough to PIC, set it as grabbed.
Otherwise, float the star around so when the player sees it, they'll want to grab it.

Image

When a star touches another game object with physics, the engine calls the onStartCollide callback. When the script gets this it checks if the game object it is now touching is PIC, if so it calls the collected() function.

The collected() function does the wrap up for what happens when a star is finally collected by PIC. PIC's collected variable is incremented by 1, it destroys "me" (which is the actual star object), a flash of light is displayed, and lastly it plays the sound effect.

So now that you have all that in mind, take a look at those star collectables in the trailer HERE. It's pretty cool what a little bit of lua scripting can create.

If you have any questions, I'm waiting to answer them in our IRC room.

Comments

Will

January 20th, 2011 9:27:15 am

Very nice, I'm getting ready to start the coding for python interfaces in my engine, and it's cool to see working examples of scripting and how other people implement things. I 've been following you guys on facebook for a while, and also made use of your photoshop animation export script(which I had to tweak to get working), but it has saved me a lot of time. You guys do good work, and I can't wait to give SnapShot a try when you're finished with it.

Peace

TESTING




Post Comment!
Loading

Other Info

Retro Affect LLC
28 Lang Street
Meredith NH 03253
info@retroaffect.com

Find Something

Follow us on Twitter
Look at us on Flickr
Watch us on YouTube
Friend us on Facebook