Page 1 of 1

Idea inspired by SLB's red/green input/output switcher idea

Posted: Sat Dec 23, 2017 10:27 am
by golfmiketango
golfmiketango wrote:Is there some kind of magical "offset" applied to the circuit inputs to compensate for the boxes own "contents" output? Is that offset lagged by one tick to avoid discrepancies as described above? If there is some offset, does it apply to both circuit networks connected, or just to the chest "net", meaning that it will DWIM with one wire color connected but not both? What if we wire multiple chests together, do the offsets aggregate across the connected chests?
Actually... crazy idea.

I wonder if, above, I have more or less stumbled onto a solution (of sorts) for these input/output muddling problems.

To be clear, the problem is "blowback" affecting duplex circuit-network entities. Combinators solve this by providing two terminals instead of one (four instead of two really but same diff). That is great -- basically there is no muddle, since inputs and outputs are completely separate i/o terminals. But for 1x1 entities, there is a graphical/UI problem of displaying four "terminals" on one smallish object.... I think there's no getting around that with any amount of clever graphic design. So we "must" deal, somehow, with any complications that result from "duplex" circuit-network connections (or not use them, which does solve the problem as well :D)

My idea is: maybe the game engine should lie to those circuit-network-connected entities configured to read and write to the circuit network on a single terminal (but only those entities). Instead of showing these entities the actual value on the wire, the game engine would show them the value they would have seen had those entities only read from the wire, and written nothing (even if, in fact, they did write something).

Formalizing this might look something like this:
  • Entities configured to potentially read and write to the same circuit terminal are required to observe this "protocol". All other entities are exempt and continue to work exactly as they do now. For example, any vanilla combinator is exempt because although it reads and writes to its terminals simultaneously, it never reads and writes to any single terminal (unless it's input and output are wired into the same network which does not count). However, an inserter configured to Enable/Disable based on a circuit condition but also to "read hand contents" would qualify, as it is configured simultaneously to read from and write to the same circuit-network connection, as would a similarly configured transport belt. Let's also say this applies to all entities configured for duplex operation, even if, in a given game-tick, those entities might not be writing any actual value to the wire.
  • Some definitions are needed: at tick t let's call the literal wire value on circuit network N l(N,t).
  • At tick t let the set of all entities required to observe this protocol (as specified in the first bullet point), which also happen to be connected to circuit network "N" be known as |P(N,t)| (it is an unordered set of entities).
  • Let network N's written shared output w(N,t) be the sum, at tick t, of all the outputs written to circuit network N by all of the entities in |P(N,t)|.
  • Let us then define the effective shared input from circuit network N, e(N,t), to be the literal wire-value of circuit network N at tick t, minus the written shared output at tick t-1. In other words, e(N,t) = l(N,t) - w(N, t-1)⁽¹⁾. (that's a footnote, not some crazy math thing :D).
  • So the exact rule/protocol/lie is: all entities in |P(N,t)|⁽²⁾ will see the effective shared input from circuit network N, as though this were the circuit-value on the wire, instead of l(N,t).
Even though the above looks pretty confusing written out in pseudo-math-speak as above, I believe it would actually be quite intuitive. Basically it would mean you could forget about the whole problem of shared inputs and outputs: any "blowback" (by which I mean, the situation where one-terminal entities read their own outputs from tick t back from the circuit network at tick t+1) just goes away. If you had some very complicated build you might need to look at this "protocol" and reason it out precisely, but for the vast majority of real-(virtual)-world situations the following simple explanation would describe the result quite clearly:
"Factorio magically prevents duplex circuit gizmos from seeing their own outputs"
I should maybe mention: I'm pretty sure, but not absolutely 110% positive, that this is not how factorio already works. I habitually build my own circuits in a way that is agnostic to this difference, but I'm pretty confident no "scrubbing" like the above occurs today. No doubt someone will correct me if I'm wrong (not complaining: please do set me straight if I'm mixed up!).

___________________________

(1) This difference is circuit-network arithmetic, so when I say "l(N-t) - w(N, t-1)," I mean the result we'd get by summing the contents of circuit network N with the output from an EACH -> EACH * (-1) arithmetic combinator whose input was the written shared output defined in the fourth bullet-point.

(2) [Edit: here I originally said, "entities in both |P(N,t)| and |P(N,t-1)| (in other words, the disjunction |P(N,t) ⋂ P(N,t-1)|)". Maybe I got carried away there.... this will almost always be the same thing as P(N,t); the only exception would be at the precise moment when the membership of P(N) changes over time, i.e., when you change wires or entity configurations (or some robot does so). This seemed like a confusing distraction from the basic idea. I'm not even sure it makes the idea any saner, if and when the reader eventually figures out what the hell I'm talking about, so ... whatever. Maybe it should apply to |P(N,t)|, or maybe to |P(N,t-1)|, or maybe to |P(N,t) ⋂ P(N,t-1)|; whatever winds up being the least confusing or hard to implement.]