Make possibility to send a table from data.lua to control.lua

Things that we aren't going to implement
Post Reply
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Make possibility to send a table from data.lua to control.lua

Post by darkfrei »

Hi all!

It would be nice for mods, where control.lua uses some information from data stage.

For example this mod https://mods.factorio.com/mods/darkfrei/MineralGoo

I need all ores (vanilla and from all mods), that isn't infinite. So, now it's possible to send one table by making a lot of flying-text prototypes.

Can we have some prototype, where we can save one custom_table? A lot of prototypes is not better for performance.

posila
Factorio Staff
Factorio Staff
Posts: 5201
Joined: Thu Jun 11, 2015 1:35 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by posila »

darkfrei wrote:For example this mod https://mods.factorio.com/mods/darkfrei/MineralGoo

I need all ores (vanilla and from all mods), that isn't infinite. So, now it's possible to send one table by making a lot of flying-text prototypes.
You can get this through LuaEntityPrototype interface http://lua-api.factorio.com/latest/LuaE ... otype.html

Code: Select all

/c for k,p in pairs(game.entity_prototypes) do if (p.infinite_resource ~= nil) and not p.infinite_resource then game.print(p.name) end end

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

Re: Make possibility to send a table from data.lua to control.lua

Post by Klonan »

darkfrei wrote:Hi all!

It would be nice for mods, where control.lua uses some information from data stage.

For example this mod https://mods.factorio.com/mods/darkfrei/MineralGoo

I need all ores (vanilla and from all mods), that isn't infinite. So, now it's possible to send one table by making a lot of flying-text prototypes.

Can we have some prototype, where we can save one custom_table? A lot of prototypes is not better for performance.
Having you pass arbitrary information from data to control isn't reliable,
For instance in this case, if a mod updates all the ores after you make your flying text, your information will be incorrect

It is better to ask for specific information to be added to the API, and it is more suitable in the long term

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

Klonan wrote:
Thu Oct 26, 2017 1:50 pm
darkfrei wrote:Hi all!

It would be nice for mods, where control.lua uses some information from data stage.

For example this mod https://mods.factorio.com/mods/darkfrei/MineralGoo

I need all ores (vanilla and from all mods), that isn't infinite. So, now it's possible to send one table by making a lot of flying-text prototypes.

Can we have some prototype, where we can save one custom_table? A lot of prototypes is not better for performance.
Having you pass arbitrary information from data to control isn't reliable,
For instance in this case, if a mod updates all the ores after you make your flying text, your information will be incorrect

It is better to ask for specific information to be added to the API, and it is more suitable in the long term
I'm actually running into a situation where being able to do as the OP was requesting would be good.

I'm working on a mod now that makes it so some entities and entity types (trees, worms, resources, cliffs) collide with "artificial" tiles (stone path, concrete, etc). In control.lua, when the mod is first loaded or a setting is changed on an on-going game, I parse through the affected entities to see if they now collide with a tile that they didn't before and, if so, remove said tile.

I want to be able to allow other modders to register their entities for this as well. I've figured out that through the use of a global variable in the data stage, I can make my collision_mask available to them (even a function stored in the global variable that they can call so I can do the work of adding the mask - properly - for them). However, for the control stage, I have no way of knowing which of all the entities in the game these other modders may have altered without just parsing through every entity in the game.

I'd love the ability to, as these modders are calling my global function, store the entity name into a separate table that can then be passed on to the control stage for my mod to make use of. With that, when the mod is first loaded into an existing save, or someone enables one of the entity categories in my settings, I can then just parse through this table that's been passed up from the data stage to hit only what I need to, rather than all of certain entity types (worms are turrets...) or even just all entities in the whole game.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

Qon
Smart Inserter
Smart Inserter
Posts: 2119
Joined: Thu Mar 17, 2016 6:27 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by Qon »

FuryoftheStars wrote:
Thu Jun 02, 2022 6:38 pm
However, for the control stage, I have no way of knowing which of all the entities in the game these other modders may have altered without just parsing through every entity in the game.
Only once per save file load. How long do you think it takes to loop through a list of entity prototypes once?

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

Qon wrote:
Thu Jun 02, 2022 6:45 pm
FuryoftheStars wrote:
Thu Jun 02, 2022 6:38 pm
However, for the control stage, I have no way of knowing which of all the entities in the game these other modders may have altered without just parsing through every entity in the game.
Only once per save file load. How long do you think it takes to loop through a list of entity prototypes once?
Aside from not wanting to make assumptions on the end user's hardware, looping through all the prototypes doesn't help me. Without being able to pass something up from data to control, I don't have any guaranteed ways (that I'm aware of) of detecting my mod's collision mask, which means I have to assume any entity prototype could be affected, which in turn means looping through every entity on every surface of the existing save. Imagine a mega-base applying this mod?

Edit: And just to put it out there, I use collision_mask_util.get_first_unused_layer() for getting a collision mask so I don't have to worry about compatibility with another mod.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

Pi-C
Smart Inserter
Smart Inserter
Posts: 1648
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by Pi-C »

FuryoftheStars wrote:
Thu Jun 02, 2022 6:49 pm
Without being able to pass something up from data to control, I don't have any guaranteed ways (that I'm aware of) of detecting my mod's collision mask, which means I have to assume any entity prototype could be affected, which in turn means looping through every entity on every surface of the existing save. Imagine a mega-base applying this mod?
Do you know LuaGameScript.get_filtered_entity_prototypes and LuaGameScript.entity_prototypes? (There are similar functions for other prototypes as well: items, tiles, etc.)

I usually compile a list of all prototypes I'm interested in in on_init and store that in my global table. It won't ever change -- unless mods are added/removed/updated or startup settings are changed. In this case, on_configuration_changed will trigger and I can rebuild the list, and find all entities based on these prototypes to perform whatever checks I need. Going over all entities on all surfaces may take a while when you have a big base. But that will happen just once until the configuration is changed again.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

Pi-C wrote:
Thu Jun 02, 2022 7:10 pm
FuryoftheStars wrote:
Thu Jun 02, 2022 6:49 pm
Without being able to pass something up from data to control, I don't have any guaranteed ways (that I'm aware of) of detecting my mod's collision mask, which means I have to assume any entity prototype could be affected, which in turn means looping through every entity on every surface of the existing save. Imagine a mega-base applying this mod?
Do you know LuaGameScript.get_filtered_entity_prototypes and LuaGameScript.entity_prototypes? (There are similar functions for other prototypes as well: items, tiles, etc.)

I usually compile a list of all prototypes I'm interested in in on_init and store that in my global table. It won't ever change -- unless mods are added/removed/updated or startup settings are changed. In this case, on_configuration_changed will trigger and I can rebuild the list, and find all entities based on these prototypes to perform whatever checks I need. Going over all entities on all surfaces may take a while when you have a big base. But that will happen just once until the configuration is changed again.
Yes, and I use the get_filtered_entity_prototypes as of right now. However, again, if someone in the data stage adds this mask to say, an assembling machine of theirs, I have no way of knowing this in the control stage. I can cycle through game.entity_prototypes and check their masks, sure, but again, how do I guarantee a way of knowing which mask was returned from collision_mask_util.get_first_unused_layer() in data? And if they only apply this to their specific assembler, not all assemblers, why should I cycle through all assembling machines for this? If I had their entity prototype name at my finger tips, I could just .get_filtered_entity_prototypes(name = whatever) and have just those.

Yes, it's one cycle on load. Again, putting aside assumptions about machine hardware and load times, what's the harm in the request? Wouldn't this make it easier so we don't have to cycle through everything in the first place?

Edit: I want to make the point here, without this ability, if I want to open this up to other modders tagging onto my mod's functionality, then I have to give up all pretense of trying to filter to only those that could be affected, and just cycle through everything.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by robot256 »

FuryoftheStars wrote:However, for the control stage, I have no way of knowing which of all the entities in the game these other modders may have altered without just parsing through every entity in the game.
This is commonly done in the control stage with a remote interface that the other mod calls in on_init and on_configuration_changed to register a particular entity with your mod. It means the other mod has to have code in both data and control, but avoids you having to search for them.

Another way I have done it is with a hidden dummy technology, and add an "unlock effect" for every item/entity in a particular category. Other mods in data phase could call a global function of yours to append items to the dummy tech unlock list. Then you read the tech prototype contents in your control phase.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

robot256 wrote:
Thu Jun 02, 2022 8:39 pm
FuryoftheStars wrote:However, for the control stage, I have no way of knowing which of all the entities in the game these other modders may have altered without just parsing through every entity in the game.
This is commonly done in the control stage with a remote interface that the other mod calls in on_init and on_configuration_changed to register a particular entity with your mod. It means the other mod has to have code in both data and control, but avoids you having to search for them.

Another way I have done it is with a hidden dummy technology, and add an "unlock effect" for every item/entity in a particular category. Other mods in data phase could call a global function of yours to append items to the dummy tech unlock list. Then you read the tech prototype contents in your control phase.
Yeah, I had considered remote interface as a last resort. I mean, I didn't want to force a mod to have to include a control.lua file for just that, plus I considered the possibility that they may have procedurally generated entities and names and this would mean having to have a second instance of that code.

I might give that hidden dummy tech a try, though. Thanks. Seems like my best shot at the moment. Still think it'd be better if they included a native/non-hacky way of doing it, though. :D
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

robot256 wrote:
Thu Jun 02, 2022 8:39 pm
Another way I have done it is with a hidden dummy technology, and add an "unlock effect" for every item/entity in a particular category. Other mods in data phase could call a global function of yours to append items to the dummy tech unlock list. Then you read the tech prototype contents in your control phase.
Hmm, this doesn't appear to be working for me. All of the different effect types seem to want to validate what I'm putting in there. Even the "nothing" type, while it'll accept my inputs, comes out in control stage as nil. Is there one I'm missing that'll just accept (and preserve) any string? They are all entities, but many don't have items or recipes associated with them. :/
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by robot256 »

It's been a while. I just checked how I do it in Multiple Unit Train Control, and I actually make a dummy recipe for each entry too. So, no easy answer.

If the info you want can be extracted from existing prototype data, I agree with Pi-C that searching for it every time is best. We all do it, and it's so much easier than debugging complicated migrations.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

Ok, cycling through all entities in existence it is, then. Remote interface isn't working out, either. :/
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by robot256 »

Don't know if this was clear from before. But you should only do the search in on_init and on_configuration_changed, and store the list in global. That way it only runs after updates, when you know the prototypes might have changed. It won't have to run every time you load the save file.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

robot256 wrote:
Fri Jun 03, 2022 2:22 am
Don't know if this was clear from before. But you should only do the search in on_init and on_configuration_changed, and store the list in global. That way it only runs after updates, when you know the prototypes might have changed. It won't have to run every time you load the save file.
Yes, that was clear, although in my case, as I have no way of telling which entities were touched from control stage without the data stage pass-through, I just need to process all of them anyway. But yeah, only in on_init and on_configuration_changed.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by robot256 »

If it helps, find_entities_filtered can search for entities with a specific collision mask layer (at the same time as other conditions). You may not need to do anything special in Lua at all.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

Except I don’t have access to the layer name in the control stage anymore as it was generated via the collision_mask_util.get_first_unused_layer() function in data.

Edit: Well, as it is only 1 thing and thus much more manageable, I could use the technology trick you mentioned by creating a dummy item who’s name is the used mask layer…. That could work as a work around for now. I’ll have to try it tomorrow.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

PFQNiet
Filter Inserter
Filter Inserter
Posts: 289
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by PFQNiet »

Presumably you have a known entity or tile in your mod that uses the mask layer? Since you know that entity's name, you can look up its collision mask in control and there you go.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2530
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by FuryoftheStars »

PFQNiet wrote:
Sun Jun 05, 2022 8:48 am
Presumably you have a known entity or tile in your mod that uses the mask layer? Since you know that entity's name, you can look up its collision mask in control and there you go.
And how do you guarantee that another mod doesn’t add a mask of its own?
FuryoftheStars wrote:
Fri Jun 03, 2022 3:31 am
Edit: Well, as it is only 1 thing and thus much more manageable, I could use the technology trick you mentioned by creating a dummy item who’s name is the used mask layer…. That could work as a work around for now. I’ll have to try it tomorrow.
This worked as a work around. It’d still be better if a table could be passed up, as then I could prefetch and even sort all of the affected entities during the data stage, which would then make detecting changes to this list easier in control, shifting some of the load time to startup instead of map load.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: Make possibility to send a table from data.lua to control.lua

Post by robot256 »

It wouldn't be arbitrary data, but a new prototype for "custom collision layer" would make a lot of sense. Sort of like how we have to define item groups and subgroups. The collision layer framework has been growing ad-hoc and the next step is a way to tag new layers in a persistent manner.

Post Reply

Return to “Won't implement”