Sunday, January 18, 2015

Game AI in Lua

Recently an email turned up in my inbox asking me to have a look at a new book on Lua titled Learning Game AI Programming with Lua, by David Young (published by Packt).  Here's my thoughts on the book following a read of the first half of the book, and a skim through the second half.



First some of my background for context.  Most of my career in computing (which professionally goes back to 2000) has been in C++ development on Linux devices, but also includes some server-side work, and lately iOS/Mac development in Objective-C.  I spent 4 years from early 2009 working on and then leading the team that built Qt3D, a C++ OpenGL rendering system which was scriptable in QML, and was mainly intended for Linux mobile devices, and embedded systems.  I gave a number of talks on Qt3D at Qt Dev Days in Munich and San Francisco during those years.  

From 2012 I have been working on my own business: doing some client work, and my own game development projects, including Ethex 2080 which was written in Objective-C for iOS devices and which used Lua scripting.  I demo'ed Ethex 2080 at the 2013 Game On symposium, but its currently on hold.  A series of screencasts covering the approach I used to create my Lua bindings for Ethex 2080 is on this blog.

In 2014 I wrote Space Bot Alpha, an Qix-style area claiming game in Objective-C using Cocos2D, and its currently available in the App Store and soon to be available for Android (via Apportable's Objective-C environment for Android).

Lua Scripting in Games

Using Lua for scripting a game is a great idea.  You often need a high performance language that compiles to native machine code (e.g. an x86 or ARM binary) in many parts of a game engine, for example the main rendering functions, the parts that traverse the scene graph.  So you write your engine in C++ or some other C-like language.

But often game development involves cycling around the edit-compile-run loop over and over until game play feels right.  Removing the compile step and loosening up the syntax from a strongly typed language like C++ makes that development so much quicker.  Enter Lua, a language born for this job.

Also some other parts of game functionality are really hard to abstract out and do good software engineering on, and also maybe you want to be able to put small pieces of ad-hoc or hard-coded functionality into an game character.  Lua is ideal for working in this way.  Engineer your engine in C++, and hack your game logic in Lua - its a great approach.

Lua performs well also, even marshalling over from C/C++ into Lua and back is fast.  Its ability to handle pointers to chunks of native memory via the userdata Lua type is very nice.  Once you know you're using Lua in your native-engine game, the problem of how to handle AI rears its head.  This is where David Young's book comes in.

The Downloads and the Book

The book itself is relatively slim at 328 pages, but the must-have downloadable accompaniment is much of the value for your spend on Learning Game AI Programming with Lua.  It includes a copy of the Decode Lua IDE, Young's Sandbox game engine (which is a proxy for "insert your game engine here") and a heap of open source projects for the back end of the Sandbox engine, including Ogre3D the popular 3D rendering framework.

Knowing the versions of the software that work together is for example very useful - this book targets Lua 5.1 and as the project just recently released 5.3 its handy to know you'll need to go back a minor version or two to get everything working.

Is this Book Right for Me?

If you're planning to script your game logic in Lua whilst your main game engine runs in C++ (or a similar language) and you know you're going to have to deal with AI then this is a great book to buy. If you're working with CryEngine, Unreal or some other game engine like that then Young's sandbox is a proxy for that engine and the concepts will come across very well as far as I can tell.

If you develop for iOS, then you'll be on Mac and the Windows Visual Studio solutions in the book will be difficult for you to evaluate, as they were for me.  Similar story for Linux.  I didn't take the time out to fire up my Windows VMWare image and try out Young's sandbox engine, but a look through the code (downloadable from Packt's website as a companion to the book) shows fairly clean (if sparsely documented) C++ that is a good exemplar for Lua bindings in a game engine.  Here's an example:

int Lua_Script_AgentApplyForce(lua_State* luaVM)
{
    if (lua_gettop(luaVM) == 2)
    {
        Agent* const agent = AgentUtilities::GetAgent(luaVM, -2);
        const Ogre::Vector3* const force =
            LuaScriptUtilities::GetVector3(luaVM, -1);

        AgentUtilities::ApplyForce(agent, *force);
    }
    return 0;

}

I don't think it would take long to get the sandbox ported to run on Mac and since all the components of Young's sandbox engine are popular Open Source items like Ogg Vorbis, Ogre3D, Bullet physics and so on the whole thing could probably be gotten ported to Mac without a lot of work.  Maybe future editions of the book will ship a Mac version of the sandbox.

But even if you just bought the book to get Young's code as an example of how to do your bindings then that is good value.  In my opinion writing your own bindings across exactly the part of the interface that you need them is the right way to do it.  I'm not sure about bindings done using bindings generators - I think its better to manually write those bindings yourself.  While Young does not cover bindings writing in the book, his code and the chapters in the Lua book should get any competent programmer over this part.  That's true even if you're on a system that does not support Microsoft's Visual Studio.

If you want a more generic book about game AI, where algorithms are expressed in generic language then a good start is O'Reilly's AI for Game Developers which is an excellent book.  I have a paper-back copy that stays on my desk at work and it is accessible and high level enough to inform many projects.  The content of that book is still relevant today after it was first printed in 2004.  Learning Game AI Programming in Lua covers a lot of the topics in that book just by doing an implementation, and adds a few more things like Influence maps for agent AI (something that was totally new to me).

To learn Lua itself the actual Lua book, is pretty good, also functions as a reference, and buying it helps the development of the language.  Young's book is not too demanding on Lua knowledge, but it won't try to teach you Lua either.  Its best to have a reasonable understanding of Lua, especially of its type system, associative tables and stack based C language interface (covered in the final chapters of the book) before you go into scripting your game and AI in Lua.

If you're writing games in Lua, using for example Corona; or hosted game content in World of Warcraft or another Lua scriptable game, then this is not so well suited.  It's really for developers of hard-core games, especially 3D games, and less suitable for indie dev's hacking on a smaller game using something like Corona.  You probably need to read a generic book on Lua and a book on game AI, like the two mentioned just above.

AI and Animation Hand in Hand

One thing I love about this book is the pragmatism about how tightly bound AI and animations are.  Young's management of this is well done, and its something that you don't see in generic books on AI.  For example you need your state-machine to handle AI, but it also has to handle the animation states of your characters and props in the game.

The book develops an animation state-machine in its early chapters and then goes on to base its AI work on top of this, which is a solid approach, and one that clearly shows the author's experience in real shipped games.  I wonder if a Harel state-chart with hierarchical state machines could handle the relationship between character animation states and AI states with a solid theoretical framework to underpin it, but the pragmatic approach is the straightforward one.

Frameworks like Playmaker for Unity do hierarchical state-machines well but I think in code it would become unwieldy without a visual editor to manage the structure.  The approach in the book is clean and seems to work well.

This kind of AI tight integration with animation is a little bit less relevant for 2D games but still important.

Summary

Though I have not been able to compile and test the code shipped with the book from my read it looks really good, and an invaluable resource for the hard-core game developer adding AI to a Lua scripted game.  The information in this book is solid and immediately applicable while still being knowledge that is not going to date quickly.  A good addition to any game developers library.

Disclaimer

Packt Publishing provided me a free copy of the book for review.  Otherwise I have no affiliation with Packt.