spill_item_stack() causes heavy lag

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
-DeadlyKitten
Inserter
Inserter
Posts: 44
Joined: Sat Dec 14, 2019 3:26 am
Contact:

spill_item_stack() causes heavy lag

Post by -DeadlyKitten »

the command spill_item_stack() causes unnecessarily heavy lag due to needing to find where to drop repeatedly.

this is shown in the following example
on my machine the following code takes 2 seconds.

/c player = game.player
for i=1,1 do
player.surface.spill_item_stack({0, 0}, {name="iron-plate", count=100000}, true, player.force, true)
end

while this code takes 16 seconds.

/c player = game.player
for i=1,1000 do
player.surface.spill_item_stack({0, 0}, {name="iron-plate", count=100}, true, player.force, true)
end

both have identical results but the 2nd is divided into stacks of 100

this is important due to the most common use case looking something like this, going through an inventory and spilling everything on the same location.

for i=1,#inventory do
if inventory.valid_for_read then
player.surface.spill_item_stack(player.position, inventory, true, player.force, true)
inventory.count = 0
end
end

(code from https://mods.factorio.com/mod/muppet_streamer)

this is far closer to the slow case and so takes a long time.

my request would be to either allow spill_item_stack() to take in a list of stacks or to cache the searched area for the duration of the tick (only a single tick is likely necessary)
the list of stacks should be the same format as an inventory so coping the reference of the inventory directly into the command works
mrvn
Smart Inserter
Smart Inserter
Posts: 5969
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: spill_item_stack() causes heavy lag

Post by mrvn »

This makes me wonder how often you spill items on the ground and from what. 1000 stacks of iron are a lot. But then again angles-warehouse has iirc 720 slots. So spilling that on deconstruction would be nearly your test case. And 16s for the game to hang is a lot. Would a multiplayer game handle that at all?

My guess is the spilling goes in a spiral and if there is space it drops an item. So each successive call has to spiral out further and further retesting the same spots over an over. Probably the same guess as you had.

Other than the devs fixing this have you considered randomizing the placement of each stack? Take the number of stacks (or better total items) to calculate a suitable radius. Then pick random spots in that radius and drop a stack there. The radius should be large enough so stacks of items drop into different heaps but small enough so they still overlap a bit. I think that would even look better than the big square spiral of items you get now.
PFQNiet
Filter Inserter
Filter Inserter
Posts: 290
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: spill_item_stack() causes heavy lag

Post by PFQNiet »

A `spill_inventory()` function would be nice. Among other uses, it could take the temporary LuaInventory buffer from a `player_mined_entity` event and spill that.
mrvn
Smart Inserter
Smart Inserter
Posts: 5969
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: spill_item_stack() causes heavy lag

Post by mrvn »

How does item spilling work when you abort hand crafting?

Fill your inventory with all the ingredients, craft all of something that takes many intermediate steps. Fill your inventory again with something else. Abort all crafts. Now all the ingredients end up spilled on the ground and I don't remember that taking 16s.

Maybe there already is a C++ function to spill a list of stacks or one that remembers where it left of spilling?
User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 582
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: spill_item_stack() causes heavy lag

Post by Silari »

PFQNiet wrote: Mon Sep 13, 2021 4:01 pm A `spill_inventory()` function would be nice. Among other uses, it could take the temporary LuaInventory buffer from a `player_mined_entity` event and spill that.
That was Klonan's idea in OPs original thread.

Isn't there a way to create an inventory in the API for scripting purposes too? So for OPs use case above you could create an inventory, transfer all the stacks you want to spill to that inventory, then spill_inventory() on it. Might be simpler to implement than my suggestion, and should be able to cover all the same use cases.
Post Reply

Return to “Modding interface requests”