Recently I've been working on an RPG with a friend, for whom coding is not their strong point. We're using the excellent LÖVE framework, so the whole game is written in Lua.

Scripting of dialogues, animations and in-game events is a hugely important aspect for any RPG, and I wanted to build a scripting system that's easy to use and doesn't require any knowledge about the rest of the game's engine, but is also powerful enough for me to extend with new functionality as needed. This post aims to show how a few simple Lua features can be combined to create a scripting environment that's pleasant to use.

First, let's take a look at the XSE language used in Pokémon modding, as this was probably my main point of inspiration. It has a very straightforward, imperative style, even though each instruction doesn't correspond to a single function in-game.

By this I mean, the whole game engine doesn't freeze just because you are talking to an NPC, however there are points at which the dialogue script cannot progress until the text animations have finished and the player has pressed the [A] button.

So from this perspective, we can agree that yes, Lua's imperative nature and sloppy semantics (especially around nils) put it at a disadvantage for large codebases vs languages that have the advantage of immutability and/or intelligent type systems. But the fact that it offers setfenv makes it uniquely suited for constructing larger codebases out of small codebases. This is the approach I take in my game Bussard, where I have four separate execution contexts, none of which have much more than 3,000 lines of code in them. Each small codebase is perfectly manageable on its own, and the interfaces between them are concise and clearly-defined despite Lua lacking first-class features for defining interfaces as we normally think of them.

Right now our weapon of choice is the Lua programming language due to its relentless simplicity and the availability of the wonderful LÖVE game framework. While we've done graphical games with LÖVE, this one makes more sense to start out as a plain Lua game that uses console input and output. The complete source code is available on GitLab.