Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua and C++: separation of duties

Please help to classify ways of organizing C++/Lua game code and to separate their duties. What are the most convenient ways, which one do you use?

For example, Lua can be used for initializing C++ objects only or at every game loop iteration. It can be used for game logic only or for graphics, too. Some game engines provide full control to all subsytems from scripts! I really do not like this approach (no separation at all).

Is it a good idea to implement all game objects (npc, locations) as Lua tables without C++ objects? Or it is better to mirror them (Lua tables to control C++ objects)? Or something else?

Thank you.

Edit. My classification: Lua and C++: separation of duties.

Topic's continuation: Lua, game state and game loop

like image 803
topright gamedev Avatar asked Apr 20 '10 11:04

topright gamedev


3 Answers

My approach has been to limit what is exposed to Lua as much as possible. I have never found a need for a "main" or other such function which is called every time the scene is rendered (or more). Some Lua engines (like LOVE) do this however. I prefer to define objects with optional callback functions for common events that you may want the object to respond to such as a collision, mouse click, entering or leaving the game world, etc..

The end result is very declarative, almost a config file for objects. I have a function for creating classes or types of objects and another for creating objects based on these types. The objects then have a collection of methods which can be called when responding to various events. All of these Lua methods map to C/C++ methods which in turn modify the object's private properties. Here is an example of a bucket object which can capture ball objects:

define {
    name='ball';
    texture=png('images/orb.png');
    model='active';
    shape='circle';
    radius=16;
    mass=1.0; 
    elastic=.7;
    friction=.4; 
}

define {
    name='bucket';
    model='active';
    mass=1;
    shape='rect';
    width=60;
    height=52;
    texture=png('images/bucket.png');
    elastic=.5;
    friction=.4; 
    oncontact = function(self, data)
        if data.subject:type() == 'ball' then
            local a = data.subject:angleTo(self:getxy())
            if a < 130 and a > 50 then
                --update score etc..
            end
        end
    end;
}

I would not take this as the "one true way" to implement your scripting API. One of the beauties of Lua is that it supports many different styles of API. This is just what I have found works well for the games that I make - 2D physics based games.

like image 69
Nick Van Brunt Avatar answered Nov 09 '22 20:11

Nick Van Brunt


I propose this classification:

  1. Extreme variant: Lua scripts control everything (game logic, graphics, AI etc.). Even more: script works as a host-program, owns game loop. Some engines do such thing. Ba-ad thing: no separation of duties at all and no script safety.

  2. Lua scripts maintain game state and process game logic. Probably scripts are called at each game loop iteration.

  3. Lua scripts are rarely used for initializations, configurations, callbacks. A host program provides (binds) a very minimalistic interface for the scripts. So scripts are built from such well-designed and provided blocks.

like image 24
topright gamedev Avatar answered Nov 09 '22 20:11

topright gamedev


Start small. Allow access to game entities so that you can perform map/level-specific scripting. Behaviour that is consistent across maps/levels probably doesn't need scripting.

Also, only give access to the public interface of your objects.

like image 1
bitc Avatar answered Nov 09 '22 20:11

bitc