Jump to content
  • Advertisement
Sign in to follow this  
Kaptein

Lua scripting woes

This topic is 390 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I need some advice. After I changed my scripting language from in-memory C to Lua I've had numerous problems I've never encountered in other languages.

Prototypes? Type signatures? Calling functions with any number of parameters?

How do you deal with all the random bugs you can get that you have really no way of determining the cause of?

If I call a function with one less parameter than it should have, I might just get a Lua error somewhere else in the script. At a later time.

What do you do to make your code (which isn't bottlenecked at all, so there is tons of room to add checks and balances) more correct and more sane?

 

If I scripted sanely in C I would rarely have these issues. For example any pointers passed between the engine and the script goes through a sanitizing stage where it actually checks if the pointer points to an actual valid existing entity. If it sounds like I am regretting the change, I don't know how to answer that. Lua can construct tables and pass them around, which is very nice, unlike C where I would have to malloc (and that is just not going to happen).

Edited by Kaptein

Share this post


Link to post
Share on other sites
Advertisement

Things like this are why I have a love/hate relationship with Lua. :)

You might want to add validation checks for your function arguments and throw errors when something goes wrong. You'll want your host application to print out the call stack on errors so you can track down where the problem occurred. Ultimately, though, you need to exercise all your code (whether at runtime or as part of a test framework) to make sure everything is sound.

The problems you're experiencing seem common to all dynamically-typed languages (including JavaScript) since there's fewer ways for the language to help you out than with statically-typed languages (like C). I don't think there's an easy solution aside from being careful with your code and disciplined with testing. Dynamically-typed languages usually work great for small things but start getting harder to use as projects grows in scope.

(Background: I worked on several commercially-released titles that used Lua extensively and added Lua scripting to an older game as part of an unofficial patch.)

Share this post


Link to post
Share on other sites

Yeah Lua is great, but very unpalatable to begin with when coming from a C background...

When passing pointers from C to Lua and back, you can either pass them as a light-userdata, which is equivalent to a void*, or use a heavy-userdata which allows you to attach a metatable that you can use for runtime type validation.

Unless you actually want to write code in the prototype paradigm, you'll likely just use metatables to implement an OO-style class system and then forget about them. 

When writing OO style code, you can use one of two main styles:

className.method( self, args... )

or

self:method( args... )

If you use the first style, then it will be closer to a statically typed language, as you're constantly writing the name of the class that you expect an object to be. It's also quite a bit faster (on vanilla Lua / non-LuaJIT -- JIT'ing makes them both just as fast really).... but the first style is ugly :D

Inside your methods, you can check the metatable of each object (including self) to see if it really is of the expected type -- the details of this depend on how you choose to implement classes/OO! You can also check whether any of your arguments are nil (which will happen if it's called with too few arguments) or whether any spurious extra arguments were passed or not. You could use a pre-processor to strip out these debug assertions from shipping builds if required.

Getting a good debugger is also very useful. I'm using "tilde" at the moment, but am looking to switch to something else soon....

If you want to support runtime script reloading, then that will also affect the way you write your code. In C, you might write some code like:

foo = foo ? foo : 42; // if foo is zero, set to 42

In Lua, when creating a new global table, you might write:

foo = {}

But when reloading your script, this will assign foo to a new table (leaving some of your code potentially still referencing the old table!). So, you can instead write:

foo = foo or {}

And then if you reload the code, the foo table will not be recreated.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!