Provide SimpleCombinatorPrototype prototype

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
User avatar
Hares
Fast Inserter
Fast Inserter
Posts: 127
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Provide SimpleCombinatorPrototype prototype

Post by Hares »

TL; DR
Allow creating prototypes for custom combinators with separated in- and out- I/O points.

What?
Option A: Expose CombinatorPrototype
The easiest solution is to make the already-existing CombinatorPrototype class as non-abstract and thus allow the creation of prototypes of its type. BTW, it does not even have "Abstract" in its name.
  • Pros: Requires minimal additional work
  • Cons: Lacks additional features listed below
Option B: Create new SimpleCombinatorPrototype
Similar to already-existing SimpleEntityPrototype & co classes.

Provides the following additional prototype fields:
  • symbol_sprites (Optional): Map[String -> Sprite4Way] -- a map of modes combinator can run to their sprites
Provides the following additional runtime fields:
  • mode [RW]: String -- Switches the active sprite of the combinator; also affects how the combinator processes the input if extra-additional features would be implemented.
  • output_signal [RW]: Array[Signal] -- Similar to LuaControlBehaviour.signals_last_tick, but provides data for the next tick. Read: get pending output, Write: set pending output.
Provides the following events:
  • on_circuit_input_changed: Called when the combinator is required to be updated. As told in topic:LuaCircuitNetwork.signals_changed, such event already exists in C-code, but is not reliable and thus not exported. From my PoV, it's fine exporting this with an additional note that listeners are REQUIRED to be purely-functional (calling the same function multiple times results in the same result, without any external side-effects).
Why?
Currently, if you want to implement your custom in -> out combinator (like Stack Size comb), you are required to do the following:
  1. Define a prototype derived from either AC or DC
  2. Make entities of that prototype non-interactable
  3. Add a custom GUI event listener; custom GUI forms
  4. Place and wire some invisible, non-colliding, non-interactable constant combinators used as outputs
  5. Add the Lua logic that checks every game tick the input signal, processes it, and dumps the result to the output CC
This has a lot of disadvantages and solutions I would call at least a workaround or at most a duct tape:
  1. The MyCustomCombinator9000 should check the input on every tick, and either compare it with the cached input value or re-calculate the output entirely, which can and would affect UPS.
  2. You are required to perform some dörty häcks to make this solution blueprint-compatible. In some cases, this is just not possible. (I know this is marked as "implemented in 2.0", but the amount of code to achieve such behaviour even with this change is still ridiculous.)
  3. The combinator you placed would not show either input signals, output signals, or none of them. Never both.
  4. The UI you designed might vary from the UIs currently used in Factorio because, I see a lot of combs with UIs not being closed on Esc or E, or having pre-1.1 (or even pre-1.0!) border styles nowadays.
What I suggest is to provide a solution to some or all of the problems above.
Extra Featues
Only applicable if SimpleCombinatorPrototype (option B) is chosen to be implemented. Either is optional.
  • Automatically generate UI based on the modes list, the modes list is either the keys of symbol_sprites, or a separate prototype property.
    If first, each mode generates UI like "A <operation> B (results in) C". otherwise, each mode could have additional properties such as the number of parameters and the allowance of specific generic or wildcard signals.
  • Provide AST-parser & processor for signal. This implies the modes_processor optional field for the prototype, each working similarly to the new surface generator AST processor -- accepts a string formula which is then applied to the signals.
  • Provide Lua callbacks on the prototype level. This implies the modes_callbacks optional field for the prototype, having the same effect as binding that function to the on_circuit_input_changed event of each entity of that prototype, with the exception such event cannot be unbound.

Post Reply

Return to “Modding interface requests”