5
votes

I want to add full support for Lua scripting to my game engine. One of the biggest goals I set myself is to retain full modularity. That means, I don't want the rest of my engine, except for the Lua binding part, to use any Lua-specific functionality.

This has proven to be not any hard until now. The pure C++ to Lua functions binding part - like binding the Vector, Color and Entity objects, and modules such as the Draw library or Physics library are easily isolated from the rest of the engine.

Now, my problem lies in events. I need to provide a way for scripters to respond to game events. This involves calling Lua functions from the engine.

Examples: Call OnCreate, OnUpdate, OnCollide on entities from C++ in Lua.

These events occur in my CEntity base class, and the Lua module has no way of knowing about when and how they happen.

Possible solutions:

  • Add a function call to the events in the C++ base entity, which triggers an event in the Lua script

Bad bad bad! That's Lua binding stuff mixed right into the base entity class!

  • Add some sort of event system to my engine, where the entity events trigger an event which can also be catched by the Lua binding module and handled appropriately.

I unfortunately don't know too much about this. I'm sure it would be quite difficult to implement and also bring some minor logical and performance problems.

- How can I trigger events (call a hook function) in Lua from within my C++ engine without having any Lua binding code outside the Lua binding module of my program?

2

2 Answers

3
votes

Game Code Complete (3rd Ed.) has a solution for that exact problem. Basically, he sets up the engine to have a generic event system and then has a scripting module that registers itself for the events it wants to respond to. The event system knows nothing about Lua, and the Lua wrapper only has to know the names of the events it wants to handle, so the coupling is very minimal.

3
votes

You might choose to have (depending upon your design) a LuaEntity derived class, which handles this stuff. You may also choose to use polymorphic functors instead (boost::function), which can be supplied and changed on the fly.