Lua in SpringRTS/Gadgets

Gadgets are script files that must be present from all players. That's the reason gadgets are used in mods and maps as those should always have exactly the same data. Gadgets can use callins and callouts from both synced and unsynced mode but you need a special way to let synced and unsynced code to communicate with each other.

When making a gadget, always separate synced code from the unsynced code. That can be done with using:

That makes sure that the code blocks are in the right place. Not using the gadgetHandler:IsSyncedCode will result in executing the code in both synced and unsynced mode. That in many occasions will create errors so it's not wise to do so. Specify whether the code should be used in synced mode or unsynced.

When making a gadget you should always place the game events(UnitCreated, UnitDestroyed, ...) in the synced block of code and the events that just has with Lua graphic to do should be placed in the unsynced block of code.

An easy way to determine if something should be placed in unsynced or synced is to determine if the code should have the same effect on all users or only you. The reason Lua graphics are placed in the unsynced code is that even if one user doesn't get the right graphics it doesn't mean that other players are having the same issues. So doing so makes the gameflow go smooth. Think if UnitDestroyed for example was in the unsynced code. Then a player with a slower computer would probably get the event a bit slower thus not making the game playable for him as he would get events a bit delayed.

Using globals:
One way to communicate between synced and unsynced code is to use globals. We use the _G table from Lua to add a variable as global:

Here follows a demonstration of synced/unsynced communication via globals: In the example we declare a local variable in the synced part of the code and try to change the value of it while still in synced mode. Then we save the value as a global. After that if we want to read the value in the unsynced code we just use the "SYNCED." table.

Using SendToUnsynced function
A second way to do this is to use the SendToUnsynced function.