Статья про тонкости игрового процесса в игре Factorio.
В этой статье рассмотрим приоритеты на ж/д станциях и логику для управления ими в Factorio.
Вступление.
Если вы не читали предыдущие статьи из серии о железной дороге и прерываниях поездов, и не понимаете как всё работает и как это настраивать, то перед чтением этой статьи рекомендую, как минимум, прочитать две статьи: 1) каксоздавать расписание для поездов, 2) как использовать одинаковое название для разных ж/д станций с похожим назначением. В любом случае в этой статье речь пойдёт о логике, и тем, кто не желает отвлекаться на чтение других статей про поезда – сегодня можно это не делать.
Железная дорога и поезда.
В статье «Перевозим разные ресурсы одним поездом с помощью прерываний в Factorio» я создал примитивную железную дорогу с депо на 3 станции, 2 станциями погрузки и 2 станциями разгрузки. Там я запустил 3 поезда с расписанием имеющим прерывания.
Для нынешней статьи эту железную дорогу я расширил до 6 станций погрузки железных плит и 6 станций разгрузки железных плит. Поезда по-прежнему курсируют по расписанию от погрузки до разгрузки. Но теперь, станций стало много, а поездов по-прежнему мало – всего 3 подвижных состава. Соответственно, они ездят только на те станции, которые оказались ближе, и пропускают далёкие станции, где на погрузках уже давно полные сундуки, а на разгрузках сундуки опустели:
Приоритет.
Приоритет в ж/д станциях в игре Factorio необходим для указания локомотивам имеющим в расписании эти станции – какая станция более нуждается в его прибытии. Значит, если мы имеем несколько станций «Разгрузка», то поезд поедет разгружаться туда, где приоритет стоит более высокий. А выставить приоритет нам поможет логика, которая в свою очередь будет считать количество предметов в сундуках на разгрузке. Этот же принцип работает и со станциями «Погрузка» – поезда будут ехать сначала на те станции, которые имеют более высокий приоритет, а значит, у них более полные сундуки, чем у конкурирующих станций.
Приоритет в Factorio по умолчанию имеет значение 50 на каждой ж/д станции. Это среднее значение, и поэтому обычно поезда считают все станции «одинаковыми», если игрок не менял приоритеты. И поэтому поезду нет разницы куда ехать в первую очередь, и он отправляется на ближайшую станцию, игнорируя ту, которая дальше, и нуждается в поезде в бόльшей мере.
Итак, мы разобрались, что для того чтобы поезд «решил» ехать на более отдалённую станцию – ей надо выставить приоритет больше, чем у всех станций. Приоритет в ж/д станциях работает в диапазоне от 0 до 255 включительно. Где 0 – самое низкое значение, и поезд практически всегда будет игнорировать эту станцию, а 255 – самое высокое значение, и поезд будет считать эту станцию наиглавнейшей в своём выборе станций.
Если подключиться к станции сигнальным проводом, то включается логическая сеть и ж/д станция начинает взаимодействовать с логикой. Управление приоритетом логика выполняет через сигнал P (в программировании или математике этот сигнал назвали бы переменной P).
Логика работы с приоритетом.
Логические схемы для работы со станциями могут быть абсолютно разными и отличаться по назначению. Можно выделить два варианта более используемых схем логики:
Сложная:
Создаётся под разных игроков и разные случаи. Имеет много комбинаторов, автоматически определяет ресурс в сундуках и подсчитывает его объём в зависимости от количества ресурса в 1 пачке, от количества ячеек в сундуках, от количества сундуков. Больше всего подходит для случаев, когда готовый чертёж с такой логической схемой публикуется для всеобщего использования или раздаётся разным игрокам, особенно, не имеющим опыта в работе с логикой. Логика сама будет определять что на станции, и сама решит за игрока что и как. Обходится дороже по созданию и занимает больше места.
Простая:
Создаётся персонально под себя и под свои нужды. Имеет минимум комбинаторов, сразу заданные параметры количества ресурса в сундуках для расчётов. Больше всего подходит для самостоятельного строительства, для хранения в личных чертежах и для обмена с игроками или для разных случаев, когда количество ресурса в 1 пачке похоже. Например, разная руда имеет одинаковое количество в пачке – поэтому может использоваться одна и та же схема логики для подсчёта. Обходится дешевле по созданию и занимает меньше места.
В статье будет использоваться второй вариант – простейшая логика с заранее просчитанными значениями.
Хочется сделать замечание, что в статье намеренно будут приводиться самые-самые обычные и простые действия. Даже, если это можно было как-то улучшить или использовать более логичные варианты вычислений или подключений. В статье не ставится задача создания супер-логики, задача статьи – как можно нагляднее и проще донести до игроков суть работы логики с приоритетом станции.
Алгоритм действий на станции погрузки.
На станции погрузки сундуки заполняются не всегда быстро. Поэтому некоторые станции могут уже быть готовыми к приёму поезда и ждать с полными сундуками, в то время, когда на других станциях сундуки ещё только заполняются. Логика должна высчитывать приоритет в зависимости от количества уже имеющихся ресурсов и выставлять его автоматически в станции.
Первым делом нужно соединить все сундуки сигнальным проводом. Для этого я использовал зелёный сигнальный провод. Здесь работает привычное цветовое разделение: зелёный сигнальный провод для всех схем, где передаётся или считывается информация, красный сигнальный провод для всех схем, где что-то запрещается, выключается или блокируется.
Сундуки объединённые сигнальным проводом соединяются с арифметическим комбинатором этим же сигнальным проводом. В сундуках будет накапливаться ресурс, и общее количество будет передаваться на вход комбинатора. В комбинаторе будет производиться вычисление и результат будет отсылаться в ж/д станцию в виде сигнала P. Для этого выход из комбинатора соединяется тем же зелёным сигнальным проводом со станцией.
Теперь нужно понять принцип вычисления приоритета. Так как эта схема проектируется под эту конкретную станцию, не стоит забывать, что под другую станцию с другим количеством сундуков или другим ресурсом всё придётся пересчитать. Каждый ресурс имеет в 1 пачке разное количество предметов. Например, железная руда содержится в 1 пачке в количестве 50 штук, а железные плиты в количестве 100 штук. Соответственно, общее количество руды и плит будет разным при одном количестве сундуков. То же самое касается и объёма сундуков. Стальные – самые объёмные, железные и деревянные вмещают меньшее количество предметов.
В нашем примере станция имеет разгрузку на 1 вагон, содержит 6 стальных сундуков по 48 ячеек каждый. Значит, на нашей станции всего 6х48=288 ячеек. Максимум железных плит (которые могут быть) на станции: 288 ячеек х 100 железных плит в пачке (ячейке) = 28800 железных плит.
Как правильно считать приоритет от 0 до 255, зная, что плит может быть максимум 28800? Вспоминаем школьную математику: 28800/255=112,9411764705882 – это количество плит в одной единице приоритета. Игра не использует дробные числа, поэтому нужно отбросить дробную часть и самостоятельно округлить. Сейчас разберёмся как сделать правильно.
То число, что мы получили при делении – это количество плит в 1 единице приоритета. Давайте попробуем разделить максимальное количество 28800 на округлённое 112. Получим примерно 257, что на самом деле больше, чем наш максимальный приоритет (255). Выходить за рамки мы не будем, округлим ещё раз, но теперь в бόльшую сторону, до 113. Делим 28800 на округлённое 113. Получаем примерно 254. Это немного меньше максимального приоритета, а значит не выбивается из диапазона приоритетов 0-255. Поэтому всё количество в сундуках будем делить именно на 113. Так мы узнаем результат являющийся тем самым приоритетом от 0 до 255, который нужно будет передать на станцию.
Открываем арифметический комбинатор, выставляем на вход значение «Каждый» в левую ячейку. Выбираем знак деления. Справа вписываем наше число 113. На выход устанавливаем сигнал P. Он будет запоминать наше полученное значение:
В комбинаторе количество железных плит в сундуках делится на 113, в полученном результате отбрасывается дробная часть и мы получаем некое число, которое тут же присваивается сигналу P.
Далее, нужно открыть окно настроек железнодорожной станции, к которой уже присоединён сигнальный провод, и в подключении логической сети поставить галочку на пункт «Установить приоритет». В ячейке рядом должен быть выбран именно сигнал P, который там используется по умолчанию. Из комбинатора приходит вычисленный сигнал приоритета Pи передаётся станции. Станция в автоматическом режиме устанавливает его, что можно увидеть в левой части окна в значении «Приоритет».
Соответственно, как только железные плиты заполнили сундуки, приоритет вырос и станция стала наиболее приоритетная для поездов желающих приехать на погрузку железных плит. И вот уже один поезд приехал и встал на погрузку несмотря на то, что станция находилась далеко от его первоначального местоположения:
Копируемс этой станции компоновку оборудования и настройки на все станции погрузки. Теперь все станции будут иметь приоритеты. Те, которые только что загрузили поезда – будут иметь очень низкий приоритет, от 0 и выше. Те, которые уже почти загрузились – будут иметь высокий приоритет, приближающийся к максимуму 255. Поезда не поедут загружаться на полупустые станции с низким приоритетом, а поедут забирать железные плиты на станции с высоким приоритетом.
Алгоритм действий на станции разгрузки.
Станции разгрузки наполняются ресурсами из поездов и, затем, отдают эти ресурсы на шину или на производство. Этот процесс может быть очень долгим или быстрым. Даже одинаковые станции могут в одинаковых условиях разгружаться разное время из-за приостановленного производства или иных причин. В обычных условиях поезда часто приезжают разгружаться на станции переполненные ресурсом, в то время, как другие станции могут ждать очень долго или вообще не дождаться поезда. И происходит это потому, что поезд выбирает самую ближайшую к себе станцию.
Логика должна помочь рассчитать приоритет для ж/д станции по количеству оставшегося ресурса. Но сначала нужно понять разницу между приоритетом на станции погрузки и приоритетом на станции разгрузки: станция погрузки получает высокие значения приоритета в зависимости от наполнения сундуков, а станция разгрузки получает высокие значения приоритета в зависимости от опустошения сундуков. То есть, чем будет меньше в сундуках ресурса, тем будет выше приоритет станции.
Все сундукина станции соединяются между собой сигнальным зелёным проводом. Затем соединяются со входом арифметического комбинатора. Следом стоит второй арифметический комбинатор, который соединён своим входом с выходом первого комбинатора. Выход второго комбинатора сигнальным зелёным проводом соединяется со станцией.
Начинаем настройку первого арифметического комбинатора так же как и на станции погрузки.
Принцип такой: здесь мы по-прежнему высчитываем значение приоритета разделив количество ресурса из сундуков на наше округлённое число, но дальше этот результат нужно отнять от 255. Всё дело в том, что сундуки не наполняются, а пустеют, значит количество ресурса уменьшается – приоритет растёт.
Вспоминаем, что мы узнали количество железных плит в одной единице приоритета посчитав это для такой же станции, но на погрузке: 113. В настройках первого комбинатора будет «Каждый» делить на 113 (как делали это раньше). А результат по-прежнему будет на выходе присваиваться сигналу P:
Во втором арифметическом комбинаторе производим вычитание из 255. На вход комбинатора поступит сигнал P со значением вычисленным в первом комбинаторе. Настраиваем так: в левую ячейку входа вписываем 255. Далее устанавливаем знак вычитания. В правую ячейку входа ставим сигнал P. На выход также устанавливаем сигнал P. Это позволит от 255 отнять пришедший результат вычислений первого комбинатора (от 0 до 255), а на выходе получить «правильный» результат для опустошаемых сундуков в виде приоритета в таком же сигнале P:
После того как один комбинатор посчитал приоритет, а другой отнял от 255 этот результат и получил «правильный» приоритет (обратный первому результату), нужно подать сигнал P сигнальным зелёным проводом на ж/д станцию. Открываем окно настройки станции и устанавливаем галочку на пункт «Установить приоритет». Проверяем, что в ячейке рядом стоит правильный сигнал P по умолчанию. Сразу после всех настроек станция начнёт автоматически выставлять пришедший по сигнальному проводу приоритет в значении «Приоритет».
Как результат – станция опустошила почти все сундуки и приоритет поднялся. Поезд тут же примчался на разгрузку:
Теперь скопируем оборудование и настройки на все станции разгрузки. Поезда будут прибывать на разгрузку на те станции, которые больше опустошили сундуки и получили высокий приоритет.
Приоритеты, прерывания, поезда, разные ресурсы.
В этой статье мы разобрались как с помощью приоритетов вызывать поезда на более актуальные станции, не позволяя им зацикливаться только на ближайших. Но это всё работало для использования лишь одного ресурса – железных плит. Наверняка некоторые читатели уже догадались, что здесь какой-то подвох: в прошлой статье были разные ресурсы – железные и медные плиты, а тут медных нет. И это действительно имеет свою особую причину.
Работая на приоритетах, поезда уходят по расписанию на те станции, которые определены в первом прерывании по списку. А так как поездов мало, а станций много, то, если бы в статье использовались два вида ресурса – железные и медные плиты, – то на медные плиты поезда не ездили бы никогда. Первым прерыванием в списке всегда находится проверка на топливо в локомотивах. И, если топлива достаточно, то срабатывает следующее прерывание – на железные плиты. Поезда перевозят железные плиты. До прерывания на медные плиты список просто не прочитался бы ни разу.
Причина всего этого – отсутствие должного количества поездов. Вспоминаем золотое правило количества поездов из статьи про ж/д станции с одинаковыми названиями – поездов должно быть на 1 меньше, чем всех станций. В этой текущей статье использовались 6 станций погрузки + 6 станций разгрузки и 3 станции депо (смотри рисунок 1 в начале статьи). Итого 15 станций. То есть, поездов в идеале должно быть 14. Но это для обычного расписания в локомотивах.
Представим себе, что по железной дороге у нас перевозятся разные ресурсы. Попробуем разобраться – как поступить чтобы прерывания не мешали перевозить разные ресурсы. Так как прерывания считываются и выполняются уже на маршруте, перестраивая расписание, то поэтому депо используется как «буфер» для всех поездов, случайно не получивших сработавшее прерывание и оставшихся без расписания. Золотое правило максимального количества поездов можно скорректировать для расписаний с прерываниями и депо таким образом:
Максимальное количество поездов с прерываниями в расписании должно быть на 1 меньше, чем станций, где депо с несколькими станциями является самостоятельным объектом засчитываемым как 1 станция.
! Иными словами, максимальное количество поездов с прерываниями в расписании и с депо должно быть равно количеству станций, без учёта депо.
То есть, если станций в примере из статьи 12, не считая депо с 3 станциями, то и поездов должно быть 12. Депо со станциями – это тот отдельный объект, который готов принимать поезда с прерыванием по топливу, и поезда, для которых не срабатывают прерывания из-за занятых станций. Поэтому депо со станциями не подсчитываем.
Ещё раз. Если станций будет 6 и есть отдельное депо, значит максимально поездов будет 6, станций будет 56 и есть отдельное депо, значит максимально поездов будет 56.
Нужно понимать, что мы говорим про максимальное количество поездов на ж/д линии имеющей депо и с прерываниями в поездах, настроенными на погрузку, а затем на разгрузку. И это всё для разных ресурсов! Поезда будут перевозить разную руду, разные плиты и другие предметы – разные поезда на разные ресурсы.
Теперь важное замечание про депо! На ж/д линии имеющей поезда с прерываниями для последовательной погрузки, а затем разгрузки требуется депо с таким количеством станций, сколько курсирует поездов. То есть, если у вас 60 станций и вы запускаете максимальное количество – 60 поездов, то и станций с названием «Депо» должно быть – 60. Понимаю, что сейчас кто-то поперхнулся чаем или кофе и начал возмущаться, мол, какие 60 станций «Депо»??
Гипотетически все поезда по разным причинам могут одновременно благополучно остаться без топлива, значит у всех сработает прерывание по топливу. Все 60 поездов поедут в депо для заправки. Депо должно быть готово принять все эти поезда. Если вы жмот, или вам лень строить, можно обойтись и 1 станцией в депо. Можно двумя станциями или тремя. Ваше дело. Но поезда будут ездить по очереди на заправку, а остальные в это время будут стоять на станциях и ждать. Не просто ждать – а занимать эти станции и не позволять другим поездам производить погрузку/разгрузку.
Помимо заправки поездов на станциях депо, может произойти самый банальный из всех банальных случаев в игре – месторождения иссякнут и поезда перестанут ездить на них. Вас нет на планете, вам не до перестроек, а поездам надо куда-то деваться. Вот они и уйдут в депо.
Теперь по количеству поездов закрепляем главную мысль, которую мы вывели из золотого правила: если в прерываниях используется последовательность – погрузка, затем разгрузка, – поездов должно быть столько, сколько используется станций, не считая станций в депо. Можно ли пустить на маршрут меньше поездов? Можно. Можно ли пустить на маршрут всего 2 поезда? Можно. А 1 поезд? Можно! Но правильно ли это?
Нет, неправильно! Мы знаем, что по расписанию в прерывании поезд сначала должен загрузить ресурс, а затем разгрузить. А если у нас несколько прерываний на разные ресурсы и несколько станций, то чем меньше поездов – тем больше гарантия, что все они будут возить ресурс указанный в первом прерывании. Те, которые «не помещаются» в первое прерывание – поедут по второму прерыванию. Может, если станций с ресурсами не много, то и на третье прерывание кто-то поедет. Но из-за небольшого количества поездов остальные прерывания останутся не сработавшими, а поезда на те станции не приедут никогда.
А можно ли пустить на маршрут больше поездов, чем получается максимально по золотому правилу? Можно. И это не нарушит работу железной дороги. Все лишние поезда «осядут» на станциях депо. Но при этом депо должно содержать сколько положено станций – по количеству поездов.
Тогда зачем устанавливать логику на станциях и использовать приоритеты, если поезда всё равно ездят только по первым прерываниям, если их малое количество?
Логика для подсчёта приоритетов ж/д станций необходима чтобы в группе станций использующих один ресурс выявлять наиболее актуальные станции и запрашивать туда поезда. Логика и приоритеты не могут заставить локомотивы изменить очерёдность считывания прерываний и отправить поезда на другие ресурсы. Но игрок может запустить максимальное количество поездов, либо даже больше максимального, при условии, что депо построено правильно, как описывалось выше – под количество всех поездов.
Выводы.
Логика для приоритетов может быть сложной, узнавать ресурс, высчитывать его количество и высчитывать приоритет автоматически.
Логика для приоритетов может быть простой, в ней вручную вписаны данные для вычисления.
Логика для приоритетов станций не влияет на прерывания и не умеет управлять расписанием поездов. Поезда следуют строго соответствуя расписанию. Все поезда разделяются на разные станции с разными ресурсами в зависимости от количества поездов и станций, от количества прерываний по ресурсам. Но при этом поезда перевозящие один и тот же ресурс отправляются на более приоритетные станции.
Станций депо должно быть достаточно для принятия всех поездов работающих на прерываниях – погрузка/разгрузка – в идеале количество станций депо должно равняться количеству поездов или быть больше.
Чертежи.
К этой статье в качестве тренировочных материалов прилагаются два чертежа приведённых выше станций погрузки и разгрузки с логикой на вычисление приоритетов. Чертежи к другим статьям (и не только к статьям) можно скачать в текстовых файлах в моём канале Telegram и в чате с чертежами.
-----------------------------------------
Прямая ссылка на чертежи из статьи в моём канале Telegram: https://t.me/format_aa/246
☕️ Если вы хотите угостить меня кофе или вкусняшкой за старания, сделать это можно с помощью доната: https://boosty.to/format_aa/donate
-----------------------------------------
Подпишись на канал и узнавай больше +
#Формат_АА
#Factorio
#схема
#чертежи
#приоритет
#поезд
#расписание
#топливо