Error when setting virtual signal in constant-combinator

Pi-C
Smart Inserter
Smart Inserter
Posts: 1770
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Error when setting virtual signal in constant-combinator

Post by Pi-C »

What?
If you try to set the slot of a constant-combinator to a virtual signal via script, this will error if no quality is provided. According to the description of SignalFilter (used by LuaLogisticSection::set_slot(), which has to be used for constant-combinators), all properties except name are optional. The documentation mentions that the value of quality can be "nil for any quality". However, it seems to be mandatory if type is "virtual".

I consider this a bug in either the implementation or the documentation.
How to reproduce
Run the following from the chat console in a vanilla game:

Code: Select all

/c p = game.player; pos = p.position
cc = p.surface.create_entity{name = "constant-combinator", force = p.force, position = {pos.x + 3, pos.y}}
s = cc.get_control_behavior().sections[1]
s.set_slot(1, {min = 1, value = {type = "virtual", name = "signal-A", quality = "normal"}})
s.set_slot(1, {min = 1, value = {type = "virtual", name = "signal-B"}})
This will create a constant-combinator next to the player. If you open the combinator, signal 'A' will be set in the first slot, but slot 2 will be empty. Instead you'll see this message on the command line:

Code: Select all

Cannot execute command. Error: Can't specify non zero request with non trivial item filter condition.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 4178
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Error when setting virtual signal in constant-combinator

Post by boskid »

I will throw this to Not a bug:

1/ Related to "but slot 2 will be empty" -> you called set_slot twice with index 1, because of that slot 2 would never be modified.

2/ SignalFilter allows to skip quality, however that means you are providing a signal filter with an "Any" quality condition. Logistic sections specifically do not allow having one filter to specify a quality range when `min` is non-zero. Quality range is allowed when min is 0 because that is used for auto-trashing, however having logistic section with no quality provided and be used in a requester chest would be ambiguous how many items are requested (is it `min` of each quality or is it up to a total provided regardless of quality).
Pi-C
Smart Inserter
Smart Inserter
Posts: 1770
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Error when setting virtual signal in constant-combinator

Post by Pi-C »

boskid wrote: Mon Sep 08, 2025 9:00 am I will throw this to Not a bug:
Thank you for your reply! As mentioned in my original post, I wasn't sure myself whether this bug should be classified as implementation or documentation bug. If you say it's working as expected, could you move this to Documentation Improvement Requests instead, please?
1/ Related to "but slot 2 will be empty" -> you called set_slot twice with index 1, because of that slot 2 would never be modified.
Sorry, that's not true! Of course I messed up my example by writing to the same slot twice although I meant to write to slots 1 and 2. But if the SignalFilter is correct, slot 1 will be overwritten with "signal-B" the second time:

Code: Select all

/c p = game.player; pos = p.position
cc = p.surface.create_entity{name = "constant-combinator", force = p.force, position = {pos.x + 3, pos.y}}
s = cc.get_control_behavior().sections[1]
s.set_slot(1, {min = 1, value = {type = "virtual", name = "signal-A", quality = "normal"}})
s.set_slot(1, {min = 1, value = {type = "virtual", name = "signal-B", quality = "normal"}})
But this (fixed) still errors when writing to slot 2:

Code: Select all

/c p = game.player; pos = p.position
cc = p.surface.create_entity{name = "constant-combinator", force = p.force, position = {pos.x + 3, pos.y}}
s = cc.get_control_behavior().sections[1]
s.set_slot(1, {min = 1, value = {type = "virtual", name = "signal-A", quality = "normal"}})
s.set_slot(2, {min = 1, value = {type = "virtual", name = "signal-B"}})
2/ SignalFilter allows to skip quality, however that means you are providing a signal filter with an "Any" quality condition. Logistic sections specifically do not allow having one filter to specify a quality range when `min` is non-zero.
It would have been helpful to see this in the documentation. :-)
Quality range is allowed when min is 0 because that is used for auto-trashing, however having logistic section with no quality provided and be used in a requester chest would be ambiguous how many items are requested (is it `min` of each quality or is it up to a total provided regardless of quality).
It's unfortunate that LuaConstantCombinatorControlBehavior is using LuaLogisticSection to begin with, as constant-combinators don't have logistics. I can definitely understand that it's easier to reuse LuaLogisticSection for combinators rather than making a copy of it with some tiny changes at best – but, damn, is that unintuitive! :mrgreen:
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Bilka
Factorio Staff
Factorio Staff
Posts: 3636
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Error when setting virtual signal in constant-combinator

Post by Bilka »

I've updated the docs with this behaviour for 2.0.67.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.
Pi-C
Smart Inserter
Smart Inserter
Posts: 1770
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Error when setting virtual signal in constant-combinator

Post by Pi-C »

Thank you! :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Post Reply

Return to “Resolved Requests”