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
spill_item_stack() causes heavy lag
-
- Inserter
- Posts: 44
- Joined: Sat Dec 14, 2019 3:26 am
- Contact:
Re: spill_item_stack() causes heavy lag
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.
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.
Re: spill_item_stack() causes heavy lag
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.
Re: spill_item_stack() causes heavy lag
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?
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?
Re: spill_item_stack() causes heavy lag
That was Klonan's idea in OPs original thread.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.
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.