How do I get a value from another Lua state?

Pazyryk

Deity
Joined
Jun 13, 2008
Messages
3,584
Sorry for the rather technical question.

I know how to use LuaEvents to call a function in another lua state (e.g., for a popup). However, LuaEvents don't return values. So I don't know a simple way to get a value from another state. Any lua experts out there that can help me?
 
I'm sure there's probably a way to pass information back and forth through the call statement, but I never bother. The easiest way, assuming you have control over both files involved, is to have them both include a Lua file and store whatever you need as globals within that file. Failing that, you can do this pretty easily by using a MapModData structure; as long as you've created the instances for it, you can use that data structure in any number of files without needing to screw around with include statements or function calls.

Actually, you can use it across multiple mods as well; in my own mod set, I do this to have the Top Panel (which is in my Base mod) display some of the values generated in my Mythology mod. As long as you check to make sure the structure's not a null before using it for anything, it works just fine.
 
Actually, I found the answer in an old thread (can't find again). The problem with "include" is that I'm working with many many UI states, which all need info from my mod's main state. I'm not even sure what happens if I include one ... but I'm sure it's a bad idea to include all.

The answer was really remarkably simple. You can use LuaEvent to pass an empty table (really a reference) from the UI to your Main. Then contents of that table are accessible to both states.

So, say I have everything in my mod's main state nested within gT. For example I have subtables gT.gUnits, gT.gPlots, and so on...

At game init my main mod code runs this:
Code:
LuaEvents.Pass_gT_pointer.Add(
function(gTT)
	gTT.gT = gT
end)

Now, from a UI lua file (or any different state) I run this:
Code:
	if not gTT then
		gTT = {}
		LuaEvents.Pass_gT_pointer(gTT)
	end

So now from this other state I can access (to read or change) anything under gT in my mod's state by using gTT.gT.gUnits, gTT.gT.gPlots, etc.

It's really fantastic for UI states because it is an easy way to expose everything in your mod's state to all of those UI states.
 
Like I said, you could use MapModData to do something almost exactly like that, without function calls. It's not as easy as just using an extra include, but it's definitely cross-compatible. In my Mythology mod I've got lines like

Code:
MapModData.Mythology.PlayerFavorData[iPlayer] = pFavor;

and in my Base mod I've got things like

Code:
player_favor = MapModData.Mythology.PlayerFavorData[iPlayerID];

The only thing you need to do to set this up is have lines that runs whenever the game starts up that looks like

Code:
MapModData.Mythology = {};
MapModData.Mythology.PlayerFavorData = {};

And you can use any number of dimensions, as long as you initialize them correctly. For instance, in that same mod I also have

Code:
MapModData.Mythology.CityFavorData[iPlayer][iCity][iFocus] = cFavor;

The only downside is that this data structure doesn't persist across savegames, so you'll need to find some way to save/load tables of arbitrary nesting structure to some sort of saved game database. I'm sure you can find something for that.
 
Ah, thanks for the details. I didn't read your initial response carefully beyond the include suggestion (or really I tried to but didn't know what you were talking about without the code details). This is something I didn't know about. I'll have to look over it. [Edit: remarkable that I didn't know about superglobals. I guess I never needed them before.]

Yes, I am an expert on save/loading tables of arbitrary nesting structure. (The link is for anyone reading this thread that doesn't know how to do this.)
 
Back
Top Bottom