As of May 19th, I've unsubscribed from the Lua mailing list. Thus ends an era.
For years I have been a strong proponent of Lua. I've used it in my games, and I've used it in servers with Nginx. I've used Lua to write command line tools, and I've used it to write extensions for existing games. Lua is a great language to play with for a number of reasons. The syntax is easy to learn and somewhat forgiving. It includes the concept of tables, which double as arrays, and even though it's extremely simple, it's also very fast (extremely fast when using LuaJIT).
So why did I leave?
Five factors combined in a perfect storm to cause me to drop Lua as a game scripting language, as a server language, and as a language for my command line tools:
- LuaJIT is in permanent maintenance mode.
- Lua version fragmentation.
- Lua Coroutines are no longer a monopoly.
- Type annotations FTW
More details on each point below.
Future of LuaJIT
Mike Pall, the author of LuaJIT, single-handedly created the most amazing dynamic language JIT compiler ever. He may hold that title for years, despite the fact that he's no longer extending LuaJIT. He resigned from the project to move on.
LuaJIT will continue to be an awesome example of what a single brilliant developer can create, of course, but it means that the people who replace him have huge shoes to fill. Odds are good that anyone who does step up (and I'm not following the status; people may have stepped up already, I don't know) will probably just maintain LuaJIT, fixing bugs, and at best may bring LuaJIT 2.1 to a final release state.
But without Mike Pall, we probably won't be seeing amazing new features and performance enhancements any more. That amazing new garbage collector that he had planed to create will likely never come to pass, and there's little chance that LuaJIT will catch up to the new 5.3 syntax, meaning using Lua will forever be a choice between LuaJIT @ 5.1 with a few 5.2 upgrades, or using 5.3. leading me to….
Fragmentation of Lua
The major breaking changes in Lua in 5.3 seem to be fragmenting the already sparse Lua library ecosystem. Anyone who creates a library needs to now support LuaJIT (a 5.1/5.2 hybrid), 5.2, and 5.3. A lot of Lua libraries aren't actively updated, so in reality existing libraries are a crapshoot of 5.1, 5.2, and 5.3 support.
Lua dependency management is also very hit-or-miss. The "luarocks" package manager has about a 60% chance of working with any particular package on Windows, for instance. This has always been the case, but with the additional Lua version fragmentation, it's only making things worse.
I have encountered the occasional bug on Windows where, after I say
npm install, it doesn't manage to finish installing everything. This doesn't inspire confidence. But in general it's easy enough to run the install command again, or nuke the packages folder and re-run. I don't run Windows on my servers, so this is really just a development environment issue;
npm install has been completely reliable for me on Linux.
Intermittent Windows issues aside, the sheer quantity of tools available through an
It was useful for game AI ("do this, then this, and then this!"), and it was amazing for writing simple and amazingly fast web servers ("grab THIS from the database, THIS from this other server, and then send a response"). By fast I mean: If you compare to a connection-per-thread server (like one based on PHP or Ruby), you can see a 50-100x performance improvement. In games, it simply makes some kinds of code possible to write out in an easy to follow fashion.
Lua is an easy language to write code in, in part because the types of variables isn't specified. Instead the interpreter needs to figure out the type at runtime. This trait is rather common in a lot of popular languages right now, including Ruby, PHP, and Python. It's totally in vogue.
But I found that, in writing several games and server projects in Lua, 80%+ of the bugs that I ended up having to fix were type errors.
A more annoying type error is when you have an object that has fields. Say you have a
thing that has a
color, but you accidentally type
thing.Color instead of
thing.color. If you're trying to set the color, you'll create a new field Color, and the actual color won't change. No runtime error, no evidence that anything is wrong – except the color isn't what you expect.
Languages like C++, on the other hand, require that every single variable and parameter have a type specified. This can be tedious, and can involve changing several files when the type of a structure changes.
thing. in my editor, it will know that thing has a "color" field and will offer to complete it, along with any other fields
thing might have.
I swear that my productivity is almost twice what it was before.
LuaJIT is my preferred Lua scripting engine because of its raw speed. That speed is even more important when running on mobile, where CPUs aren't as fast.
But due to an architectural decision made by Apple, you cannot JIT compile code for iOS. Period. LuaJIT is still faster than vanilla Lua, but only like 3x, not 5-100x.
Lua experienced quite a strong popularity as a game scripting engine. World of Warcraft famously used it. There are other games that use it, and that will likely continue for the intermediate term, if only out of inertia, but I'm guessing that Lua has passed its popularity peak.