Libraries?

Thalassicus

Bytes and Nibblers
Joined
Nov 9, 2005
Messages
11,057
Location
Texas
I have a library of lua functions I'd like to use across multiple mods. It's similar to the "Ace" library in wow lua programming.

I added my library to as a "dependency" association of the mod which will use the library. I then added an include("CivupLibrary.lua") to my target mod file. However, when I called one of the library functions, I encountered an error message that the function does not exist. What might have I done wrong?
 
Lua contexts are sand-boxed - they intentionally can't call functions in Mod A from Mod B - so unless CivupLibrary.lua is included in your mod and imported (via VFS=true) this is not going to work.

You can get some of the effects of a shared library via LuaEvents, but to return values from the functions you will have to provide a wrapper API to unpack values from a table passed as a parameter
 
I was just testing this myself and was able to call functions between different mods. Although it's true what Whoward69 said, but there is a way around these sandboxes.

Method is to piggyback a globally exposed table. It even has the same function id on both cases so it's not a copy. It's kind of a hack, but it works. In your code you could implement this quite simply by using packages.

Code:
Mod A:
local G = {}
MyLibraryPackage = G
function G.MyFunction()
	return "test"
end
--GameTypes is a globally exposed table
GameTypes.MyLibrary = MyLibraryPackage

Mod B:
local G = GameTypes.MyLibrary
G.MyFunction()
>> test

Of course you should be very VERY careful when doing anything with globally exposed tables. Just taking baby steps with this one so don't know if that GameTypes table is even safe to use?
 
I'll post this as an alternative that makes use of the (supposedly) support LuaEvent mechanism, rather than using a mechanism that may or may not be removed in future (as there is no reason why those tables need to be a) globally exposed or b) writeable)

Code:
-- This is the Library code and lives in the common Library mod
function LibX(a, b, c)
  -- Do something useful
end

function ILibX(result, a, b, c)
  result.value = LibX(a, b, c)
end
LuaEvents.LibX.Add(ILibX)


-- This is the Lib.lua "header" file provided as part of the common library, but included in any mod that needs access to the library (with VFS=true)
function LibX(a, b, c)
  result = {}
  LuaEvents.LibX(result, a, b, c)
  return result.value
end


-- This is the code in the mod that needs to use the library
include("Lib")
x = LibX(l, m, n)

If your library is implemented as a class you can make use of variable parameters and marshal the method name into the LuaEvent parameters and that way you only need one event to access the full library
 
I had changed the name of a file in the library, but not changed the corresponding include() statements in the target mod. After correcting that mistake everything worked. The code posted above does not appear to be necessary with the new dependency system. Unless I'm overlooking something, it works as you'd expect libraries to work in other languages like c++... 1) set dependency 2) include the file and 3) use the functions, like it's in the same mod.

ModTools.lua within library mod:
PHP:
function DoCrossmodTest()
    return "success"
end
Target mod:
PHP:
include("ModTools.lua")

if DoCrossmodTest then
    print(tostring(DoCrossmodTest()))
end
Output:
Code:
[13639.011] GET_Events: success
 
Lua contexts are sand-boxed - they intentionally can't call functions in Mod A from Mod B - so unless CivupLibrary.lua is included in your mod and imported (via VFS=true) this is not going to work.

Yeah, that's just not true. My entire 4-mod set was structured around all of my utility functions being in my "Base" mod, but they'd be used in my other three.

All you need is VFS=true. There's no Dependency requirement, and it works just fine for most utility functions. The ONLY problems I ever ran into were if the functions involved required something like SaveUtils, which needed a unique identifier for that mod, or if they required an added schema/table in the XML (like BuildingResources did). But if you just want a simple utility function that's accessible from any other mod, it's not hard to do.
 
Back
Top Bottom