Hacker News new | ask | show | jobs
by catdawg 1404 days ago
I've worked now for 3 years on a large lua game code base, over 4000 files, 1.5 million lines of code.

In the first week or so, I was a bit weirded out by the lack of language features, as I come from C#/Typescript/C++, but I was very surprised that after 2 or 3 weeks, I was already doing very complex tasks on the code base.

I think a lot of that comes from the simplicity of the language. It's very difficult to surprise you, everything works in pretty much the same way.

Here are some things that I will miss once I move to other languages: (note that most of these are not things that come from simply using lua, you have to implement it into your framework/engine, but they are still pretty common)

- stack traces print the contents of the variables in the stack. Not all lua code bases have this, but it is easy to implement.

- if the code crashes, you can fix the code and continue. This doesn't always work, and requires the code base to be written in a way that supports it, but it is definitely possible and I've used it many times.

- debugging works really well. You can easily attach and inject code, stop on exception and inspect the state.

- settings are also lua code. This is probably the biggest thing I'll miss. I love being able to have simple functions as part of settings (e.g. things like tweening functions), being able to generate settings based on other settings, or run simple sanity checks, all on the same file.

- index starting on 1, this is definitely an unpopular opinion, but IMO it just makes things so much easier. When you need to access the last element, you just do tbl[tbl_length], no need to decrease by 1, or doing a for loop, you only specify the indices you're actually accessing "for i = 1, last_index do end". I think it really helps with off by 1 errors. I used "normal" indices for over 10 years before this project, and I would still occasionally have these errors, but with lua, I don't really remember having them.

- not having to fight the compiler to quickly try out different things. Need something from a completely different system? Just add it to the global table and access it from the other place.

A big learning I got from transitioning from languages with a very strong type system to a dynamic language like lua, is that in order to be effective, you really need to use code architecture patterns, otherwise things become very hard to reason with. This might be counter intuitive, but I think you need to be a better programmer to use lua effectively, than you need to with a language like C# or Typescript. With the latter languages, the compiler helps you a lot, but with lua, you have to know how to use these things on your own, because you can pretty much do anything and that can be reeeeally bad :)

4 comments

I love to see the Lua love on HN, especially given my other languages of choice are generally disliked around here.

Funny enough, I was just mentioning to a friend this weekend that I would love to write Lua as a full time job (and particularly in gaming), but those jobs seem nearly non-existent.

How do you recommend going about finding opportunities like yours?

If you want to work on "AAA" games, I don't think there are many companies left using it to this scale. An engine where those kind of games are developed almost fully in Lua, AFAIK, is Bitsquid (later Stingray by autodesk), but that has been discontinued. There are still some companies that use Bitsquid derivatives though, like Fatshark, Toadman and Arrowhead. See https://en.wikipedia.org/wiki/Bitsquid

As for non "AAA", I think https://love2d.org/ is quite popular for game jams and commercial 2d games - I haven't used myself though.

So maybe look for opportunities in companies using those engines.

I worked for a few years on a project developing a content using openresty, if you're interested in other Lua uses/jobs.
> a large lua game code base, over 4000 files, 1.5 million lines of code

Interesting; how do you manage to keep consistency? Do you have special tools to e.g. detect inadvertent global variables? I once wrote a Smalltalk VM in Lua (https://github.com/rochus-keller/Smalltalk/blob/master/Inter...) which is a much smaller code base, but even with this modest size I quickly would have lost track of e.g. scopes and names without tools I had to write myself (https://github.com/rochus-keller/LJTools).

Most of the time nothing is used. The thing is that iterating is so quick, that you find the problems really fast.

Although, I've been using luacheck https://github.com/mpeterv/luacheck. It is quite nice, but you have to write down the global variables by hand on the config file.

Edit: Also, the vscode lua plugins have been getting quite good, and completion works to a certain extent.

It depends. You can also configure luacheck from within the file you are checking. For instance, in some of my lua code [1], I have:

    -- luacheck: globals init handler
    -- luacheck: ignore 611
The first line tells luacheck that the variables `init` and `handler` are globals, and the second line tells it to ignore lines that contain just whitespace (a quirk the text editor I use uses to manage indenting levels).

[1] https://github.com/spc476/port70/blob/master/port70/handlers...

Lua’s language server can be nice for detecting unwanted globals. It gives you a warning whenever you declare a global that starts in lowercase, which works nicely if you’re okay with using uppercase globals as a convention
> I think you need to be a better programmer to use lua effectively ... with lua, you have to know how to use these things on your own, because you can pretty much do anything and that can be reeeeally bad :)

I find this sentiment interesting. Perhaps somewhat akin to Linus Torvalds famously preferring C to weed out bad programmers.

I think many people would say that a language which makes it easier to do things poorly is objectively worse than the alternative. But the way a language "selects" the sort of programmers that use it is an important second-order effect (maybe even more important than the initial one?).

> index starting on 1, this is definitely an unpopular opinion, but IMO it just makes things so much easier.

Not modulo!