[2.0.70] package key calculation for require

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
User avatar
hgschmie
Fast Inserter
Fast Inserter
Posts: 159
Joined: Tue Feb 06, 2024 5:18 am
Contact:

[2.0.70] package key calculation for require

Post by hgschmie »

Both standard lua and the Factorio lua use the package.loaded table to manage files that have already been loaded. However, in Factorio, the standard implementation has been replaced by a custom implementation (it says so at https://lua-api.factorio.com/latest/aux ... -functions).

To allow circular references between packages, standard Lua allows one to do

Code: Select all

local my_stuff = {}
package.loaded[...] = my_stuff
... more code here ...
return my_stuff
to "predefine" the contents of the package.loaded table and resolve circular references.

This works in factorio as well, however, the key is way more complicated, for mod "X", the key is __X__/a/b/c.lua, totally independent if the package was loaded with require('a/b/c.lua') or require('a.b.c').

I ended up using this as the computation for the key: package.loaded['__' .. script.mod_name .. '__/' .. (...):gsub('%.', '/') .. '.lua'] = my_stuff

There has to be a piece of code somewhere in the C++ code base that does that computation. Would it be possible to expose it in the package table? e.g. if that would be exposed as a function called key (which should be able to take the ... varargs passed in when a package gets required, similar to regular lua, then it would be possible to simply write package.loaded[package.key(...)] = my_stuff which would be as close to "regular" lua as it gets.
Last edited by hgschmie on Thu Oct 16, 2025 5:04 pm, edited 1 time in total.
User avatar
hgschmie
Fast Inserter
Fast Inserter
Posts: 159
Joined: Tue Feb 06, 2024 5:18 am
Contact:

Re: package key calculation for require

Post by hgschmie »

Following up on my own post: Having this would be especially beneficial for using mods in data/settings stage, as those don't have `script` available and there is not a good way to find the current mod name. As `require` works fine in those stages (and the keys in the `package.loaded` table have the mod name, this code surely exists somewhere.

Pretty please? ;-)
User avatar
hgschmie
Fast Inserter
Fast Inserter
Posts: 159
Joined: Tue Feb 06, 2024 5:18 am
Contact:

Re: [2.0.70] package key calculation for require

Post by hgschmie »

With 2.1 coming at some point, I’d like to ask again to consider adding support for a stable “package loaded” key to the factorio runtime. It would make life for a lot of use cases (especially circular dependency resolution) so much easier.

It seems to me that something like this should exist in the runtime today, exposing it to the lua api would be great.
hgschmie wrote: Mon Oct 06, 2025 5:18 am Both standard lua and the Factorio lua use the package.loaded table to manage files that have already been loaded. However, in Factorio, the standard implementation has been replaced by a custom implementation (it says so at https://lua-api.factorio.com/latest/aux ... -functions).

To allow circular references between packages, standard Lua allows one to do

Code: Select all

local my_stuff = {}
package.loaded[...] = my_stuff
... more code here ...
return my_stuff
to "predefine" the contents of the package.loaded table and resolve circular references.

This works in factorio as well, however, the key is way more complicated, for mod "X", the key is __X__/a/b/c.lua, totally independent if the package was loaded with require('a/b/c.lua') or require('a.b.c').

I ended up using this as the computation for the key: package.loaded['__' .. script.mod_name .. '__/' .. (...):gsub('%.', '/') .. '.lua'] = my_stuff

There has to be a piece of code somewhere in the C++ code base that does that computation. Would it be possible to expose it in the package table? e.g. if that would be exposed as a function called key (which should be able to take the ... varargs passed in when a package gets required, similar to regular lua, then it would be possible to simply write package.loaded[package.key(...)] = my_stuff which would be as close to "regular" lua as it gets.
Rseding91
Factorio Staff
Factorio Staff
Posts: 16593
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: [2.0.70] package key calculation for require

Post by Rseding91 »

There are some complexities/issues with such a function since internally when a given require() is processed the game goes over several possible resolution options - and the first one to exist on disk is the one that gets used. That isn't such a big issue in itself - except that the logic is intertwined with the actual loading of the results and caching it in the package.loaded table.

A far simpler option seems to be: don't make circular requires. After over 10 years of Factorio you're the first person I've seen attempt it (not that nobody else has, but nobody else has said anything).
If you want to get ahold of me I'm almost always on Discord.
Post Reply

Return to “Modding interface requests”