Some of the modders in the SupCom mod community have made some abysmal code that causes problems with compatibility even now, so I'mma write a quick tutorial here on how to make your mod compatible.
#1 Tables.
You can recognize a table by the use of {}. This marks a table constructor. Tables are passed by reference- that is, if you pass a table to a function, the table is the same table, and not copied. Table constructors can contain fields, like this:[code]{
Key = value,
Anotherkey = anothervalue,
}[/code]This is much, much faster and neater than creating an empty table and inserting into it, and should be used whenever you want to store something in a table when you know what it is at create time.
Now, you're going to see a lot of predefined tables in GPG code. You can see an example of big tables by cracking open any blueprint file, but they're everywhere in Lua. Now, how do you alter a table that's already been created? There are several ways, but the easiest is to use table.insert(table, value). This function will literally append the value to the end of the table. You call it, your value's in, you toddle off.
The second way to modify tables is through the use of the table[key] = value syntax. Here, you specify your own key, instead of table.insert coming up with an efficient numerical key for you. This can be important in, for example unit description tables, when the description key has to match the one specified, or blueprints. Here, Lua doesn't distinguish between overwriting a previous key, and adding a new one, so you'd best be careful to make sure that you're the correct user of that key. By assigning a key to nil, you can also remove that key/value pair from the table, i.e. table[key] = nil.
Do not ever change a table by hooking a file with an altered version of the constructor in it. That's a sin, and other modders will rightfully end your existence.
#2 Functions
If you have the function without a key, there is no way to tell what function it is without resorting to some extreme methods. However, you can modify it without needing to know the source. Modifying a function occurs only at the environment where the modification takes place. E.G. if you want to alter a function for everyone who calls it, you need to alter it at the point of calling. Function hooking uses a simple principle: you overwrite a variable with the value of a new function, which calls the old function. By using this, you can for example record when a function is called, and such things.
[code]function example(args) end
local temp = example
function example(...) # This will make sure that no arguments are ever lost. If you know the source function, you can name and gather information about them.
return temp(...)
end[/code]
Of course, that function effectively makes no change. However, you could alter it to do anything instead.
The key with the above techniques is that they will nest indefinitely, and are order-independent. That means that you can use them with a hundred mods, and it doesn't matter when they're loaded, and it will still work out correctly. Do not ever change a function or table by simply overwriting the definition of it, unless you must, and those instances are pretty rare.
In SupCom, there's a UnitDescriptions table, where table[ID] = description. People overwrote the definition of it. Surprisingly, their mods have conflict issues, now the original creator doesn't support it and .. mess. If you need to alter a GPG function or table, do try not to destroy the original.