on_module_changed (assembler, furnace)

Things that we aren't going to implement
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

on_module_changed (assembler, furnace)

Post by eradicator »

What?:
An event that is raised when the module configuration of an assembler or furnace changes. Containing:

Code: Select all

event.entity  --the entity which had its module inventory content changed
event.player --the player who did the changing if any (optional)
event.modules --a list of module names that are in the assembler now (this is the part i need. i don't need the actual stack. but that's an implementation detail not up to me to decide) (optional)
Why?:
I'm trying to implement some special modules that do not directly affect the internals of assemblers (i.e. not speed, productivity, etc) but rather they affect certain parameters that my script considers when handling logic related to an assembler. This works by reading an assemblers inventory (currently once on initial parsing) and detecting if a module of a certain name (pattern) is inserted into the assembler. Of course i'd like to only check assemblers as rarely as possible, but currently the only way to detect if the module inventory changed after the initial setup seems to be to run through a cached list of entities in on_tick and read their inventory one-by-one.
As assembler module inventories can not be automatically changed this should not have any significant performance impact? (Beacon modules can theoretically be automated but even if they are they probably don't change that often? Personally i only need the event for assemblers, but not raising it for beacons would look odd?)
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14601
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: on_module_changed (assembler, furnace)

Post by Rseding91 »

This isn't currently possible because mods can't be trusted.

Example:
  • The game is transferring all modules from the characters inventory into an assembling machine
  • The first module into the inventory fires the event
  • The mod destroys the character and switches the player to the god controller in the event
  • The game goes back to finish transferring the rest of the modules from a now deleted character and it crashes
To make this work would take too much time and have too much of a performance loss for what little it would gain.
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: on_module_changed (assembler, furnace)

Post by eradicator »

Rseding91 wrote:
  • The game is transferring all modules from the characters inventory into an assembling machine
  • The first module into the inventory fires the event
I'd be perfectly fine if the last module transfered triggered the event (i.e. after the engine is done with everything it's going to do to that inventory in that tick). After all i'm only interested in the complete new state of the machine, and not in some incomplete tick-intermediate state where more changes are going to happen in the same tick... call it on_post_module_configuration_changed maybe? Of course if that's still too much time and performance i'll just have to go back to on_tick :/.

And as much as i agree with "mods can't be trusted" couldn't the same argument be made for many events? What if i delete the player in any of the on_player_xyz_inventory_changed events, that works fine doesn't it? What about on_pre_player_died? etc. So far i always assumed all events are raised after the event.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14601
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: on_module_changed (assembler, furnace)

Post by Rseding91 »

eradicator wrote:
Rseding91 wrote:
  • The game is transferring all modules from the characters inventory into an assembling machine
  • The first module into the inventory fires the event
I'd be perfectly fine if the last module transfered triggered the event (i.e. after the engine is done with everything it's going to do to that inventory in that tick). After all i'm only interested in the complete new state of the machine, and not in some incomplete tick-intermediate state where more changes are going to happen in the same tick... call it on_post_module_configuration_changed maybe? Of course if that's still too much time and performance i'll just have to go back to on_tick :/.

And as much as i agree with "mods can't be trusted" couldn't the same argument be made for many events? What if i delete the player in any of the on_player_xyz_inventory_changed events, that works fine doesn't it? What about on_pre_player_died? etc. So far i always assumed all events are raised after the event.
Virtually all events are raised when the thing happens. To make it happen "after" means we have to store the fact it happened somewhere in the game state data which gets included in the save file.

Additionally something like an entity died event can't be fired "after" because after an entity dies it's removed from the game.

Almost every event has a ton of protection built around it to handle the fact mods do weird things during events but that doesn't mean they're perfect. I know some specific actions that mods could theoretically do that would end up crashing the game. I just haven't fixed them yet because nobody has actually done it yet and it will be a lot of work to make them all "mod safe".
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: on_module_changed (assembler, furnace)

Post by eradicator »

Well, i meant "after" in an "after the engine did its thing but in the same function" kinda way. I.e. that the last thing done during event handling is handing the event to mods. But ofc that doesn't help if the current transfer_module action happens on a per module basis and doesn't know about any other modules transfered after it in the same tick. ;/

So i 'll just have to stick to the slow workaround...or rethink the concept :(.
Thanks for the detailed answers though. They are appreciated :):
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
User avatar
Therax
Filter Inserter
Filter Inserter
Posts: 471
Joined: Sun May 21, 2017 6:28 pm
Contact:

Re: on_module_changed (assembler, furnace)

Post by Therax »

eradicator wrote:What?:
An event that is raised when the module configuration of an assembler or furnace changes. Containing:

Code: Select all

event.entity  --the entity which had its module inventory content changed
event.player --the player who did the changing if any (optional)
event.modules --a list of module names that are in the assembler now (this is the part i need. i don't need the actual stack. but that's an implementation detail not up to me to decide) (optional)
Why?:
I'm trying to implement some special modules that do not directly affect the internals of assemblers (i.e. not speed, productivity, etc) but rather they affect certain parameters that my script considers when handling logic related to an assembler. This works by reading an assemblers inventory (currently once on initial parsing) and detecting if a module of a certain name (pattern) is inserted into the assembler. Of course i'd like to only check assemblers as rarely as possible, but currently the only way to detect if the module inventory changed after the initial setup seems to be to run through a cached list of entities in on_tick and read their inventory one-by-one.
As assembler module inventories can not be automatically changed this should not have any significant performance impact? (Beacon modules can theoretically be automated but even if they are they probably don't change that often? Personally i only need the event for assemblers, but not raising it for beacons would look odd?)
This seems like a case where you could avoid polling all of the possible assembler/furnace entities by doing something like what I'm doing in Miniloader's on_wire_placed: tracking player cursor_stack & selections and opened GUIs to watch only 1 or 2 entities per player. Most of the time you wouldn't need an on_tick handler registered at all. For bots, you could watch for creation and destruction of item-request-proxy entities to similarly narrow down the set of assemblers/furnaces that need to be polled. Pardon me if this is something you're already doing or considering doing. :)

If that sounds interesting, I might extend my on_wire_placed to be a more general on_entity_state_changed library, watching circuit connections, module inventories, recipe changes (for assemblers, since furnaces can change on their own), circuit condition changes, etc.
Miniloader — UPS-friendly 1x1 loaders
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: on_module_changed (assembler, furnace)

Post by eradicator »

Therax wrote:This seems like a case where you could avoid polling all of the possible assembler/furnace entities by doing something like what I'm doing in Miniloader's on_wire_placed: tracking player cursor_stack & selections and opened GUIs to watch only 1 or 2 entities per player. Most of the time you wouldn't need an on_tick handler registered at all. For bots, you could watch for creation and destruction of item-request-proxy entities to similarly narrow down the set of assemblers/furnaces that need to be polled. Pardon me if this is something you're already doing or considering doing. :)

If that sounds interesting, I might extend my on_wire_placed to be a more general on_entity_state_changed library, watching circuit connections, module inventories, recipe changes (for assemblers, since furnaces can change on their own), circuit condition changes, etc.
Hi :), thanks for the hints. I remember that on_wire_changed thread ^^. Sure, i could try watching all instances in which the module inventory changed. The question remains if i can get it precise and fast enough ^^. Do proxy requests fire any kind of event when they're fullfilled? Haven't done much with those yet. For the moment i've postponed the feature and am rethinking if it's worth it without a proper event (effort and gameplay wise). If you generalize your library i'm sure there'd be some ppl happy about that. Though i highly doubt i'd personally use it for various reasons (though i might get some inspiration from yours if the license allows it :P).
User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: on_module_changed (assembler, furnace)

Post by bobingabout »

Rseding91 wrote:This isn't currently possible because mods can't be trusted.

Example:
  • The game is transferring all modules from the characters inventory into an assembling machine
  • The first module into the inventory fires the event
  • The mod destroys the character and switches the player to the god controller in the event
  • The game goes back to finish transferring the rest of the modules from a now deleted character and it crashes
To make this work would take too much time and have too much of a performance loss for what little it would gain.
I can account for that.

check button name, button name matches, delete button, checks to see if the button matches the next name, button doesn't exist, game crashes.

Though that's just bad code, adding a check to make sure the button is valid during each check solves the issue.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: on_module_changed (assembler, furnace)

Post by darkfrei »

Rseding91 wrote:This isn't currently possible because mods can't be trusted.

Example:
  • The game is transferring all modules from the characters inventory into an assembling machine
  • The first module into the inventory fires the event
Why first module, but not table of inserted modules? The same as tiles placing or item stack inserting.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14601
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: on_module_changed (assembler, furnace)

Post by Rseding91 »

darkfrei wrote:
Rseding91 wrote:This isn't currently possible because mods can't be trusted.

Example:
  • The game is transferring all modules from the characters inventory into an assembling machine
  • The first module into the inventory fires the event
Why first module, but not table of inserted modules? The same as tiles placing or item stack inserting.
Because it doesn't know what all modules will be transferred. The logic starts inside the player and says "transfer modules from inventory to destination" with destination being an entity, your quickbar/inventory, and even another item. The game transfers items 1 stack at a time and when it's all done the player has no idea what items went where in the destination.

Or the transfer could start from a mod calling "insert", or a mod could call set_stack, or a player could call that through the console, or a robot could be mining the entity and it's transferring the modules out into the robot inventory 1 stack at a time.

There are so many entry points that can manipulate inventories/items that it's not time-feasible to try to account for all of them to add an event like this.
If you want to get ahold of me I'm almost always on Discord.
protocol_1903
Fast Inserter
Fast Inserter
Posts: 133
Joined: Fri Sep 09, 2022 4:33 pm
Contact:

Re: on_module_changed (assembler, furnace)

Post by protocol_1903 »

Pinging thread because times might have changed and it might be easier to implement now.

Also,
eradicator wrote: Mon Feb 05, 2018 2:22 pm Do proxy requests fire any kind of event when they're fullfilled? Haven't done much with those yet.
Did you ever figure that out? Otherwise, I'm going to have to use a few different tracking methods similar to the ones mentioned in an earlier post.
If you need to reach me, message me on discord.

I make qol mods. Check them out, maybe.
https://mods.factorio.com/user/protocol_1903
If you have a mod idea, I can look into it.
curiosity
Filter Inserter
Filter Inserter
Posts: 515
Joined: Wed Sep 11, 2019 4:13 pm
Contact:

Re: on_module_changed (assembler, furnace)

Post by curiosity »

protocol_1903 wrote: Tue Apr 02, 2024 6:37 pm Did you ever figure that out? Otherwise, I'm going to have to use a few different tracking methods similar to the ones mentioned in an earlier post.
on_entity_destroyed
protocol_1903
Fast Inserter
Fast Inserter
Posts: 133
Joined: Fri Sep 09, 2022 4:33 pm
Contact:

Re: on_module_changed (assembler, furnace)

Post by protocol_1903 »

curiosity wrote: Wed Apr 03, 2024 2:01 am on_entity_destroyed
Register the proxy request?
If you need to reach me, message me on discord.

I make qol mods. Check them out, maybe.
https://mods.factorio.com/user/protocol_1903
If you have a mod idea, I can look into it.
Post Reply

Return to “Won't implement”