Adding event trigger for an item stopping at the end of a belt

Things that we aren't going to implement
Post Reply
Techrocket9
Manual Inserter
Manual Inserter
Posts: 4
Joined: Fri Oct 01, 2021 8:40 am
Contact:

Adding event trigger for an item stopping at the end of a belt

Post by Techrocket9 »

I'm working on creating a more performant version of the belt balancer mod.

The current version works by iterating over all balancers in the world every few ticks and processing them one by one.

There is a lot of room to optimize this (the low-hanging fruit improved performance 20%), but to get massive performance gains I need a new architecture for event handling.

Ideally I'd like to add a custom event to Prototype/TransportBeltConnectable that triggers whenever an item stops at the end of a belt and handle this event in my mod to perform belt-balancing activity.

However, looking at the prototype for TransportBeltConnectable it doesn't look like the actual event of an item stopping at the end of a belt is being exposed to Lua.

I think this means that I'm stuck with triggering every n ticks and manually searching each balancer for items that can be processed, but before I commit to writing a more efficient implementation of that I would like to confirm that the ideal solution (adding a custom event for an item stopping at the end of a belt) is in fact impossible.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2244
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Adding event trigger for an item stopping at the end of a belt

Post by boskid »

Belts (transport lines) are updated in multithreaded environment. Such events would not be free in terms of performance because such events would have to be queued for later and then merged into deterministic order before they would be dispatched (which means they would be a deferred events). There is already one such mechanizm with belts and it is the alarm system with wakeup lists where a belt may wake some inserters, loaders or mining drills when the belt is active. I am not going to decide about this yet, but keep in mind it is not simply "add an event", its a whole logistic of making it a deterministic event with as little performance impact as possible when not used.

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Adding event trigger for an item stopping at the end of a belt

Post by mrvn »

Wouldn't loaders or inserters and linked chests be the better solution than doing this in LUA?

Techrocket9
Manual Inserter
Manual Inserter
Posts: 4
Joined: Fri Oct 01, 2021 8:40 am
Contact:

Re: Adding event trigger for an item stopping at the end of a belt

Post by Techrocket9 »

I agree that it sounds nontrivial to implement this trigger if the belt update code is multithreaded. Would be cool if it ended up making the cut though!

As for why not do it with loaders and chests; I'm trying to make a drop-in replacement for the existing mod, which does transparent flow-through balancing.

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Adding event trigger for an item stopping at the end of a belt

Post by mrvn »

Techrocket9 wrote:
Sat Oct 02, 2021 12:21 am
I agree that it sounds nontrivial to implement this trigger if the belt update code is multithreaded. Would be cool if it ended up making the cut though!

As for why not do it with loaders and chests; I'm trying to make a drop-in replacement for the existing mod, which does transparent flow-through balancing.
And?

Make every balancer a linked chest and place hidden loaders or inserter on all the belts going in and out of the balancers. You probably don't even have to wire up the inserters at all to synchonize them. Just let them work round-robin naturally and you have everything balanced.

Tell my why that wouldn't work.

Techrocket9
Manual Inserter
Manual Inserter
Posts: 4
Joined: Fri Oct 01, 2021 8:40 am
Contact:

Generalizing the feature request

Post by Techrocket9 »

mrvn wrote:
Sat Oct 02, 2021 11:38 am
Tell my why that wouldn't work.
Taking another crack at this; I did some experiments with linked containers and loaders.

Image

It works pretty well in the supply-shortage case -- with 500 input items I saw a range of ~8 item variance from the most favored output to the least (among 16). Not perfect (like the mod I'm trying to replace), but probably acceptable under real-world conditions.

The rub comes when you have a supply-surplus. In this case the loader arrangement seems to greatly favor a single source -- in the experiment on the right one chest was drained completely (>9K items taken) while the others had ~80 items taken each.

A 100:1 spread is pretty terrible for a system aspiring to balance inputs and outputs. The possibility of pushing the balancing workload into the C++ layer by using linked containers and loaders is tantalizing for its performance benefits, but to truly make a fair balancer we would need to be able to hook the loaders and force round-robin sequencing, but as it stands I think we're stuck using Lua to enforce round robin behavior.

As far as the modding API request goes, I suppose we can generalize it to "event for item stopping at end of belt or ability to force round-robin on specific sets of loaders, whichever is easier".
Last edited by Techrocket9 on Mon Nov 29, 2021 2:00 am, edited 1 time in total.

Techrocket9
Manual Inserter
Manual Inserter
Posts: 4
Joined: Fri Oct 01, 2021 8:40 am
Contact:

P.S.

Post by Techrocket9 »

Oh also the linked container + loaders approach breaks down pretty badly if you have multiple kinds of items coming down the pipe, but that's another limitation that is probably fine™ in real world use.

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Generalizing the feature request

Post by mrvn »

Techrocket9 wrote:
Mon Nov 29, 2021 1:01 am
mrvn wrote:
Sat Oct 02, 2021 11:38 am
Tell my why that wouldn't work.
Taking another crack at this; I did some experiments with linked containers and loaders.
What about linked containers and inserters? I know inserters taking from e.g. an assembler work round-robin and take equally at least with stack size = 1. With higher stack size 3 plates can be split 2:1 every time.

Post Reply

Return to “Won't implement”