Контроллер ядра v2
Для чего это нужно
Эта программа предназначена для того чтобы в ядре энергии всегда было определенное количество энергии для реакторов, чтобы в ядре не было ее слишком много или слишком мало. При избытке программа повышает выход из ядра, при недостаче - понижает или совсем отключает.
Список компонентов
Компьютер
- Монитор (3-ий уровень) - 6шт
- Клавиатура - 1шт
- Преобразователь энергии - 1шт
- Системный блок (3-ий уровень) - 1шт
- Адаптер - 1шт
- EEPROM (Lua BIOS) - 1шт
- Видеокарта (3-ий уровень) - 1шт
- Центральный процессор (ЦП) (3-ий уровень) - 1шт
- Память (Уровень 3.5) - 2шт
- Жёсткий диск (3-ий уровень) (4МВ) - 1шт
- OpenOS (Operating System) - 1шт
Ядро энергии
- Само ядро энергии (как его построить)
- Флаксовый гейт - 1шт
- Энергетический пилон - 1шт
- Криостабилизированная флаксовая труба - смотреть по ситуации
Первые шаги
Обязательно первым делом включаем отображение чанков (F9) и для удобства выделяем область. Дальше мы строим ядро энергии (лучше сразу 7го тира, чтобы потом не перестраивать). Главное в одном чанке. Инструкция тут. Схематика тут.
Скриншот ядра

Установка компьютера
Ставим все как на скриншоте, желательно тоже в одном чанке.
Не забываем за клавиатуру!
Скриншот установки пк и мониторов

Компоненты внутри системного блока

Обратите внимание что EEPROM должен быть именно (Lua BIOS), для этого создайте обычный EEPROM и в верстаке соедините его с Руководством OpenComputers.
Тоже самое касается и дискеты, делаем обычную дискету и соединяем ее с Руководством OpenComputers и мы получим дискету OpenOS (Operating System).
Подключение к ядру
Скриншот подключения к ядру

На что тут надо обратить внимание.


Очень важно, следите за тем чтобы ядро энергии не переполнялось энергией, иначе реакторам некуда будет девать энергию и они взорвутся.
Если это будет проблемой - перепишу код и добавлю энергетическую мусорку, чтобы туда сливалась лишняя энергия.
Настройка компьютера
После всех подключений мы заходим в наш системный блок и нажимаем Включить

Сначала мы видим загрузку, после чего у нас появляется вот такое окно

Для начала нам нужно установить ОС на наш компьютер, для этого впишите эту команду.
Либо скопируйте и при помощи нажатия колесика мыши вставьте ее.
install

Дальше нажмите Enter и начнется установка ОС. После завершения установки программа предложит перезагрузить ПК, опять нажмите Enter.

После перезагрузки нам нужно вписать в первую очередь себя в администраторы ПК и только потом тех кто будет им пользоваться помимо вас при помощи этой команды
Чувствителен к регистру, если у игрока ник DesOope то и в команде нужно писать DesOope, а не desoope.
useradd ник

Это мы делали для того чтобы ПК могли пользоваться только вписанные в него пользователи.
После того как мы всех добавили мы пишем такую команду
edit .shrc
и дописываем в самом конце такую строку
gate.lua

И нажимаем Ctrl + S (сохранить) и Ctrl + W (закрыть).
Это нужно чтобы программа запускалась автоматически после перезагрузки.
Дальше создаем файл gate.lua
edit gate.lua
У нас открывается окно для ввода кода, мы вписываем туда этот код. (вставлять надо по 250 строк из-за ограничений вставки кода)
local component = require("component")
local event = require("event")
local computer = require("computer")
local unicode = require("unicode")
local term = require("term")
local keyboard = require("keyboard")
local gpu = component.gpu
--------------------------------------------------------------------------------
-- [КОНФИГУРАЦИЯ]
--------------------------------------------------------------------------------
local CFG = {
targetEnergy = 1000 * 10^9, -- Цель: 1 T RF
aggressiveness = 0.03, -- Плавность реакции стабилизации
-- Настройки кнопок
btnStep = 10^9, -- Шаг (1B)
btnStepCtrl = 10 * 10^9, -- Шаг с Ctrl (10B)
btnStepShift = 100 * 10^9 -- Шаг с Shift (100B)
}
local COLORS = {
bg = 0x111111, tileBg = 0x222222, tileHeader = 0x333333,
text = 0xEEEEEE, label = 0x999999,
good = 0x55FF55, warn = 0xFFAA00, bad = 0xFF5555,
energy = 0x00AAFF, sat = 0xFFAA00, fuel = 0xFFFF55,
btn = 0x444444, btnActive = 0x006699,
graphLine = 0x444444,
black = 0x000000
}
-- Проверка компонентов
if not component.isAvailable("draconic_rf_storage") then
print("ОШИБКА: Нет ядра (draconic_rf_storage)!")
os.exit()
end
if not component.isAvailable("flux_gate") then
print("ОШИБКА: Нет гейта (flux_gate)!")
os.exit()
end
local rfStorage = component.draconic_rf_storage
local fluxGate = component.flux_gate
local W, H = gpu.maxResolution()
gpu.setResolution(W, H)
--------------------------------------------------------------------------------
-- [ПЕРЕМЕННЫЕ И РАСЧЕТ МАКЕТА]
--------------------------------------------------------------------------------
local running = true
local buttons = {}
-- === НАСТРОЙКА СИММЕТРИИ ===
local M = 2 -- Отступ (Margin) со всех сторон
local panelH = 9 -- Высота верхних панелей
-- Расчет координат
local totalW = W - (M * 3)
local panelW = math.floor(totalW / 2)
-- Левая панель
local x1 = M
local y1 = M
-- Правая панель
local x2 = x1 + panelW + M
local y2 = M
-- График
local graphX = M
local graphY = y1 + panelH + 1
local graphW = W - (M * 2)
local graphH = H - graphY - M - 2
local energyHistory = {}
for i = 1, graphW do energyHistory[i] = 0 end
local maxCoreCapacity = rfStorage.getMaxEnergyStored()
-- Фильтр (Плавность)
local filVal = 0
local function expRunningAvg(newVal)
if math.abs(newVal - filVal) > 10^15 then filVal = newVal end
filVal = filVal + ((newVal - filVal) * 0.05)
return filVal
end
--------------------------------------------------------------------------------
-- [ГРАФИКА - ФУНКЦИИ]
--------------------------------------------------------------------------------
local function rect(x, y, w, h, col)
gpu.setBackground(col)
gpu.fill(x, y, w, h, " ")
end
local function text(x, y, str, fg, bg)
if bg then gpu.setBackground(bg) end
gpu.setForeground(fg)
gpu.set(x, y, str)
end
local function center(x, y, w, str, fg, bg)
if bg then gpu.setBackground(bg) end
gpu.fill(x, y, w, 1, " ")
local px = x + math.floor((w - unicode.len(str))/2)
if fg then gpu.setForeground(fg) end
gpu.set(px, y, str)
end
-- ВНИМАНИЕ: Эта функция очищает всю строку под собой.
local function textRight(x, y, w, str, fg, bg)
if bg then gpu.setBackground(bg) end
gpu.fill(x, y, w, 1, " ")
local len = unicode.len(str)
local px = x + w - len
if fg then gpu.setForeground(fg) end
gpu.set(px, y, str)
end
local function fmt(num)
if math.abs(num) >= 10^12 then return string.format("%.3f T", num/10^12)
elseif math.abs(num) >= 10^9 then return string.format("%.3f B", num/10^9)
elseif math.abs(num) >= 10^6 then return string.format("%.3f M", num/10^6)
elseif math.abs(num) >= 10^3 then return string.format("%.3f K", num/10^3)
else return string.format("%d", math.floor(num)) end
end
local function progressBar(x, y, w, pct, colBar, colBg)
rect(x, y, w, 1, colBg)
local barW = math.floor(w * (pct/100))
if barW > w then barW = w end
if barW > 0 then rect(x, y, barW, 1, colBar) end
end
local function btn(id, x, y, w, h, str, bg, fg)
rect(x, y, w, h, bg)
center(x, y + math.floor(h/2), w, str, fg or COLORS.text, bg)
buttons[id] = {x=x, y=y, w=w, h=h}
end
--------------------------------------------------------------------------------
-- [ИНТЕРФЕЙС]
--------------------------------------------------------------------------------
local function drawStaticInterface()
gpu.setBackground(COLORS.bg)
term.clear()
-- Левая панель
rect(x1, y1, panelW, panelH, COLORS.tileBg)
rect(x1, y1, panelW, 1, COLORS.tileHeader)
center(x1, y1, panelW, "СОСТОЯНИЕ ЯДРА", COLORS.text, COLORS.tileHeader)
text(x1+2, y1+2, "НАКОПЛЕНО:", COLORS.label, COLORS.tileBg)
text(x1+2, y1+4, "ЦЕЛЬ СТАБ.:", COLORS.label, COLORS.tileBg)
-- Правая панель
rect(x2, y2, panelW, panelH, COLORS.tileBg)
rect(x2, y2, panelW, 1, COLORS.tileHeader)
center(x2, y2, panelW, "ЭНЕРГИЯ", COLORS.text, COLORS.tileHeader)
text(x2+2, y2+2, "ТЕКУЩИЙ ПОТОК:", COLORS.label, COLORS.tileBg)
text(x2+2, y2+4, "ВЫХОД ГЕЙТА:", COLORS.label, COLORS.tileBg)
-- График
rect(graphX, graphY, graphW, 1, COLORS.tileHeader)
center(graphX, graphY, graphW, " ГРАФИК ПОТОКА ", COLORS.label, COLORS.tileHeader)
rect(graphX, graphY+1, graphW, graphH, COLORS.bg)
-- Подвал
local footerY = H - 1
btn("exit", M, footerY, 10, 1, "ВЫХОД", COLORS.bad)
-- Кредиты
local crX = W - 32
local crY = H - 3
text(crX, crY, "Разработчик: DesOope", COLORS.label, COLORS.bg)
text(crX, crY+1, "Проект: McSkill", COLORS.label, COLORS.bg)
text(crX, crY+2, "Сервер: HitechClassic 1.7.10", COLORS.label, COLORS.bg)
end
local function drawGraph(delta)
table.insert(energyHistory, delta)
while #energyHistory > graphW do table.remove(energyHistory, 1) end
local gTopY = graphY + 1
local gBottomY = graphY + graphH
local midY = gTopY + math.floor(graphH/2)
if graphH < 2 then return end
local maxVal = 1
for _, v in ipairs(energyHistory) do
if math.abs(v) > maxVal then maxVal = math.abs(v) end
end
for i = 1, graphW do
local val = energyHistory[i] or 0
local x = graphX + i - 1
local h = 0
if math.abs(val) > 0 then
h = math.ceil( (math.abs(val) / maxVal) * (graphH/2) )
if h > (graphH/2) then h = math.floor(graphH/2) end
end
local barTop, barBottom
local color
if val > 0 then
barBottom = midY + 1
barTop = barBottom - h
if barTop < gTopY then barTop = gTopY end
color = COLORS.good
elseif val < 0 then
barTop = midY + 1
barBottom = barTop + h
if barBottom > gBottomY then barBottom = gBottomY end
color = COLORS.bad
else
barTop = midY
barBottom = midY + 1
color = COLORS.bg
end
if barTop > gTopY then
gpu.setBackground(COLORS.bg)
gpu.fill(x, gTopY, 1, barTop - gTopY, " ")
end
local barH = barBottom - barTop
if val ~= 0 and barH > 0 then
gpu.setBackground(color)
gpu.fill(x, barTop, 1, barH, " ")
elseif val == 0 then
gpu.setBackground(COLORS.bg)
gpu.setForeground(COLORS.graphLine)
gpu.set(x, midY, "─")
end
if barBottom < gBottomY then
gpu.setBackground(COLORS.bg)
local clearH = gBottomY - barBottom + 1
gpu.fill(x, barBottom, 1, clearH, " ")
end
end
end
local function updateLiveDisplay(stored, target, delta, gateFlow)
local valWidth = 16
local valX = x1 + panelW - valWidth - 2
-- === ЛЕВАЯ ПАНЕЛЬ ===
center(valX, y1+2, valWidth, fmt(stored).." RF", COLORS.energy, COLORS.tileBg)
center(valX, y1+4, valWidth, fmt(target).." RF", COLORS.warn, COLORS.tileBg)
local btnW = 3
local btnPlusX = valX - btnW - 1
btn("inc", btnPlusX, y1+4, btnW, 1, "+", COLORS.btn)
local btnMinusX = btnPlusX - btnW - 1
btn("dec", btnMinusX, y1+4, btnW, 1, "-", COLORS.btn)
local maxPct = (stored / maxCoreCapacity) * 100
if maxPct > 100 then maxPct = 100 end
local barX = x1 + 2
local barW = panelW - 4
center(barX, y1+6, barW, string.format("%.2f%% (от макс. объема)", maxPct), COLORS.text, COLORS.tileBg)
text(barX, y1+6, "0%", COLORS.label)
local str100 = "100%"
local x100 = barX + barW - unicode.len(str100)
text(x100, y1+6, str100, COLORS.label)
progressBar(barX, y1+7, barW, maxPct, COLORS.energy, 0x111111)
-- === ПРАВАЯ ПАНЕЛЬ ===
local valX2 = x2 + panelW - valWidth - 2
local dColor = COLORS.text
local sign = ""
if delta > 0 then dColor = COLORS.good; sign = "+"
elseif delta < 0 then dColor = COLORS.bad; sign = "" end
center(valX2, y2+2, valWidth, sign..fmt(delta).." RF/t", dColor, COLORS.tileBg)
center(valX2, y2+4, valWidth, fmt(gateFlow).." RF/t", COLORS.text, COLORS.tileBg)
-- === БОЛЬШОЙ СТАТУС БАР (ВНИЗУ) ===
local statusStr = ""
local statusBg = COLORS.btn
local statusFg = COLORS.black
-- НОВАЯ ЛОГИКА СТАТУСОВ
if math.abs(stored - target) < 10^9 then
-- Энергия в норме (равна цели)
statusStr = "СТАБИЛЬНО"
statusBg = COLORS.good
else
if stored < target then
-- Нехватка энергии
if delta > 0 then
-- Но она растет = Хорошо
statusStr = "ВОСПОЛНЕНИЕ"
statusBg = COLORS.energy -- Синий
else
-- Она падает = Плохо
statusStr = "ВНИМАНИЕ: РАЗРЯД"
statusBg = COLORS.bad -- Красный
statusFg = 0xFFFFFF
end
else
-- Избыток энергии
if delta < 0 then
-- Она падает (возвращается к цели) = Хорошо
statusStr = "СБРОС ИЗЛИШКОВ"
statusBg = COLORS.warn -- Оранжевый
else
-- Она растет дальше = Плохо
statusStr = "КРИТИЧЕСКОЕ ПЕРЕПОЛНЕНИЕ"
statusBg = COLORS.bad -- Красный
statusFg = 0xFFFFFF
end
end
end
local stX = x2 + 2
local stW = panelW - 4
local stY = y2 + 6
local stH = 3
gpu.setBackground(statusBg)
gpu.fill(stX, stY, stW, stH, " ")
center(stX, stY + 1, stW, statusStr, statusFg, statusBg)
drawGraph(delta)
end
local function handleTouch(x, y)
for id, b in pairs(buttons) do
if x >= b.x and x < b.x + b.w and y >= b.y and y < b.y + b.h then
if id == "exit" then
running = false
elseif id == "inc" or id == "dec" then
local step = CFG.btnStep
if keyboard.isControlDown() then step = CFG.btnStepCtrl
elseif keyboard.isShiftDown() then step = CFG.btnStepShift end
if id == "dec" then CFG.targetEnergy = CFG.targetEnergy - step end
if id == "inc" then CFG.targetEnergy = CFG.targetEnergy + step end
if CFG.targetEnergy < 0 then CFG.targetEnergy = 0 end
computer.beep(1000, 0.05)
rect(b.x, b.y, b.w, b.h, COLORS.good)
os.sleep(0.05)
rect(b.x, b.y, b.w, b.h, COLORS.btn)
end
end
end
end
--------------------------------------------------------------------------------
-- [ГЛАВНЫЙ ЦИКЛ]
--------------------------------------------------------------------------------
drawStaticInterface()
local prevTime = computer.uptime()
local prevEnergy = rfStorage.getEnergyStored()
while running do
local nowTime = computer.uptime()
local dt = nowTime - prevTime
if dt < 0.2 then
os.sleep(0.2)
nowTime = computer.uptime()
dt = nowTime - prevTime
end
local nowEnergy = rfStorage.getEnergyStored()
local rawDiff = (nowEnergy - prevEnergy) / (dt * 20)
local smoothedDiff = expRunningAvg(rawDiff)
local currentGate = fluxGate.getFlow()
local errorVal = nowEnergy - CFG.targetEnergy
local correction = errorVal * CFG.aggressiveness
local newGate = currentGate + smoothedDiff + correction
if newGate < 0 then newGate = 0 end
if math.abs(newGate - currentGate) > 500 then
fluxGate.setSignalLowFlow(math.floor(newGate))
end
updateLiveDisplay(nowEnergy, CFG.targetEnergy, smoothedDiff, newGate)
local sig = {event.pull(0.1, "touch")}
if sig[1] then handleTouch(sig[3], sig[4]) end
prevTime = nowTime
prevEnergy = nowEnergy
end
gpu.setResolution(W, H)
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
term.clear()
И нажимаем Ctrl + S (сохранить) и Ctrl + W (закрыть).
После перезагружаем систему командой
reboot
После перезапуска у нас сразу откроется программа стабилизации ядра и мы будем видеть его состояние

Управление простое + и - для регулирования количества энергии в ядре
ЛКМ добавить или отнять 1B (млрд)
Ctrl+ЛКМ добавить или отнять 10B (млрд)
Shift+ЛКМ добавить или отнять 100B (млрд)
Когда количество энергии дойдет до той что вы выставили - лишняя энергия начнет выходить через Флаксовый гейт.
Если цель энергии не достигнута - через гейт энергия не идет
Если энергии больше чем должно быть - выход гейта будет повышаться до тех пор пока ее количество не стабилизируется