Monday, June 26, 2006

More Scripting in Lua

In the first LUA tutorial - we looked at how to call C# functions from LUA. All well and good ... but what about using classes? That's kinda of important isn't it! You want to interact with your NPC classes and all that kind of cool stuff. This is what we'll be covering here.

Let There Be Classes!



I assume you can set up a LUA enabled C# project - we're going to do another nice console window one.

First thing to note:

Classes, enumerations, structs, what have you, . . . are all "CTS types".

Q: "What does CTS stand for?"
A: "Shutup"

Right, so how do we use these CTS types inside LUA. How how how?

Well there are two important functions that we must use.

1. luanet.load_assembly
2. luanet.import_type

While you're commiting those to memory - let's start creating a demo, framework, example whatever! Let's make one. So we make a new console application.

When I type you . . . type. Just like that



Using the previous tutorial we created a LUA enabled C# program. You should end up with the following and should be able to compile it without errors (if you fail in this hang your head in shame and go read the first tutorial again)


using System;
using System.Collections.Generic;
using LuaInterface;

namespace LuaScriptingAdvanced
{
class Room
{
Lua lua = new Lua();

public Lua Lua
{
get { return lua; }
}

public Room()
{
}

static void Main(string[] args)
{
Room partyRoom = new Room();

}
}

}


Now we're going to add a class, a marvel of object orientated design and programming.


class Person
{
public string Description = "";
}


Amazing! Well let's say we want a few of these people in a room. We need the generic collections namespace. Luckily it's already at the top of the room class.


using System.Collections.Generic;


The class "Room" is where we'll be having the party so we need to add some code there. We'll have a list of people in the room (enjoying the party) and we'll have a function look, that will tells us what's going on.


class Room
{
// Our revellers.
List people = new List();

public void Look()
{
foreach (Person p in people)
{
Console.WriteLine(p.Description);
}
}


We need one last function then we can start our LUA stuff. Can you guess what function? No? Well it's an AddPersonToParty function, doesn't exactly roll off the tongue but it will do.


public void AddPersonToParty(Person p)
{
people.Add(p);
}


Making Use of Lua



Let's stick to tried and true ground first and register the above function. Well kind of tried and true - it has a type in it, Person, that's not basic to LUA! But if you're not afraid, I'm not afraid, let's continue! We're going to jazz up the room constructor like so.


public Room()
{
lua.RegisterFunction("JoinParty", this,
GetType().GetMethod("AddPersonToParty"));
}


Hmm sweet jazzy jazz. Here we register the room's function that will let us add people to the party from a Lua script (The room also contains a Lua reference). Imagine if we created more than one room object! We would have problems, we'd always register over the last join party function! Luckily we only ever want one room, so this is okay.

Also we're going to expand the main function so it actually does something.


static void Main(string[] args)
{
Room partyRoom = new Room();

partyRoom.Lua.DoFile("scripts/party.txt");
partyRoom.Look();

Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}


Obviously the DoFile line of code jumps out. Scripts directory? "party.txt"? What's all this? You might wonder.

For now it's just filler in your bin directory create a directory called scripts. In the scripts directory create blank text file called "party.txt". Okay now you're all caught up.

So we call our [tag]script[/tag] and then call the room's look function - this will scope out the people at the party for us. Of course there are no people at the moment. Guess what the script might do! Now to write that script.

Coding in Lua



Ready? Okay go to the bin directory where the executable is being generated. You know where you dumped all those Lua dll files? Yeah? Good. Go there. Now you should have already created a text file named "party.txt". Open it and prepare to type!


--Grab the class info

luanet.load_assembly("LuaScriptingAdvanced");

Person = luanet.import_type("LuaScriptingAdvanced.Person");

--Steve
steve = Person();
steve.Description = "There's Steve drinking something brown and frothy from a shoe.\r\n";
JoinParty(steve);


For now Steve is a one man party. Okay now run the executable and try not to look alarmed. We should get the output:


There's Steve drinking something brown and frothy from a shoe

Press any key to exit.


And there you go. Remember what CTS stands for and you'll be fine! Now you can add classes to your Lua files - and you now what classes mean - prizes!

Let's Do Functions



We have to make use of the Lua libraries to do this. We're going to use the base library. Let's go back to our person class and add a few bits.


class Person
{
public string Description = "";
public string Name = "";

public void GiveName(string name)
{
Name = name;
}
}


Wow, talk about your contrived examples :D. Now let's check out that look function, in the room class.


public void Look()
{
foreach (Person p in people)
{
Console.WriteLine(p.Name + ": " + p.Description);
}
}


Let's alter the part of script dealing with Steve to include this new ground breaking function.


--Steve
steve = Person();
steve.Description = "There's Steve drinking something brown and frothy from a shoe.\r\n";
steve:GiveName("Steve");
JoinParty(steve);


Notice the little colon rather than a peroid. Be careful about that otherwise it will trip you up. Okay that should be enough to keep you going.

If you're going to use ints or numbers as function arguments remember all Lua's numbers are doubles therefore they need to be converted. This is done automatically yah! But in order to do it automatically you must include the math library. Using this: room.Lua.OpenMathLib(); will sort you out.

Next time I might do delegates, of course consider the amount of time that seems to pass between tutorials before you go betting your deadline on me. You may also be wondering about inheritence and all that ... the answer is yes you can but it's not something I think I'm going to need at the moment so I'm leaving it alone.

Source Code



Source Code
Post a Comment