Best practices for scoping variables with Lua

,

This isn't a specific technical issue but this category seemed most appropriate. Apologies if it should've gone somewhere else, or if this info is out there somewhere and I haven't been able to dig it up.

I'm really enjoying experimenting with the Playdate SDK (on Windows) and have been slowly building a game using Lua. But I'm curious what best practice is for scoping variables.

I ask because the very first item in "Lua Tips" in the docs says to initialize variables with "local" whenever possible. However, a lot of the examples I've looked at (including those that come with the SDK) don't necessarily follow this convention. I also realized pretty quickly that using only local variables would mean being very careful about splitting code over multiple files.

Should I get in the habit of playing close attention to this now and passing local variables between files using function calls/callbacks? Or is it reasonable to be using global variables for things that multiple files need access to?

Any guidance on this would be helpful, thank you!

The answer is 'it depends'...

Wide global usage without careful consideration is a recipe for really hard to find bugs caused by strange interactions between globals and different parts of your code. You only have to experience this once or twice to learn the painful lesson that 'default global' (which Lua and other languages support) is a potentially dangerous thing.

One Lua specific thing about globals is they can be less efficient (for Lua) to find than locals - because globals all live in a table with everything else that came with the environment (eg. the Play.Date Lua SDK).

Imho your default should be to use local, and pass parameters to functions.

However globals ARE useful, and you'll see them in use in complex code, but they are typically used for global state you explicitly want to be global. Things like 'manager' objects or 'singletons' that are used across your code. A Player object that is everywhere in your code is common. However it's usually worth naming these sensibly, something the Global_Player or Player (with a capital P) so it's clear this is a global variable.

Also short demo pieces of Lua code (like some of the examples) usually won't bother using locals. It's just easier to use globals to show you how something works quickly.

This is just my 2c - it'll be interesting to see what other people think.

Edit: To your point about splitting over multiple files btw. Once your code gets sufficiently large, it's much easier to split functionality into separate files to manage things. Have a look in the PlaydateSDK/Examples/Hammer Down folder for an example.

Thanks, Stuart! It turns out it wasn't that difficult to switch most things to local, just had to untangle what was used where. Hammer Down is also a great suggestion, I hadn't looked at it in a while and it felt very daunting at the time. It still does, but I think it'll be helpful.

I'll mark this as the "solution" in a sec but I wanted to ask a follow up. It seems like there isn't as much of a concern over local vs. global functions, am I right in thinking that? Is there an easy explanation as to why? Are they stored or accessed differently than global variables?

I'm not an expert but I believe the same rules apply. Functions are global by default unless you make them local, in which case they're only visible in the file they're defined in (Lua calls that a chunk). This is because functions in Lua ARE variables which is a subtle and useful feature of Lua... (worth googling 'first class functions' ).

Your functions should have specific... function I guess. Give them sensible names so it's clear what their function is (to labour the joke). Again have a look at the Lua SDK examples perhaps.

Thanks again, Stuart! I appreciate your input on both of these questions.

1 Like