Moving components to C++

Published April 13, 2015
Advertisement
5w4nGXr.png

So, I've gotten the game fully back to where it was before. Works great. But I have a pretty big project to tackle now.

You see, a LOT of the game functionality is written as Lua script objects attached as script object components to Urho3D Nodes. Which is great and all, but the thing is that the Lua bindings use tolua++ to generate the bindings. It is an issue (known to the Urho3D team and the users on the Urho3D forums) that bindings generated using tolua++ tend to be slow and non-optimal. It's a thing I've run into before in my own stuff as well.

The issue is in the way tolua handles taking ownership of objects. You can specify that certain objects be "owned" by tolua; that way, when they are out of scope they will be garbage collected. The way tolua.takeownership works, though, is that for each call to takeownership, a full garbage collection cycle is performed. And any time an API method or function, bound to Lua, returns an object by value then that returned object is automatically taken ownership of by tolua. Meaning that for every single one, a full garbage collection cycle is performed.

If you think about it, that can turn into an ungodly number of garbage collection cycles per frame. That means that it will spend a lot of time in the gc that it doesn't need to. You can mitigate some of it by explicitly calling new/delete to create your own local objects and temporaries, but there is not much you can do about the full gc pass done for objects returned by value. You can see in this shot...

jWNPL62.jpg

... how the update portion spends almost half of its time inside LuaCollectGarbage. And that is even after an optimization pass where I reduced the number of locals being taken over by tolua as much as I could. By necessity, there are still just a lot of places where objects are being returned by value. Call GetPosition() on a node? That's a gc cycle. Iterate the returned results of a raycast? Some more gc cycles. It adds up.

So my project for the next few days/weeks (depending on work and stuff) is to begin moving components out of script objects and into dedicated C++ components to try to reduce the gc overhead. It would probably be helpful to switch to AngelScript, since the AngelScript API for Urho3D works better than the Lua API, but that's something I really don't want to do unless I have to. I've already significantly reduced the wasted time by implementing a few of the more widespread script objects with C++ components, so I'll see where I sit in a few days.

I'm talking mostly about nuts-and-bolts stuff, here. I still will leave as much of the gameplay and AI type stuff in Lua, but with some potential redesigns to help reduce gc waste even further.
Previous Entry Implementing elevation
Next Entry Useless filler
8 likes 5 comments

Comments

Navyman

I game is looking amazing! Hopefully, your efforts will payoff. You have made great leaps from the first time I saw your game. Continue the awesome work.

April 14, 2015 04:29 AM
Ashaman73

Take a look at luajit (just exchange the lua.dll) and analyse how the performances changed.

PS: the screenshot looks pretty cool :D

April 14, 2015 04:33 AM
Aardvajk
This is the kind of thing that has driven me to try to create a scripting language with dynamic typing but deterministic destruction rather than garbage collection. So far, it seems quite possible and seems to be working well [/shameless_plug]
April 14, 2015 07:09 AM
JTippetts

Ashaman73: I don't really get a whole lot of difference when I build with LuaJIT enabled. (Urho3D has a build option for LuaJIT already, and I use it most of the time except when debugging.) The problem lies in tolua, rather than in Lua itself. Ideally, I'd like to use LuaJIT+FFI, but to do so would require a massive rewrite of Urho3D's Lua binding layer--something I'm not really prepared to do right now. :D

April 14, 2015 02:38 PM
tnovelli

Aardvajk: and I'm one-upping you with a static native compiler. biggrin.png Language geeks, unite! er, divide.

Actually it's not a high priority for me; my current game is all C++, and it looks like simple fixed-function scripting will be enough. But someday!

JTippetts: yeah, Lua/C++ binding libraries are a nightmare. LunaWrapper(?) seemed like one of the better, lighter ones... still crazy though. That GC/no-GC impedance mismatch. Lua+C binding/embedding is great though... maybe not super-efficient, but simple. I've wondered if it would make sense to use Lua as the primary language, handling all the OO stuff there, only using C for low-level graphics etc. I'd try it if I *liked* Lua, haha. (Can't stand the oddball syntax and conflated data types)

April 16, 2015 03:09 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement