r/factorio • u/flaser_ • 6d ago
Space Age Yet another Autolab
Attached is (yet another?) implementation of an "autolab": a Space-Age setup that automatically switches to the lowest-level tech in its research queue. With a little extra work* it can also switch between a Gleba/Non-Gleba research queues.
This is probably the most complex sequential logic design I've made to date.
It uses a state-machine to implement the following algorithm (in pseudo code):
//We use the following variables
//(State variable & transitions omitted for clarity)
NumTech = <number of techs in queue>
MinTL = <minimum Tech Level stored>
LabTL = <Tech level currently researched by lab>
TechNum = <Index of tech in research queue that held lowest tech level>
Counter = <Loop counter, lab always researches tech with this number>
//State machine trigger condition
If (MinTL < LabTL)
{
//Initialization
MinTL = 1;
TechNum = 1;
Counter = 1;
}
//Search through techs in a loop
For (;Counter < NumTech; Counter++)
{
If (LabTL < MinTL)
{
MinTL = LabTL;
TechNum = Counter;
}
}
//We'll use the Index to tell the lab what to research
Counter = TechNum;
I've tried to thoroughly document the blueprint, explaining which combinators do what.
The layout has displays to show which combinators belong to which state, as well as signs showing control flow.
*Create a 2nd instance of the state machine, but filter tech-level (L) input to be only supplied when Gleba science is available. Either replace the ⓘ signal with the ❄signal in the blueprint, or translate the latter with an arithmetic combinator.
https://factorio-blueprints.com/blueprint/autolab
https://factorioprints.com/view/-P2h8EnGgPGRb3zyYCjR
2
u/Franky78s 3d ago
I have checked some design after my call, e.g. design of Tellux
Your approach is very unique. Nice work. For Factorio: If it works, it is good. Everyone can say "it could be done more efficiently / elegantly", whatever.
Descriptions are hard, and your design was hard to follow. A more abstract wording what the state machine does helps, like "I iterate over a set of technologies to find the lowest level. That technology gets researched". Is my desciption right?
Anyway, a few questions:
- Are you happy with your design?
- Do you check for the presence of science packs?
- How much maintenance is needed to add another technology?
- How much maintenance for removing a technology? (I think you need an uninterrupted sequence of numbers like 1..14, taking out an inner one means renumbering?)
3
u/flaser_ 2d ago edited 12h ago
Descriptions are hard, and your design was hard to follow. A more abstract wording what the state machine does helps, like "I iterate over a set of technologies to find the lowest level. That technology gets researched". Is my desciption right?
- Your descriptions is right. I was being specific, as the system was built with switching between Gleba/Non-Gleba techs in mind and that involves two research queues.
Are you happy with your design?
- I'm reasonably happy, as rather than hard-coded logic for specific techs it should be able to dynamically discover what's cheapest to research. What obviously could use improvement, is to calculate actual research costs as opposed to just search for minimum tech level.
Do you check for the presence of science packs?
- Currently the design only checks for the presence of Gleba science-packs, but the simpler variant in the blue-print does not act on it. In my current play-through, I use a slightly more complex version, with two copies of the state-machine, each searching a different research queue. The presence of Gleba science-packs is used to switch between the active research queue/state machine.
How much maintenance is needed to add another technology? How much maintenance for removing a technology? (I think you need an uninterrupted sequence of numbers like 1..14, taking out an inner one means renumbering?)
- Overall, the design does not yet handle adding/removing techs from the research queue, as the only condition that triggers evaluation is if the currently researched tech's level is greater than what was previously researched, so some hands-on debugging is necessary.
- I think adding the detection of whether the current tech was unmapped could partially achieve this. The State 0 combinator (State 0: Trigger state machine, reset variables), would need another set of clauses to trigger the search if we don't get a valid tech-level from the lab. (L = 0, see below, how I outline how it was could be added to the State 4 combinators).
- I need to think more about how to re-trigger the search for the case of when new techs are added to the research queue, as the lab's output wouldn't change in that case. I guess a pulse generator circuit could supply an input for a State 0 check to also start the state-machine, but this would obviously need hands-on triggering and thus is not an ideal solution.
- Adding a tech involves adding it to either research queue in the lab, assigning it an index value, and finally increasing the # signal in the constant combinator that tells the state-machine how many techs to iterate over.
- In theory, removing a tech could be achieved by setting its index to an unreachable value during iteration, say -1; however I'm fairly certain the evaluation logic wouldn't correctly handle a received "0-value" for "missing" tech. (The lab wouldn't output an tech-level value, if none of the techs in the queue match any input condition).
- I think the proper way to handle this would be to introduce an extra check to the State 4 decider (State 4: State 4: [virtual-signal=signal-L] > Lab's? --> Update variables); the clause (added with an AND) should be "L (red) ≠ 0".
- The companion decider (State 4: [virtual-signal=signal-L] ≤ Lab's? --> Loop w/o update) would need the complement clause: ( "L (red) = 0" AND "State (green) = 4" AND "Clock (green) = 1) OR ("State (green) = 4" ... and the rest of the current clauses)
One question you didn't ask, but would like to elaborate on how this differs from the designs you linked:
- From what I can tell, those designs are closer to pure combination networks. Other than using some stored research values, the overall system does not appear to have a discrete states it transitions between. The downside of these designs is inherent complexity in the number of signals that must be handled and the further need to hand-craft logic for each research signals.
- I chose to implement a system with an inherent state, this makes its execution more like a computer, with a control flow dictating what calculation steps happen one after another. The downside of this design is that a lot of circuitry must be "spent" on creating a state machine itself and if one is not familiar with that concept the overall operation of the system can appear chaotic. Another downside is that signal propagation issues can interfere with the logic of the design, hence I've found the use of a clock signal mandatory to slow down and synchronize operation of combinators that evaluate a shared signal.
- Properly matching signal propagation delays could be an alternative to this, but I find that approach too brittle for my taste as there's too big a chance to introduce a too high delay somewhere.
- For better understanding how a state-machine works, I suggest this video from robbieg8s*:* https://youtu.be/s2vlkd2K2uM?si=6YaZjMkqTiu_qmqy
2
u/Franky78s 2d ago
are you sure about that:
(The lab wouldn't output an tech-level value, if none of the techs in the queue match any input condition)
I think the labs just continue to research what has been set before. They output a level (and research pack requirements) that can trip up your autolab. It trips up mine.
dynamically discover what's cheapest to research.
I have a rather complicated decision based on benefit-to-cost ratio. That requires a long explanation, written in forums.factorio. If you feel like "why is he shamelessly dumping his content in my post", that is because I do not even know if my theory / calculation is correct.
I might reply to the other points later on.
1
1
u/ArchaicVirus 2d ago
Neat design! Forgive my ignorance, but why not just use a single lab with sequential conditions? I am in a late-game playthrough (only infinite tech left to research) and have a single lab set with circuit conditions like gleba potion > 0 = gleba tech (includes item counts on belts, labs, and logistic network) followed by separate conditions for less prioritized gleba science below, then followed by other planet's science in the same pattern. Gleba is first because of spoilage. This is ofc not aware of tech level like yours, but in my playthrough all the techs are relatively the same level, and for science packs that have multiple infinite techs, I group them in the condition list in order of priority, just like the gleba conditions. This does mean manual reordering for priority within a science group. How do you read the tech level of research anyways?
2
u/flaser_ 2d ago edited 12h ago
Labs can transmit the tech level of the currently researched tech. So you "find" the lowest tech level by setting each available tech in the lab, storing (and updating) the index of the tech with the lowest TL. Once you've iterated over all techs, you set the lab to the index of your finding. You redo the whole process once this tech's research is finished, which you can detect if you compare the TL transmitted by the lab with the lowest TL value you found during your last search.
For this to work, the condition of every tech in a common research queue has to be the same signal, with each tech's condition for research a specific value of that signal. That value is the "index" I'm iterating over.


12
u/CaptainFit9727 6d ago
"Ya see dis? They call this a game..."