Sign in to follow this  
  • entries
  • comments
  • views

Lua and the like...

Sign in to follow this  


So, true to my word over the last week or so I've been brushing up on my Lua skills/knowledge; I don't tend to make a secret of it being my scripting language of choice.

Mostly it's been a refresh of things I've forgotten, I've also taken my time to clarify a few points and take my time to understand things I kinda half-skipped over before when reading the book.

One of the things I considered as I was reading about Lua's cooperative threading support was 'how viable is it to give each entity it's own Lua stack in a game and use that via a co-routine to power its brain?'.

From a coding point of view it's very viable; on entry to the function you call it like normal and after that it's just a matter of yeilding and restarting as required.

While each 'thread' has it's own stack they all share the same global state with each other and as they run cooperatively and have to yeild there are no deadlock problems either.

The question remained however; what kind of hit are you going to take memory wise from each of these stacks? In theory is shouldn't be too big, the struct its self isn't huge so memory shouldn't be that much of a problem.

So that end a little test app was built to see how things would compare;

#include "stdafx.h"
#include "psapi.h"

#include "lua/lua.hpp"

// Needed for reporting things
#include // for output stream data formatting

int _tmain(int argc, _TCHAR* argv[])

lua_State * L = luaL_newstate();

// Create a new table and place it on the stack
lua_newtable(L); // this will be position -3 in all future calls

std::vector states;

std::ofstream results("memory.csv");
results << "number of Lua threads,Working Set Size" << std::endl;


if(NULL != process)
for(int i = 0; i < 1000; i++)
lua_pushinteger(L,i); // key for table (position -2 in future call)
lua_State *L1 = lua_newthread(L); // create new thread (position -1 on stack)
lua_settable(L,-3); // does the set for the table at position -3, using key at position -2 and value at -1
states.push_back(L1); // store it


results << boost::format("%1%,%2%\n") % i % pmc.WorkingSetSize;
return 0;

The amount of memory used in the working set at the first allocation was 3031040 bytes.
After the last allocation was made the working set was 4235264 bytes.

Some maths later and we get a total memory requirement of approx. 1.1Meg for 1000 states. This includes the pointer storage in the vector and storing each state in a lua table element.

I don't know about you, but I think that is fine, certainly for AI agents where is is unlikely we'll have too many alive at once anyways and even 5,000 is only like to cost ~6Meg over all.

Something else I discovered was that I couldn't leave the states on the stack after creating them; on the 60th allocation the program exploded, heh, my bad [grin] Thus why we push them into a table, indexed by 'i'.

So, Lua is definately the brains of the operation [smile]

In other news; WoW totally didn't draw me in, I've not played it for a few days now and I'm not missing it in the slightest, so that's one MMO down. I also tried UO for about 3mins, at which point the POS UI and system they had made me swear at it, cancel the subscription and remove it from my system; so that's another MMO down.
So far the only MMOs I've enjoyed for any lenght of time have been;
Dark Age of Camelot

All the rest have lacked for some reason... ah well.
Sign in to follow this  


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now