Hi, I’m the original poster.
The only way I could think of solving this is to generate a bunch of headers and pass it to the modules.
In this example, I put the function headers in a block of code that won’t execute at all in runtime but would be picked up by the editor. The header block is generated at runtime once all modules have loaded into it.
local AGENT = {}
if not RECOMPILE_FUNC_HEADERS then
function AGENT:AutoTurn() : nil end
function AGENT:Avoid() : nil end
function AGENT:BindResetFunction() : nil end
function AGENT:CheckTarget() : nil end
...
function AGENT:TurnTo() : nil end
function AGENT:UpdateTarget() : nil end
function AGENT:UpdateTargetSightline() : nil end
function AGENT:VerifyPather() : nil end
function AGENT:Wander() : nil end
end
if RECOMPILE_FUNC_HEADERS then
local list = {}
for i,v in pairs(AGENT) do
if type(v) == "function" and not internalFuncNames[i] then
table.insert(list, string.format("function AGENT:%s() : nil end", i))
end
end
table.sort(list)
for _,e in pairs(list) do
print(e)
end
end
return AGENT
You can also take advantage of export type and pass the data structure around for the auto complete to work with.
export type LoadedModule = {
ModuleA: {
FunctionA1: (string) -> (boolean),
FunctionA2: (string) -> (nil),
},
ModuleB: {
FunctionB1: (string) -> (boolean),
FunctionB2: (string) -> (nil),
FunctionB3: (LoadedModule, number, number) -> (nil),
},
}
local mainModule: LoadedModule = {}
for _, module in script:GetChildren() do
for name, value in require(module) do
mainModule[name] = value
end
end
return mainModule
Again, you need to manually put in the function names, the parameters and their types, and the output.
All of this work is very tedious, but it works. You can automate it if you write a plugin to scan the lines of code and generate new header code based on that, but no one’s done it yet. I haven’t felt the need to do that yet since in most applications I only needed to look at 1-2 scripts within the module set to get stuff working.