Skip to main content
GameDev.net gamedev.net

PRO Tired of ads? Read GameDev.net ad-free and help keep the community independent with GameDev Pro — $3/month.

RPG Anvil: The Lua Tutorial Part 3

RPG Anvil: The Lua Tutorial Part 3

gdunbar
gdunbar
Merry Prankster Games · · 3 min read
1,384 0


Today, how to call a Lua script from your game.

The previous installments of this tutorial are here:



As you may recall from previous installments of this tutorial, the goal of the tutorial is for our C++ game code to call into a Lua script to determine whether the player can open a door or not. Today, we'll call a dummy Lua script, just to demonstrate how to call into Lua.

First, we need a script to call. We'll put this into a fixed string, up near the top of our luatest.cpp file.

char *szLua ="x = 8 ""return ( x > 7 ) ";


Astute readers may notice that this script always returns true. In later installments, we'll replace the line "x = 8 " with code that calls back into C++. But, walk before you run, grasshopper.

We need to initialize Lua before we call into it; something like this:

    lua_State *lState;    lState = luaL_newstate();    luaL_openlibs( lState );


This creates a lua_State object, ready to make Lua calls. You could think of a lua_State as a little virtual Lua computer for use by our program. It maintains its state until destroyed, so we can manipulate the Lua virtual computer in our C++ code as much as we want without having to worry about reinitializing variables each time or whatever.

We can load our script into the lua_State as such:

    int iStatus = luaL_loadstring( lState, szLua );    if( iStatus )    {        std::cout << "Error: " << lua_tostring( lState, -1 );        return 1;    }


See the Lua documentation for other ways to load scripts; you can load them directly from files if desired.

To run the script:

    iStatus = lua_pcall( lState, 0, LUA_MULTRET, 0 );    if( iStatus )    {        std::cout << "Error: " << lua_tostring( lState, -1 );        return 1;    }


Be sure to check for errors, because if you make an error in your script, Lua will usually give you a decent error message so you can fix the script. (This is a big advantage over my previous, self-designed scripting language, where any syntax errors had to be painstakingly determined by hand).

To check the return value of the script, do:

    int iRet = (int) lua_toboolean( lState, -1 );    if( iRet )    {        std::cout << "Door opened!" << std::endl;    }    else    {        std::cout << "Door still closed." << std::endl;    }


And last, cleanup the lua_State, freeing any associated memory:

    lua_close( lState );


Build and run your code, and you should get "Door opened!" on the screen. Hint: Put a breakpoint on the "return 0;" and you can view the message in the console window before it gets shut down.

Here's the entire luatest.cpp file to this point:

// luatest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include #include char *szLua ="x = 8 ""return ( x > 7 ) ";int _tmain(int argc, _TCHAR* argv[]){    lua_State *lState;    lState = luaL_newstate();    luaL_openlibs( lState );    int iStatus = luaL_loadstring( lState, szLua );    if( iStatus )    {        std::cout << "Error: " << lua_tostring( lState, -1 );        return 1;    }    iStatus = lua_pcall( lState, 0, LUA_MULTRET, 0 );    if( iStatus )    {        std::cout << "Error: " << lua_tostring( lState, -1 );        return 1;    }    int iRet = (int) lua_toboolean( lState, -1 );    if( iRet )    {        std::cout << "Door opened!" << std::endl;    }    else    {        std::cout << "Door still closed." << std::endl;    }    lua_close( lState );    return 0;}


So, that all fine and dandy, but our "real" script still needs the Lua script to be able to call back into C++ code to determine the player's Lockpicking level. Next time!

Discussion

Loading comments...