Lua: Basic Engine

From Mario Fan Games Galaxy Wiki
Revision as of 16:35, 15 July 2009 by Xgoff (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Add to this template
 Standardwikimessagebox.png This article assumes the use of Lua 5.1.

Information may not be accurate or may need revision if you are using a different version.

This page covers the creation of a simple object engine. It will use many of the concepts from the other tutorials, so it is a good idea to read those first. For simplicity it assumes you are using MMF2 and a recent version of the XLua extension already set up and ready to go. When seeing the final code in its entirety at the end of the tutorial, you'll notice a lot of stuff has been moved around into a more logical order; this tutorial goes step by step so it'd be difficult to do that from the start!

To start off, we need a way to store and create new object instances. We also want to define a few namespaces, which will be used to hold many functions and variables under one table; this is considered good practice and also makes some things easier. For instance, accessing object methods would be a mess if they were stored in the global namespace.

object = { } -- object methods

newid = 0 -- next id to assign object
instances = { }

object.getId = function ()
    newid = newid + 1
    return newid
end = function (data_table)
    local var = data_table
    local obj = {
        __index = object, -- use the 'object' method table
        id = object.getId(),
        x = var.x or 0, -- default to 0 if no 'x' is supplied
        y = var.y or 0,
    setmetatable(obj, obj)
    return obj

Though we really don't need the object to serve as its own metatable (we could move the __index metamethod to object and reflect that change in setmetatable), it helps keep the method table uncluttered and also gives the object a sort of "type" specification: it's obvious we know that this is an 'object' instead of something like 'hud_element', which would use an entirely different method set.

You'll also notice how that function expects a table of named elements instead of separate parameters; it doesn't matter which of those you go for, but for constructor functions like this it makes sense to use a table, since they're used exactly like a regular table construction anyway.

To avoid possible gotchas, we aren't going to create (or destroy) objects immediately; instead we will either wait before (or after) the main loop runs and then we will either create/destroy it. Right now, we'll just worry about creating it:

createList = { }

object.createListFlush = function ()
    for _, obj in ipairs(createList) do
        table.insert(instances, obj)
    createList = { } -- clear the create list

object.create = function (data_table)

object.create is basically a macro function for constructing AND handling the new object. You don't necessarily need to use a function for that purpose, but it's a good idea in case you need to change how the object is created.

The createListFlush function calls a cb_newObject function; that function will be used by MMF to create an object and export it to XLua with the provided id. In fact, here is the psuedocode for that:

Start of Frame
--> XLua - Register MMF Function: cb_newObject

XLua: On Function "cb_newObject"
--> Create Object: <Active>; 0; 0
--> Active - Set ID (Alterable Value A): MF_NumericParam("XLua", 1)
--> XLua - Export Object: <Active>; ID("Active")

to be continued