Если вы запускали стадийный сервер, то знаете, как это обычно выглядит: ночью правишь конфиги, поднимаешь кап, открываешь грейд, перезапускаешь сервер и надеешься, что ничего не забыл. Теперь сервер делает это сам. Он помнит текущую главу и переключает её по таймеру, к конкретной дате или когда достаточно игроков дошло до капа. Новые ограничения начинают действовать сразу, рестарт не нужен.
Если нужно вмешаться руками, переключить главу можно из игры или из Telegram-бота.
Что можно ограничивать
Кроме того, у каждой стадии свои множители рейтов, свой догоняющий бонус опыта для отстающих и свои группы спавна, которые появляются и исчезают вместе с главой.
На ГМов ограничения не действуют.
Команды
Для игроков
.stage (а также .stages и .chapter) открывает окно с текущей главой, временем до следующей, числом игроков на капе, личным бонусом опыта и правилами всех глав. Команду можно отключить в настройках.
Для администратора в игре
В Telegram-боте (если бот включён в telegram_bot.properties)
Настройка
Всё настраивается в одном файле: gameserver/data/stages.xml. Отредактировали, выполнили //stage reload, изменения применились.
Общая структура файла:
Стадии идут по возрастанию id. Название и описание стадии берутся из data/string/strings_ru.properties, strings_en.properties и других языковых файлов по ключам из name_address и desc_address, поэтому каждый игрок видит их на своём языке.
Ниже разобраны все параметры. Если атрибут не указан, используется значение из колонки «По умолчанию».
Жёсткий кап и полоска опыта. Пример для maxLevel="52":
Мягкий кап. Если softCapExpMul="0.10", то после maxLevel игрок получает только 10% опыта. Самые упорные возьмут уровень-другой сверху, но далеко от остальных не уйдут.
Профессия. Ограничение действует везде: в классмастере, в комьюнити-борде, у NPC профессий и в квестах. Сабклассы оно тоже касается. Если профессия закрыта, у игрока ничего не списывается: ни адена, ни предметы, ни марки. Квест на 3-ю профессию останавливается на последнем шаге, и его можно сдать, когда профессию откроют.
Сабклассы. allowSubClass="false" запрещает брать, покупать и заменять сабы. Переключаться между уже взятыми сабами можно и при закрытых сабах.
Грейд. Вещь выше грейда стадии надеть нельзя. Если откатить стадию назад, лишняя экипировка снимется в инвентарь. Если в maxGrade опечатка, при загрузке в логе появится предупреждение, а ограничение грейда на этой стадии не будет работать.
Заточка. Предмет, который уже на лимите, нельзя положить в окно заточки, и свиток при этом не сгорает. Свиток со случайным приростом (+1..+3) при успехе не поднимет заточку выше лимита стадии.
Пример: четыре недели
Расклад по неделям:
Если есть идеи, что ещё добавить в стадии, пишите в теме, посмотрю и сделаю.
Если нужно вмешаться руками, переключить главу можно из игры или из Telegram-бота.
Что можно ограничивать
- кап уровня: жёсткий или мягкий, когда после капа опыт идёт со штрафом;
- максимальную профессию, в том числе на сабклассе;
- сабклассы и олимпиаду;
- грейд экипировки и отдельные предметы;
- заточку: отдельно оружие, броню и бижутерию;
- вход в зоны и инстансы, мультиселлы, урон по рейдам и эпикам.
Кроме того, у каждой стадии свои множители рейтов, свой догоняющий бонус опыта для отстающих и свои группы спавна, которые появляются и исчезают вместе с главой.
На ГМов ограничения не действуют.
Команды
Для игроков
.stage (а также .stages и .chapter) открывает окно с текущей главой, временем до следующей, числом игроков на капе, личным бонусом опыта и правилами всех глав. Команду можно отключить в настройках.
Для администратора в игре
| Команда | Что делает |
|---|---|
| //stage | Панель управления стадиями |
| //stage toggle | Включить или выключить систему на ходу |
| //stage next | Перейти на следующую стадию с анонсом |
| //stage prev | Откатиться на предыдущую стадию |
| //stage set <id> | Включить стадию по номеру |
| //stage set <id> silent | То же, но без анонса на сервер |
| //stage pause / resume | Поставить таймер на паузу или снять с паузы |
| //stage addhours <часы> | Добавить или убавить время текущей стадии, например 24 или -2 |
| //stage reload, //reload_stages | Перечитать stages.xml (есть и в //admin -> Reload) |
В Telegram-боте (если бот включён в telegram_bot.properties)
| Команда | Что делает |
|---|---|
| /stage | Статус, таймер и список глав |
| /stage toggle | Включить или выключить систему |
| /stage next, /stage prev | Следующая или предыдущая стадия |
| /stage set <id> | Включить стадию по номеру |
| /stage pause, /stage resume | Пауза и продолжение таймера |
| /stage addhours <часы> | Изменить таймер текущей стадии |
| /stage reload | Перечитать stages.xml, не заходя в игру |
Настройка
Всё настраивается в одном файле: gameserver/data/stages.xml. Отредактировали, выполнили //stage reload, изменения применились.
Общая структура файла:
XML:
<stages enabled="true" announceOnEnter="true" voiceCommand="true" notifyTelegram="true">
<stage id="1" name_address="stage.1.name" desc_address="stage.1.desc">
<transition ... /> <!-- когда переходить на следующую -->
<limits ... /> <!-- капы и запреты -->
<rates ... /> <!-- рейты стадии -->
<catchup ... /> <!-- бонус для отстающих, строк может быть несколько -->
<restrictions ... /> <!-- закрытый контент -->
<spawns ... /> <!-- группы спавна -->
</stage>
</stages>
Стадии идут по возрастанию id. Название и описание стадии берутся из data/string/strings_ru.properties, strings_en.properties и других языковых файлов по ключам из name_address и desc_address, поэтому каждый игрок видит их на своём языке.
Ниже разобраны все параметры. Если атрибут не указан, используется значение из колонки «По умолчанию».
| Атрибут | По умолчанию | Описание |
|---|---|---|
| enabled | false | Включена ли система. При false сервер работает как обычный, без стадий. |
| announceOnEnter | true | При входе в игру писать игроку текущую главу, время до следующей и его бонус опыта. |
| voiceCommand | true | Разрешить игрокам команду .stage. |
| notifyTelegram | true | Отправлять в Telegram отчёт о каждом переходе, в том числе о ночном по таймеру. |
У последней стадии этот блок не нужен, переходить после неё некуда.
Форматы даты для endTime: 2026-11-15 20:00:00, 2026-11-15 20:00, 15.11.2026 20:00, 20:00 15.11.2026.
С endTime удобно открывать главу под вечерний прайм, например ровно в пятницу в 20:00.
Режимы mode:
Как считается прогресс игроков. Учитываются уникальные аккаунты, у которых есть персонаж или сабкласс с уровнем не ниже капа стадии. Несколько персонажей на одном аккаунте считаются за одного, так что твинки переход не ускорят. ГМы, забаненные персонажи и персонажи на удалении в счёт не идут. Условие проверяется раз в 10 секунд.
| Атрибут | По умолчанию | Описание |
|---|---|---|
| durationHours | 0 | Длительность стадии в часах с момента её начала. 168 = неделя. |
| durationMinutes | 0 | Минуты, которые прибавляются к часам. Удобно для тестов. |
| endTime | - | Точная дата окончания по часам сервера. Если она указана, durationHours и durationMinutes игнорируются. |
| unlockPlayersAtCap | 0 | Сколько аккаунтов должно дойти до maxLevel этой стадии. 0 - условие выключено. |
| mode | ANY | Как сочетаются таймер и прогресс игроков, см. ниже. |
Форматы даты для endTime: 2026-11-15 20:00:00, 2026-11-15 20:00, 15.11.2026 20:00, 20:00 15.11.2026.
С endTime удобно открывать главу под вечерний прайм, например ровно в пятницу в 20:00.
Режимы mode:
- ANY - переход при первом наступившем условии: кончился таймер или набралось нужное число игроков на капе;
- ALL - нужны оба условия сразу: и время вышло, и игроки докачались;
- MANUAL - автоматического перехода нет, главу переключает только администратор.
Как считается прогресс игроков. Учитываются уникальные аккаунты, у которых есть персонаж или сабкласс с уровнем не ниже капа стадии. Несколько персонажей на одном аккаунте считаются за одного, так что твинки переход не ускорят. ГМы, забаненные персонажи и персонажи на удалении в счёт не идут. Условие проверяется раз в 10 секунд.
| Атрибут | По умолчанию | Описание |
|---|---|---|
| maxLevel | 0 | Кап уровня. 0 - капа нет. |
| allowCapBarFill | true | При жёстком капе разрешает добивать полоску опыта последнего уровня, подробности ниже. |
| softCapExpMul | 0.0 | 0.0 - жёсткий кап. Больше нуля - мягкий кап, подробности ниже. |
| maxProfession | -1 | Максимальная профессия: 0 - нельзя брать даже первую, 1, 2, 3 - соответствующая профессия, -1 - без ограничений. |
| allowSubClass | true | Можно ли добавлять, покупать и менять сабклассы. |
| allowOlympiad | true | Можно ли регистрироваться на олимпиаду. |
| maxGrade | - | Максимальный грейд экипировки: NONE, D, C, B, A, S. Если не указан, разрешены любые вещи. |
| maxWeaponEnchant | -1 | Лимит заточки оружия. |
| maxArmorEnchant | -1 | Лимит заточки брони: шлемы, верх, низ, перчатки, ботинки, щиты, сигили, рубашки, пояса. |
| maxJewelryEnchant | -1 | Лимит заточки бижутерии: кольца, серьги, ожерелья. |
Жёсткий кап и полоска опыта. Пример для maxLevel="52":
- allowCapBarFill="true": игрок берёт 52-й уровень и может набить опыт до 99.99%, но 53-й не получит. Мы рекомендуем этот вариант: после первой смерти в PvP игрок не слетает с 52-го уровня и спокойно фармит SP.
- allowCapBarFill="false": опыт замирает ровно на 52-м уровне и 0%. SP при этом начисляется как обычно.
Мягкий кап. Если softCapExpMul="0.10", то после maxLevel игрок получает только 10% опыта. Самые упорные возьмут уровень-другой сверху, но далеко от остальных не уйдут.
Профессия. Ограничение действует везде: в классмастере, в комьюнити-борде, у NPC профессий и в квестах. Сабклассы оно тоже касается. Если профессия закрыта, у игрока ничего не списывается: ни адена, ни предметы, ни марки. Квест на 3-ю профессию останавливается на последнем шаге, и его можно сдать, когда профессию откроют.
Сабклассы. allowSubClass="false" запрещает брать, покупать и заменять сабы. Переключаться между уже взятыми сабами можно и при закрытых сабах.
Грейд. Вещь выше грейда стадии надеть нельзя. Если откатить стадию назад, лишняя экипировка снимется в инвентарь. Если в maxGrade опечатка, при загрузке в логе появится предупреждение, а ограничение грейда на этой стадии не будет работать.
Заточка. Предмет, который уже на лимите, нельзя положить в окно заточки, и свиток при этом не сгорает. Свиток со случайным приростом (+1..+3) при успехе не поднимет заточку выше лимита стадии.
Множители умножаются на базовые рейты из конфигов и действуют на всех игроков, пока стадия активна. Значение 1.0 оставляет рейты сервера без изменений.
| Атрибут | По умолчанию | Что умножает |
|---|---|---|
| expMul | 1.0 | Опыт |
| spMul | 1.0 | SP |
| adenaMul | 1.0 | Адену |
| dropMul | 1.0 | Дроп |
| spoilMul | 1.0 | Спойл |
Пример: третья неделя сервера, кап уже 75. Приходит новичок с первого уровня, а стартовые локации пустые и рейты обычные. Скорее всего, через час он уйдёт.
Catchup ускоряет прокачку только тем, кто отстал от основной массы игроков. Когда персонаж догоняет остальных, бонус отключается сам.
Строк может быть несколько, так можно сделать ступени:
С 1 по 51 уровень персонаж получает x3, с 52 по 63 - x1.8, а с 64 бонуса нет, и он качается наравне со всеми.
На первой стадии catchup обычно не нужен: все стартуют одновременно.
Catchup ускоряет прокачку только тем, кто отстал от основной массы игроков. Когда персонаж догоняет остальных, бонус отключается сам.
| Атрибут | По умолчанию | Описание |
|---|---|---|
| minLevel | 1 | С какого уровня действует бонус (включительно) |
| maxLevel | 1 | До какого уровня действует бонус (включительно) |
| expMul | 1.0 | Множитель опыта |
| spMul | = expMul | Множитель SP. Если не указан, равен expMul. |
Строк может быть несколько, так можно сделать ступени:
XML:
<catchup minLevel="1" maxLevel="51" expMul="3.0" spMul="3.0" />
<catchup minLevel="52" maxLevel="63" expMul="1.8" spMul="1.8" />
На первой стадии catchup обычно не нужен: все стартуют одновременно.
Значения можно перечислить через запятую в атрибуте или вынести отдельными тегами. Работают оба варианта, можно и смешивать.
Как это работает в игре:
ID эпиков для справки: 29001 Queen Ant, 29006 Core, 29014 Orfen, 29022 Zaken, 29020 Baium, 29019 Antharas, 29028 Valakas, 29045 Frintezza.
| Атрибут | Тег | Что закрывает |
|---|---|---|
| blockedZones | <zone name="..." /> | Зоны по имени из data/zone/*.xml |
| blockedInstances | <instance id="..." /> | Инстансы по ID из data/instances |
| blockedMultisells | <multisell id="..." /> | Мультиселлы по ID |
| blockedItems | <item id="..." /> | Предметы, которые нельзя надеть, даже если их грейд разрешён |
| blockedBosses | <boss npcId="..." /> | Рейды и эпики, по которым не проходит урон |
Как это работает в игре:
- Зоны. Если игрок зашёл или телепортировался в закрытую зону, он получит предупреждение и будет отправлен в город. Это касается только основного мира: зоны с таким же именем внутри инстансов не трогаются.
- Мультиселлы. Закрытый мультиселл не откроется. Если игрок открыл его до смены стадии, купить в нём всё равно не получится.
- Боссы. Закрытый босс не получает урона, а игроку приходит сообщение, что этот босс недоступен на текущей главе.
ID эпиков для справки: 29001 Queen Ant, 29006 Core, 29014 Orfen, 29022 Zaken, 29020 Baium, 29019 Antharas, 29028 Valakas, 29045 Frintezza.
В файлах data/spawn/*.xml у блока spawn можно задать имя группы через event_name. Затем перечислите группы в стадии:
Когда стадия включается, указанные группы спавнятся. Когда сервер переходит на стадию, где этой группы нет, её NPC и монстры убираются из мира. Рестарт для этого не нужен.
XML:
<spawns groups="stage1_event_mobs,stage1_shop_npc" />
<!-- или так -->
<spawns>
<group name="stage1_event_mobs" />
</spawns>
Пример: четыре недели
Расклад по неделям:
- Кап 52, грейд C, только 2-я профессия, сабы и олимпиада закрыты. Закрыты Zaken, Baium, Antharas и Valakas. Переход через 7 дней или раньше, если до капа дойдут 50 аккаунтов.
- Кап 64, грейд B, открывается Zaken. Тем, кто ниже 52-го уровня, опыт x2.
- Кап 75, грейд A, открываются сабклассы и Baium. Ступенчатый бонус для отстающих.
- Капов больше нет: 3-я профессия, S-грейд, олимпиада и все эпики.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stages SYSTEM "stages.dtd">
<stages enabled="false" announceOnEnter="true" voiceCommand="true" notifyTelegram="true">
<!-- Неделя 1: кап 52, C-грейд, 2-я профа, заточка +6/+4/+4 -->
<stage id="1" name_address="stage.1.name" desc_address="stage.1.desc">
<transition durationHours="168" durationMinutes="0" unlockPlayersAtCap="50" mode="ANY" />
<limits maxLevel="52"
allowCapBarFill="true"
softCapExpMul="0.0"
maxProfession="2"
allowSubClass="false"
allowOlympiad="false"
maxGrade="C"
maxWeaponEnchant="6"
maxArmorEnchant="4"
maxJewelryEnchant="4" />
<rates expMul="1.0" spMul="1.0" adenaMul="1.0" dropMul="1.0" spoilMul="1.0" />
<restrictions blockedBosses="29019,29020,29022,29028" />
</stage>
<!-- Неделя 2: кап 64, B-грейд, заточка +8/+6/+6, открыт Закен -->
<stage id="2" name_address="stage.2.name" desc_address="stage.2.desc">
<transition durationHours="168" durationMinutes="0" unlockPlayersAtCap="40" mode="ANY" />
<limits maxLevel="64"
allowCapBarFill="true"
softCapExpMul="0.0"
maxProfession="2"
allowSubClass="false"
allowOlympiad="false"
maxGrade="B"
maxWeaponEnchant="8"
maxArmorEnchant="6"
maxJewelryEnchant="6" />
<rates expMul="1.0" spMul="1.0" adenaMul="1.0" dropMul="1.0" spoilMul="1.0" />
<catchup minLevel="1" maxLevel="51" expMul="2.0" spMul="2.0" />
<restrictions blockedBosses="29019,29020,29028" />
</stage>
<!-- Неделя 3: кап 75, A-грейд, заточка +12/+8/+8, сабы и Баюм -->
<stage id="3" name_address="stage.3.name" desc_address="stage.3.desc">
<transition durationHours="168" durationMinutes="0" unlockPlayersAtCap="30" mode="ANY" />
<limits maxLevel="75"
allowCapBarFill="true"
softCapExpMul="0.0"
maxProfession="2"
allowSubClass="true"
allowOlympiad="false"
maxGrade="A"
maxWeaponEnchant="12"
maxArmorEnchant="8"
maxJewelryEnchant="8" />
<rates expMul="1.0" spMul="1.0" adenaMul="1.0" dropMul="1.0" spoilMul="1.0" />
<catchup minLevel="1" maxLevel="51" expMul="3.0" spMul="3.0" />
<catchup minLevel="52" maxLevel="63" expMul="1.8" spMul="1.8" />
<restrictions blockedBosses="29019,29028" />
</stage>
<!-- Финал: всё открыто, transition не нужен -->
<stage id="4" name_address="stage.4.name" desc_address="stage.4.desc">
<limits maxLevel="0"
maxProfession="-1"
allowSubClass="true"
allowOlympiad="true"
maxWeaponEnchant="-1"
maxArmorEnchant="-1"
maxJewelryEnchant="-1" />
<rates expMul="1.0" spMul="1.0" adenaMul="1.0" dropMul="1.0" spoilMul="1.0" />
<catchup minLevel="1" maxLevel="63" expMul="3.5" spMul="3.5" />
<catchup minLevel="64" maxLevel="74" expMul="2.0" spMul="2.0" />
</stage>
</stages>
Если есть идеи, что ещё добавить в стадии, пишите в теме, посмотрю и сделаю.
Last edited: