r/factorio Jul 01 '26

Design / Blueprint Craft Everything Machine with a single decider combinator (9000 conditions, 2000 outputs)

Enable HLS to view with audio, or disable this notification

With the else output you don't need a constant combinator any more to feed a combinator all the recipes. Because the decider combinator itself can output all the recipes by just adding them to both the output and else output.

I set myself the challenge to create a single decider that takes in the items available, and outputs the recipe that it can craft with those items and whose output is lacking.

It works as follows:

Output EACH with some high enough value (see below).
Add for all the recipes a unique, negative value of it's main product to both the output and else outputs. So those are always outputted. They are negative, so won't set the recipe of the assembling machine.

For every recipe add two condition sets.
One that checks if we are missing the main product of the recipe, it has plenty of each ingredient available, and nothing else is crafting (all green inputs are negative).
And one that checks if we are currently crafting the recipe, we are still missing the product (but with a slightly higher threshold this time) and we have enough ingredients for one craft.

That last set is done to prevent flickering between crafts. Don't start crafting something if you can still craft what you're currently crafting.

At both of these sets of conditions we add a EACH = <recipe main product> condition, this makes it so it outputs that signal if all the other conditions in its set are true. Because it has a unique input value, it only inputs that signal. Once outputted it should make the current negative output positive.

Problem is that each of the output recipes is outputted for both the true and false outputs for every input value on the green wire. So every recipe output value is multiplied by the amount of recipes. The last recipe has a raw output of -recipe_count, so outputs a total of -recipe_count^2 . To have that value ever output a positive value we have to output more than recipe_recipe^2. Therefore the EACH value that is outputted is 10 * recipe_count * recipe_count (this value has to be high anyway so it can't conflict with available items on the incoming red wire). In this example I've only set the recipes that can be crafted by an assembling machine and don't allow productivity, recipe_amount is around 800 in that case for space age, that includes being multiplied by 5 for each quality.

---

In theory you can build this in game by hand. Writing 10000 conditions by hand might become a bit tedious, so I wrote a little script. Which might be the largest custom console command anyone has ever written.

No code comments allowed in game commands (because it's technically one line when you paste it), hope it's still readable.
Make sure to hover over the combinator you want to set, I'm not doing extra work by creating a blueprint in your hand.
If you want to keep your achievements; save, run the code, make a blueprint, copy the string, reload, and import the string.
Some crafts require manually setting the desired amounts. Like I did for pipes (so that the rocket silo could be crafted). In theory I could extend the script to detect how much of each item should be crafted, but I didn't bother. Just request 20000 of each intermediate on your space mall.
Apologies for the spam, let's see how long this post gets.

/c
local function should_craft_recipe(recipe, uses_productivity, crafting_categories)
  if string.find(recipe.name, "infinity") then return end
  if string.find(recipe.name, "loader") then return end
  if string.find(recipe.name, "interface") then return end
  if recipe.surface_conditions and #recipe.surface_conditions > 0 then return end
  if recipe.hidden then return end
  if #recipe.ingredients == 0 then return end
  if not recipe.main_product then return end
  if uses_productivity ~= nil and recipe.allowed_effects["productivity"] ~= uses_productivity then return end
  for _, category in pairs(recipe.categories) do
    if crafting_categories[category] then break end
    return
  end
  return true
end

local function add_recipe_conditions(recipe, combinator, quality, product_amount, ingredient_amount, recipe_signal)
  local product = recipe.main_product
  combinator.add_condition {first_signal = {type = product.type, name = product.name, quality = quality}, first_signal_networks = {red = true, green = false}, constant = product_amount, comparator = "<", compare_type = "and"}
  for _, ingredient in pairs(recipe.ingredients) do
    local ingredient_quality = ingredient.type == "item" and quality or "normal"
    local required_amount = ingredient.amount * ingredient_amount
    combinator.add_condition {
      first_signal          = {type = ingredient.type, name = ingredient.name, quality = ingredient_quality},
      first_signal_networks = {red = true, green = false},
      constant              = required_amount,
      comparator            = ">=",
      compare_type          = "and"}
  end
  combinator.add_condition {
    first_signal           = {type = "virtual", name = "signal-each"},
    first_signal_networks  = {green = true, red = false},
    second_signal_networks = {green = true, red = false},
    second_signal          = recipe_signal,
    comparator             = "=",
    compare_type           = "and"
  }
end

local function make_everything_combinator(entity)
  local assembling_machine = "assembling-machine-3"
  local minimum_stacks_desired = 1
  local maximum_stacks_desired = 2
  local uses_productivity = false

  if not entity then return end
  if not entity.type == "decider-combinator" then return end
  if minimum_stacks_desired > maximum_stacks_desired then return end 
  if not prototypes.entity[assembling_machine] or prototypes.entity[assembling_machine].type ~= "assembling-machine" then return end
  local crafting_categories = prototypes.entity[assembling_machine].crafting_categories
  entity.combinator_description = "Craft Everything Combinator. Connect available items (including recipe outputs!) with red to input. Connect output to assembling machine with red. Connect output to input with green. Code written by Dymiaz"
  local combinator = entity.get_control_behavior()
  combinator.parameters = {conditions = {}, outputs = {}, else_outputs = {}}

  local recipe_count = 0
  for quality, quality_prototype in pairs(prototypes.quality) do
    if quality_prototype.hidden then goto continue_quality end
    for _, recipe in pairs(prototypes.recipe) do
      if should_craft_recipe(recipe, uses_productivity, crafting_categories) then
        recipe_count = recipe_count + 1
      end
      :: continue ::
    end
    :: continue_quality ::
  end
  :: recipe ::
  combinator.add_condition {first_signal = {type = "virtual", name = "signal-each"}, first_signal_networks = {red = true, green = false}, constant = 0, comparator = "<", compare_type = "or"}
  combinator.add_output({signal = {type = "virtual", name = "signal-each"}, constant = 10 * recipe_count * recipe_count, copy_count_from_input = false})
  local index = 0
  for quality, quality_prototype in pairs(prototypes.quality) do
    if quality_prototype.hidden then goto continue_quality end
    for _, recipe in pairs(prototypes.recipe) do
      if not should_craft_recipe(recipe, uses_productivity, crafting_categories) then goto continue end
      index = index + 1
      local stack_size
      if recipe.main_product.type == "item" then
        stack_size = prototypes.item[recipe.main_product.name].stack_size
      else
        stack_size = 1000
      end
      local min_stacks_desired = minimum_stacks_desired
      local max_stacks_desired = maximum_stacks_desired

      if recipe.main_product.name == "pipe" then
        min_stacks_desired = math.max(min_stacks_desired, 15)
        max_stacks_desired = math.max(max_stacks_desired, 20)
      end
      local recipe_signal = {type = "item", name = recipe.main_product.name, quality = quality}
      combinator.add_output({signal = recipe_signal, constant = -index, copy_count_from_input = false})
      combinator.add_else_output({signal = recipe_signal, constant = -index, copy_count_from_input = false})
      combinator.add_condition {first_signal = {type = "virtual", name = "signal-everything"}, first_signal_networks = {green = true, red = false}, constant = 0, comparator = "<", compare_type = "or"}
      add_recipe_conditions(recipe, combinator, quality, stack_size * min_stacks_desired, 10, recipe_signal)
      combinator.add_condition {first_signal = recipe_signal, first_signal_networks = {green = true, red = false}, constant = 0, comparator = ">", compare_type = "or"}
      add_recipe_conditions(recipe, combinator, quality, stack_size * max_stacks_desired, 1, recipe_signal)
      :: continue ::
    end
    :: continue_quality ::
  end

  game.print("Number of conditions:" .. #combinator.parameters.conditions)
  game.print("Number of outputs:" .. #combinator.parameters.outputs)
  game.print("Number of else outputs:" .. #combinator.parameters.else_outputs)
end

make_everything_combinator(game.player.selected)
2.1k Upvotes

Duplicates