Skip to content

Instantly share code, notes, and snippets.

@melvyn2
Created January 9, 2026 21:42
Show Gist options
  • Select an option

  • Save melvyn2/1221acc4db535be7d1cf47fad8c63995 to your computer and use it in GitHub Desktop.

Select an option

Save melvyn2/1221acc4db535be7d1cf47fad8c63995 to your computer and use it in GitHub Desktop.
RS2 Autocrafting with CC:T: AdvAE2 Reaction Chamber
local next = next
local pairs = pairs
local fsc = peripheral.find("functionalstorage:storage_controller")
local fscn = peripheral.getName(fsc)
local rcs = { peripheral.find("advanced_ae:reaction_chamber") }
local interface = peripheral.find("refinedstorage:interface")
-- Dictionary of name -> (slot, count)
function itemmap (inv)
local items = {}
for s, i in pairs(inv.list()) do
items[i.name] = { slot = s, count = i.count }
end
for s, i in pairs(inv.tanks()) do
items[i.name] = { slot = s, count = i.amount }
end
return items
end
local lava = "minecraft:lava"
local qifluid = "advanced_ae:quantum_infusion_source"
local water = "minecraft:water"
local ccertuscrys = "ae2:charged_certus_quartz_crystal"
local certuscrys = "ae2:certus_quartz_crystal"
local copperingot = "minecraft:copper_ingot"
local crscrys = "appflux:charged_redstone_crystal"
local enderdust = "ae2:ender_dust"
local entrocrys = "extendedae:entro_crystal"
local entrodust = "extendedae:entro_dust"
local entroingot = "extendedae:entro_ingot"
local fluixcrys = "ae2:fluix_crystal"
local fluixdust = "ae2:fluix_dust"
local gsdust = "minecraft:glowstone_dust"
local goldingot = "minecraft:gold_ingot"
local ironingot = "minecraft:iron_ingot"
local lapis = "minecraft:lapis_lazuli"
local matterball = "ae2:matter_ball"
local nstar = "minecraft:nether_star"
local netheriteingot = "minecraft:netherite_ingot"
local osmiumingot = "alltheores:osmium_ingot"
local qalloy = "advanced_ae:quantum_alloy"
local qalloyplate = "advanced_ae:quantum_alloy_plate"
local qidust = "advanced_ae:quantum_infused_dust"
local rsblock = "minecraft:redstone_block"
local rscrys = "appflux:redstone_crystal"
local singularity = "ae2:singularity"
local ssingularity = "advanced_ae:shattered_singularity"
local skydust = "ae2:sky_dust"
local skybingot = "megacells:sky_bronze_ingot"
local skyoingot = "megacells:sky_osmium_ingot"
local skysingot = "megacells:sky_steel_ingot"
local skystone = "ae2:sky_stone_block"
local recipes = {
[ccertuscrys] = { fluid = { name = water, count = 1000 }, items = { [certuscrys] = 64 } },
[crscrys] = { fluid = { name = water, count = 1000 }, items = { [rscrys] = 64 } },
[entrocrys] = { fluid = { name = water, count = 500 }, items = { [entrodust] = 32, [fluixcrys] = 32 } },
[entroingot] = { fluid = { name = water, count = 500 }, items = { [entrodust] = 32, [goldingot] = 32, [lapis] = 32 } },
[fluixcrys] = { fluid = { name = water, count = 500 }, items = { [ccertuscrys] = 32, [fluixdust] = 32 } },
[qalloy] = { fluid = { name = qifluid, count = 1000 }, items = { [copperingot] = 4, [ssingularity] = 4, [singularity] = 4 } },
[qalloyplate] = { fluid = { name = qifluid, count = 1000 }, items = { [qalloy] = 8, [netheriteingot] = 2, [nstar] = 1 } },
[qifluid] = { fluid = { name = water, count = 4000 }, items = { [qidust] = 1 } },
[rscrys] = { fluid = { name = water, count = 500 }, items = { [rsblock] = 16, [fluixcrys] = 16, [gsdust] = 16 } },
[singularity] = { fluid = { name = lava, count = 100 }, items = { [matterball] = 64 } },
[ssingularity] = { fluid = { name = lava, count = 100 }, items = { [singularity] = 1, [enderdust] = 2, [skydust] = 2 } },
[skybingot] = { fluid = { name = lava, count = 500 }, items = { [ccertuscrys] = 16, [copperingot] = 16, [skystone] = 16 } },
[skyoingot] = { fluid = { name = lava, count = 500 }, items = { [ccertuscrys] = 16, [osmiumingot] = 16, [skystone] = 16 } },
[skysingot] = { fluid = { name = lava, count = 500 }, items = { [ccertuscrys] = 16, [ironingot] = 16, [skystone] = 16 } },
}
local recipesp = pairs(recipes)
-- Setup function table to parallel pull results
local rcpulls = {}
for _,rc in pairs(rcs) do
local rcn = peripheral.getName(rc)
table.insert(rcpulls, function ()
-- Pull out finished items
interface.pullItems(rcn, 10)
-- Max amount is 16B and only quantum infusion can be made
interface.pullFluid(rcn, 16000, qifluid)
end)
end
-- How many of recipe can we make with inv
function recipe_quantity (inv, recipe)
local q = 0
if inv[recipe.fluid.name] ~= nil then
q = math.floor(inv[recipe.fluid.name].count / recipe.fluid.count)
else
return 0
end
for n,c in pairs(recipe.items) do
if inv[n] ~= nil then
q = math.min(q, math.floor(inv[n].count / c))
else
return 0
end
end
return q
end
while (true) do
-- First pull all outputs
parallel.waitForAll(table.unpack(rcpulls))
-- Build the map of item -> (slot, quantity) in the functional storage controller
local fsi = itemmap(fsc)
for n,i in recipesp, recipes do
local q = recipe_quantity(fsi, i)
if q > 0 then
print(("Attempting %d of %s"):format(q, n))
-- Build the table of (attempted) ingredient pulls
local pushes = {}
for _,rc in pairs(rcs) do
-- Only attempt as many runs as is possible, to avoid over-splitting
if q == 0 then
break
else
q = q - 1
end
-- Move this RC to end, to round-robin distribute attempts
table.insert(rcs, table.remove(rcs, 0))
table.insert(pushes, function ()
local inv = rc.list()
local tanks = rc.tanks()
-- Same issue as below but can safely bail for now (really should retry though TODO)
if inv == nil or tanks == nil then
return
end
-- Only go ahead with the pull if:
-- have 3+ free item slots (slot 6 empty)
-- have 4B free fluid space (leq 12B in input tank)
-- the reactor isn't executing an incompatible recipe (different fluid)
if inv[6] == nil and (tanks[2] == nil or (tanks[2].amount <= 12000 and tanks[2].name == i.fluid.name)) then
-- Retry transfers until they work (https://github.com/cc-tweaked/CC-Tweaked/issues/1817)
local ft = nil
while ft == nil do
ft = rc.pullFluid(fscn, i.fluid.count, i.fluid.name)
end
if ft ~= i.fluid.count then
error(("Only pulled %d of %d %s to %s"):format(ft, i.fluid.count, i.fluid.name, peripheral.getName(rc)))
end
for i,q in pairs(i.items) do
-- Retry here too
local it = nil
while it == nil do
it = rc.pullItems(fscn, fsi[i].slot, q)
end
if it ~= q then
error(("Only pulled %d of %d %s to %s"):format(it, q, i, peripheral.getName(rc)))
end
end
end
end)
end
-- Execute the pull attempts
parallel.waitForAll(table.unpack(pushes))
-- Rebuild the item map for the remaining ingredients
fsi = itemmap(fsc)
-- Now OK to attempt more recipes without waiting
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment