attempt to index upvalue '_ENV' (a nil value)

Place to get help with not working mods / modding interface.
Post Reply
User avatar
cpeosphoros
Inserter
Inserter
Posts: 40
Joined: Fri Dec 23, 2016 10:57 pm
Contact:

attempt to index upvalue '_ENV' (a nil value)

Post by cpeosphoros »

Hello,

I'm trying to make a modular mod which works like this:

A central mod, called Busy Bots, acts as a controller for other plug-in modules which contain jobs, like cutting trees, laying concrete, upgrading buildings, etc, that would be performed by construction bots in the radii of roboports. The central module would care for the logistics network, ensuring there are always free construction bots, balancing the load between the client modules, etc. All the interaction between those modules would be performed through interfaces.

So, I have interface.lua in Busy Bots, which reads:

Code: Select all

remote.add_interface("busy-bots",
    {
    	-- Registers a job to be worked by Busy Bots
        -- @param job     - a table with these key/values:
    	---- @key name    -	@value the name of the interface for calling back the job being registered.
        ----                That interface must implement a function "doJob" with this contract:
        ------              @param worker - a table with the format {roboport = roboport, 
        ------                              name = string}, roboport is guaranteed to be 
        ------                              a roboport Entity with "roboport" in its name
        ------                              (no Factorissimo buildings, no Recharging
        ------                              stations, etc)
        ------              @param amount - an allowance of how many construction jobs it 
        ------                              can order
        ------              @return a count of how many jobs it actually  performed
        ------
        ------              doJob is responsible for not ordering more construction jobs 
        ------              than its allowed amount.
    	---- @key prior   -	@value a number for this job's priority. The lowest the number, the
    	--					most robots will be allowed to perform this job
        registerJob = function(job)
            global.Registry.registerJob(job)
        end  
    }
)
Then, Registry.registerJob() reads:

Code: Select all

function Registry.registerJob (job)
	if not global.jobs_[job] then 
		-- register the job, etc
	end
end
The client modules, then, on their on_init and on_configuration_change events would call registerJob, and then be called back by the actual working part off Busy Bots.

The problem is, when the client calls

Code: Select all

	global.job = {name="Concreteer", prior=10}
	remote.call("busy-bots", "registerJob", global.job)
I get this stack error:

Code: Select all

Error while running the on_init:
Error when running interface function busy-bots.registerJob: __CpeBusyBots__/registry.lua:26: attempt to index upvalue '_ENV' (a nil value)
stack traceback:
	__CpeConcreteer__/concreteer.lua:179: in function 'load'
	__CpeConcreteer__/control.lua:7: in function <__CpeConcreteer__/control.lua:7>
registry.lua:26 is the line declaring function Registry.registerJob which reads: "function Registry.registerJob (job)"

I'm not explicitly referring _ENV anywhere in my code.

Any clues about what am I doing wrong?

As for background, I'm a programmer with more than 20 years in the job, with large experience with Java but very little with Lua. I'm using Factorio modding as a learning tool for Lua.

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: attempt to index upvalue '_ENV' (a nil value)

Post by Klonan »

You are trying to save a function in the global table,

Something like this:

Code: Select all

global.this_function = function () game.print("Hello function") end
When the game is saved, the lua serializer is unable to save any functions, only tables and some other data types, so the function is not preserved.

User avatar
cpeosphoros
Inserter
Inserter
Posts: 40
Joined: Fri Dec 23, 2016 10:57 pm
Contact:

Re: attempt to index upvalue '_ENV' (a nil value)

Post by cpeosphoros »

Thanks for the quick answer, but, no, I'm not.

The "job" object, which is what is in global, reads "{name="Concreteer", prior=10}".

I've made that mistake just before this, trying to store the callback function into global, and I've got a completely different error message - don't remember it right now.

That was what led me into using interfaces for the communication. Only strings, numbers and Factorio entities (a roboport, to be specific) are being passed around.

User avatar
cpeosphoros
Inserter
Inserter
Posts: 40
Joined: Fri Dec 23, 2016 10:57 pm
Contact:

Re: attempt to index upvalue '_ENV' (a nil value)

Post by cpeosphoros »

After digging around, I found the answer within Factorissimo's connections.lua documentation.

Due to some lua interpreter lifecycle issue, you can't make interface remote calls during on_init or on_configuration_change events, only during full lifecycle events. Probably the environment is not fully formed when those starting-up events are ran.

So, it worked with this in the client side code:

Code: Select all

script.on_event(defines.events.on_tick, function (event) 
	if not global.loaded then
		global.job = {name="Concreteer", prior=10}
		remote.call("busy-bots", "registerJob", global.job)
		global.loaded=true
	end
end)

script.on_configuration_changed(function() global.loaded=false end)
script.on_init(function() global.loaded=false end)
The whole thing is working now, but with a considerable lag - which didn't exist when all components where in the same mod and not having to go through remote. I'll try to solve that.

Thanks for the attention.

Post Reply

Return to “Modding help”