Which indeed was part of the problem. Also in CBM state I had to call local to define MapModData.
I'm still not following you here. MapModData (like most everything in Lua including function names) is just a name. Names can be redefined in any scope (or undefined with name=nil). But MapModData
should be a global in any Lua scope that already holds a pointer to one single table (the same table pointed to by all those different MapModData's). You shouldn't need to do anything with MapModData itself. You can (optionally) create a local variable in a given file (or even narrower scope) that points to this table with "local MapModData = MapModData". That should never be necessary but can speed things along if you have many accesses to that table.
If you type the line "MapModData.gT = {}" you are really doing three things: 1) Creating a table (the "{}" part) which, like any data in Lua, is fundamentally nameless. 2) Creating an element in the table MapModData called gT (table elements
do have names). 3) Putting into that table element a pointer to the table you created. You can create a new pointer to the same table by "local bunnies = MapModData.gT". Neither "MapModData.gT" nor "bunnies" really
is the table. Both hold pointers to the same table, though one happens to be a local variable and the other an element of a table. If you remove all pointers to a table, then Lua will quietly (without you telling it to) garbage collect that table since it is now eternally inaccessible to you.
The logic behind "MapModData.gT = MapModData.gT or {}" is as follows:
- If MapModData.gT does not exist yet, then MapModData.gT (the left side of the "or") evaluates to nil and Lua executes the stuff to the right of "or". I.e., it creates a new table and assigns a pointer to the new table to the just-now created element gT in MapModData.
- If MapModData.gT already exists (because the code ran from some other file or state before this) then nothing happens. The table element is unchanged and Lua does not even look at the right side of the "or" (so no new table is inited). (Due to some Lua optimization this kind of construction is faster than an "if then" construction.)
After this, MapModData.gT now holds a pointer to one single table (the same table) from any scope, regardless of file run order.
After this, it is now safe to create additional (local) pointers to this table from many different scopes with something like "local gT = MapModData.gT".
Perhaps it's confusing to use the same name for a local variable and a table element or a global variable, but this is common in Lua. E.g., "local MapModData = MapModData" or "local print = print" or "local sort = table.sort". This is very convenient because you can do it at the top of any scope without having to change the code below (well, the 3rd example requires some re-coding). But it has a major impact on the compiled code and resulting execution time since local variables are easier to access than global.
The last piece of the puzzle that may be causing confusion here is to understand that "globals" in Lua aren't really global. They are themselves local to the particular state. In Civ5, each UIAddIn (with all its included files) is in it's own state. "Gobals" can be redefined in any state without affecting that name in other states. There are a bunch of globals already defined for you in all of these different states, including, for examples, "print" and "MapModData" (the former added by the base Lua package and the latter kindly provided by Firaxis). But you can redefine any of these in any state or undefine it with a nil assignment. You can use the Fire Tuner to see what particular globals are
defined in each state. As you observed, "MapModData" is not defined in Main state, though it is in any "mod-accessible" state. Conversely, "_G" and "io" are defined in Main state but have been sandboxed by Firaxis in all other states so aren't available to modders. Even more tricky is a case like "os", which seems to exist in all states but actually (I suspect) points to a different table in Main versus other states, so modders can't do something like os.remove(<your harddrive>) from a mod but they can use os.clock() (or it could be the same table with restricted access to elements -- I'm not sure how they sandbox individual table elements like this).
Not sure if any of this helps, but your language makes me think that something is missing in your "Lua think" that is leading to an error.
Overall I find TSL extremely easy to use, much more so that saveutils/sharedata. So thanks again.
Yes, I agree, though I didn't want to blow my own horn too much

. saveutils/sharedata was created before we were given SaveGameDB. What's nice about TSL is that I don't have to think about it at all. Tables are just magically restored with their prior contents after game load. (The bad thing is the awkward way we have to intercept gamesaves since we still lack an Events for this.)