Ghost Scanner

by Optera

Adds a combinator reading ghost requests from the logistic network it's placed in.

Content
1 year, 11 months ago
0.16 - 1.1
12.1K
Circuit network

g Why is it so bad for performance?

2 years ago
(updated 2 years ago)

I mean i have multiple planets and all, but i dont have any "open" requests, still it lags 0,1s every (enter amount it should scan here)

Why?

I mean if there would be 10.000 ghosts i would understand it...? shouldnt it have nothing to do when there are no ghosts?

2 years ago

How many roboports do you have in networks with a sensor?
Since ghosts don't raise build events, it has to check every single roboport's construction area for ghosts.

2 years ago

yeah that might explain i have a very big robo network.

cant we limit the amount of roboports to check (to a number your pciture wont freeze?)

2 years ago

Not if we want consistent data.

Logistic Networks also don't have events when roboports join or leave the network.
To get a valid ghost count all roboports in a network have to be checked the same tick. Next tick a roboport might run out of power and break the network apart.

2 years ago
(updated 2 years ago)

but ehm... is that a problem? what would happen? instead of 10.000 requests we only get 5000..? i dont see a problem. maybe it would take in the end longer, but i would like that much more then a noticable lag every X seconds...?

you could make that just a option which is disabled normal, to help for very big networks

1 year, 11 months ago

This could probably be optimised by limiting the amount of area that's scanned every tick. Instead of scanning every roboport in a network every update it would be possible to just scan 1 ore a few every update and keep track of the ghosts that have been found, after all roboports in a network a scanned this then loop back around to update the ghosts found in the first roboports area. That way the UPS impact is limited and instead of taking more and more UPS in larger networks it just adds to the delay before everything is updated.

1 year, 11 months ago
(updated 1 year, 11 months ago)

This could probably be optimised by limiting the amount of area that's scanned every tick.

Did you read my post?
You can't iterate over one roboport per tick if their number in a network can change wildly between ticks.

If networks had events for roboports running out of power or getting power back I'd have aggregated the entire network area as minimum number of rectangles and cached those for iteration.

1 year, 11 months ago

Well start of by storing a table of all roboports in a list, then iterate over the list once while checking if the roboport is still valid and in the network , once every roboport in that stored list has been iterated over, make a new list with all the roboports in the network, and so on. This should work in theory with the disadvantage that it every roboport in the table has the be checked before new roboports get added to the table, but that just adds some extra delay. You don't need to know what roboports are in a network at every single tick, who cares if it takes a little bit until the scanner registers added/removed roboport area.

1 year, 11 months ago

who cares if it takes a little bit until the scanner registers added/removed roboport area.

I do, when networks break apart it can result in hundreds of incorrectly reported ghosts until scanners in cut off parts update.

This mods aim will always be to provide 100% valid data regardless of performance hit.
If you don't like it, feel free to fork.

1 year, 11 months ago
(updated 1 year, 11 months ago)

ah yeah i forgot youre the ltn dev

1 year, 10 months ago
(updated 1 year, 10 months ago)

Since ghosts don't raise build events

Not sure when this was last the case, but that is not true.
I was wondering why you were scanning instead of just listening to events. As the performance annoyed me a bit as well.

Started a quick mod to mock that, and it seems very possible. I saw you are not actively developing/maintaining mods anymore, so I'll continue on mine for personal use.
If there is any desire from the community I might upload it. Or of course this mod can be updated accordingly too.

(With listening to events there might be a performance hit if there are many bots placing items. But at least no computing power when there are no construction jobs, and the combinator is updated instantly. )

Here are all the events for keeping track of construction jobs:

-- creating ghosts/upgrades
script.on_event(defines.events.on_built_entity, function(event) entity_created(event.created_entity) end)
script.on_event(defines.events.on_marked_for_upgrade, function(event) entity_created(event.entity, event.target) end)
script.on_event(defines.events.on_entity_cloned, function(event) entity_created(event.source) end)
script.on_event(defines.events.script_raised_built, function(event) entity_created(event.entity) end)
-- both creating and deleting ghosts/upgrades
script.on_event(defines.events.on_pre_ghost_upgraded, function(event)
entity_removed(event.ghost)
entity_created(event.ghost, event.target)
end)
-- deleting ghosts/upgrades
script.on_event(defines.events.on_robot_built_entity, function(event) entity_removed(event.created_entity, event.created_entity.prototype) end)
script.on_event(defines.events.on_player_mined_entity, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.on_cancelled_upgrade, function(event) entity_removed(event.entity, event.target) end)
script.on_event(defines.events.on_marked_for_deconstruction, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.on_pre_ghost_deconstructed, function(event) entity_removed(event.ghost) end)
script.on_event(defines.events.on_entity_died, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.script_raised_destroy, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.script_raised_revive, function(event) entity_removed(event.entity) end)


And then entity_removed/created start with

local function entity_created(entity, target)
if not target and entity.type ~= "entity-ghost" then return end
local required_item = (target or entity.ghost_prototype).items_to_place_this[1]


Edit. Forgot about tiles, but easy enough to add too

1 year, 10 months ago
(updated 1 year, 10 months ago)

Last I checked on_built_entity wasn't raised when creating ghosts and the request for such an event was refused.
Also events for monitoring logistic cells or networks where also refused.

PS Yeah, I don't plan on returning to active modding, knock yourself out.

1 year, 10 months ago

Since ghosts don't raise build events

Not sure when this was last the case, but that is not true.
I was wondering why you were scanning instead of just listening to events. As the performance annoyed me a bit as well.

Started a quick mod to mock that, and it seems very possible. I saw you are not actively developing/maintaining mods anymore, so I'll continue on mine for personal use.
If there is any desire from the community I might upload it. Or of course this mod can be updated accordingly too.

(With listening to events there might be a performance hit if there are many bots placing items. But at least no computing power when there are no construction jobs, and the combinator is updated instantly. )

Here are all the events for keeping track of construction jobs:

-- creating ghosts/upgrades
script.on_event(defines.events.on_built_entity, function(event) entity_created(event.created_entity) end)
script.on_event(defines.events.on_marked_for_upgrade, function(event) entity_created(event.entity, event.target) end)
script.on_event(defines.events.on_entity_cloned, function(event) entity_created(event.source) end)
script.on_event(defines.events.script_raised_built, function(event) entity_created(event.entity) end)
-- both creating and deleting ghosts/upgrades
script.on_event(defines.events.on_pre_ghost_upgraded, function(event)
entity_removed(event.ghost)
entity_created(event.ghost, event.target)
end)
-- deleting ghosts/upgrades
script.on_event(defines.events.on_robot_built_entity, function(event) entity_removed(event.created_entity, event.created_entity.prototype) end)
script.on_event(defines.events.on_player_mined_entity, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.on_cancelled_upgrade, function(event) entity_removed(event.entity, event.target) end)
script.on_event(defines.events.on_marked_for_deconstruction, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.on_pre_ghost_deconstructed, function(event) entity_removed(event.ghost) end)
script.on_event(defines.events.on_entity_died, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.script_raised_destroy, function(event) entity_removed(event.entity) end)
script.on_event(defines.events.script_raised_revive, function(event) entity_removed(event.entity) end)


And then entity_removed/created start with

local function entity_created(entity, target)
if not target and entity.type ~= "entity-ghost" then return end
local required_item = (target or entity.ghost_prototype).items_to_place_this[1]


Edit. Forgot about tiles, but easy enough to add too

Would be nice if you uploaded your mod.

1 year, 9 months ago

yeah i second this

10 months ago

@KeinNIemand could you upload your version of the mod please?

New response