Skip to content

Группы спавна

Группы спавна - это именованные наборы класснеймов с условиями, которые можно переиспользовать сразу в нескольких точках и делать состав спавна зависимым от времени суток, погоды и случая.

Что дают группы

  • Переиспользование: одна группа (@zombies) подключается в десятках точек; правите её в одном месте - меняется везде.
  • Условный состав: две группы @dayAnimals и @nightAnimals в одном spawnList точки - днём спавнятся одни существа, ночью другие.
  • Погодные существа: волки в туман, особые зомби в грозу.
  • Редкие появления: группа с chance: 0.15 попадает в спавн не каждый цикл (редкий патруль/босс).

Как это работает

Точка по-прежнему сама триггерит спавн (вход игрока, cooldown, triggerWorkingTime). Группа не спавнит сама - она лишь определяет состав пула класснеймов, из которого точка выбирает случайный элемент при каждом срабатывании.

В момент спавна точка строит "эффективный пул": разворачивает все @group-ссылки из своего spawnList с учётом условий группы и смешивает их с обычными класснеймами. Обычные точки (без @) ведут себя ровно как раньше - эффективный пул идентичен spawnList.

Режим выбора группы: combined или exclusive 2.1

Поле groupSelectMode на точке задаёт, как точка выбирает сущности из нескольких @group-ссылок за один цикл спавна.

combined (по умолчанию)

Все прошедшие условия группы разворачиваются в один плоский пул вместе с обычными класснеймами. Затем точка делает spawnMin..spawnMax случайных выборок из этого пула - каждая сущность выбирается независимо. Если поле не задано - режим combined.

spawnList: ["@Dogs", "@Boars"],  spawnMin: 3, spawnMax: 5
→ за цикл может получиться: 1 собака + 2 кабана + 2 собаки  (смесь из обеих групп)

exclusive - одна группа за цикл

За цикл спавна точка выбирает одну группу из прошедших условия и спавнит spawnMin..spawnMax сущностей из её состава. Так получают "3-5 плотей ИЛИ 3-5 собак ИЛИ 3-5 кабанов" - каждый раз другая группа целиком.

json
{
  "pointId": 36,
  "spawnMin": 3,
  "spawnMax": 5,
  "groupSelectMode": "exclusive",
  "spawnList": [
    "@Dogs_1",
    "@Plots_1",
    "@Boars_1",
    "@Cats_1",
    "@Tushkans_1"
  ]
}

Алгоритм exclusive:

  1. Из top-level @group-ссылок точки отбираются группы, прошедшие слой доступа (isDisabled / spawnOnce / spawnTime / chance / weather). chance бросается здесь один раз - это по-прежнему слой доступа, а не вес.
  2. Выбирается одна случайная группа.
  3. Её состав разворачивается в эффективный пул (включая вложенные @group - со своими условиями).
  4. Дальше - как обычно: spawnMin..spawnMax выборок GetRandomElement из пула, |chance на списке сущностей так же работает. spawnCountLimit ограничивает итоговое число.

Поведение внутри выбранной группы идентично combined

Выбрав группу, точка спавнит из её состава ровно так же, как combined спавнил бы из единственного пула или списка спавна: с дубликатами (две одинаковые собаки) и элементным |chance. Никаких "по одному каждого" или "без повторов" - это сделано намеренно.

Ограничения exclusive

  • spawnList точки должен содержать только @group-ссылки. Прямой classname в exclusive-точке - ошибка валидации (он никогда не заспавнится: пул строится из состава выбранной группы). Если нужно заспавнить отдельный classname - заведите под него группу из одного элемента.
  • isAiBandits-группы в exclusive не поддерживаются (они идут отдельным путём и несовместимы с моделью "одна группа → N её сущностей"). Будет ошибка валидации при старте.
  • Если все группы провалили условия (или spawnList пуст) - в этом цикле не заспавнится ничего (как и в combined при пустом пуле).

Если у групп заданы spawnMin/spawnMax, счёт цикла следует выбранной группе: "3-5 волков ИЛИ ровно 1 медведь" задаётся диапазонами самих групп, а не точкой. См. spawnMin/spawnMax в списке полей.

Ссылка на группу в spawnList точки

На группу ссылаются из spawnList точки префиксом @:

"spawnList": [
  "Animal_UrsusArctos",
  "@dayAnimals",
  "@nightAnimals"
]

В этом примере эффективный пул = медведь + элементы группы @dayAnimals (если её условия пройдены) + элементы группы @nightAnimals (если её условия пройдены). Из получившегося пула точка выбирает случайный элемент, как и для обычного spawnList.

Префикс @

Префикс @ выбран потому, что ни один classname DayZ не начинается с этого символа - коллизий нет. Не ставьте пробелы вокруг @: @dayAnimals - правильно, @ dayAnimals - нет (мод почистит пробелы, но лучше писать сразу чисто).

Файлы групп

Группы хранятся в папке $profile:MPG_Spawner/Groups/. Каждый файл - массив групп (как точки в Points/):

$profile:MPG_Spawner/
├── Config.json
├── Points/
│   └── ...точки...
└── Groups/                  ← папка групп спавна
    ├── Animals.json
    ├── Weather.json
    └── ...

Автоскан папки

Папка Groups/ сканируется целиком при запуске сервера - все *.json грузятся автоматически. Список файлов в Config.json (как pointsConfigs для точек) не нужен: просто положите .json-файл в папку, и мод его подхватит.

Группа с дублирующимся groupName (в том же или другом файле) - ошибка: в лог пишется ERROR, загружается первая встретившаяся группа с этим именем, дубликат пропускается. Имена чувствительны к регистру.

Поля группы

json
{
  "groupName": "dayAnimals",
  "isDisabled": false,
  "spawnTime": "6-18",
  "chance": 1.0,
  "weather": [
    "clear",
    "cloudy"
  ],
  "spawnList": [
    "Animal_UrsusArctos",
    "Animal_CanisLupus_Grey|0.5"
  ]
}

groupName

groupName - уникальное имя группы. По нему на группу ссылаются из spawnList точки (@groupName). Не должно повторяться (дубликат → ERROR в лог).

Пример: "groupName": "dayAnimals",

isDisabled

isDisabled - отключить группу. Отключённая группа не разворачивается в пул ни в одной точке, но остаётся в файлах (удобно временно выключить набор существ, не удаляя конфиг).

Значение по умолчанию: 0 (включена). Старые конфиги без поля работают как раньше.

Пример: "isDisabled": 1,

spawnTime

spawnTime - окно игрового времени, в которое группа попадает в пул. Формат идентичен timing.workingTime точки:

всегда (значение по умолчанию): "0-24"
днём (с 6 до 18):               "6-18"
ночью (с 18 до 6):              "18-6"   ← перенос через полночь

Поддерживается перенос через полночь ("18-6" = с 18:00 до 06:00). Значение по умолчанию "0-24" - группа доступна круглосуточно.

Это игровое время

spawnTime - это игровое время (как triggerWorkingTime), а не реальное. Учитывайте настройки скорости течения игрового времени на вашем сервере.

chance

chance - групповой шанс доступа, число от 0 до 1. Бросается один раз за цикл спавна для группы: прошла → все её элементы попадают в пул; не прошла → группы в пуле нет.

Значение по умолчанию: 1.0 (всегда доступна).

Слой доступа, а не множитель

chance группы и chance отдельных элементов внутри её spawnList - разные слои:

  • chance группы отвечает за доступ (будет ли группа в пуле вообще);
  • chance элемента (через |, см. spawn.list) отвечает за выбор (выпадет ли именно этот элемент из пула).

Они не перемножаются. Пример: группа с chance: 0.15 и одним элементом Animal_UrsusArctos → в ~85% циклов спавна медведя в пуле не будет вовсе, в ~15% - он в пуле (с элементным chance 1.0, т.е. точно выпадет при выборе).

Как полностью отключить группу

Чтобы группа никогда не попадала в пул, используйте isDisabled: 1. chance: 0 тоже сработает как "никогда", но isDisabled - каноничный способ (и chance <= 0 трактуется как "поле не задано → 1.0").

weather

weather - массив типов погоды (логика ИЛИ), при которых группа попадает в пул. Пусто/отсутствует → группа доступна при любой погоде.

Допустимые значения:

ТипУсловие (фиксированные пороги)
clearоблачность < 40%
cloudyоблачность ≥ 40% и нет дождя/снега/тумана
rainсила дождя ≥ 30%
fogсила тумана ≥ 40%
snowсила снегопада ≥ 30%
stormсила дождя ≥ 30% и скорость ветра ≥ 10 м/с

Как это читается

["fog", "storm"] = группа в пуле, если сейчас туман ИЛИ гроза. ["rain"] = только в дождь. Пороги фиксированы и подобраны так, чтобы погода была визуально выражена - их нельзя менять из конфига намеренно (проще диагностировать). Невалидный тип (напр. "tornado") → WARN в лог, поле игнорируется, группа проверяется по остальным типам.

Пример:

доступна в дождь или грозу:
"weather": ["rain", "storm"],

доступна при любой погоде:
"weather": [],

spawnOnce

spawnOnce - группа появляется один раз за сессию. После того как её контент реально заспавнился, группа больше не разворачивается в пул до рестарта сервера или перезагрузки конфига.

Значение по умолчанию: 0 (группа доступна каждый цикл спавна). Старые конфиги без поля работают как раньше.

Флаг ставится по факту реального спавна

Группа считается "заспавнившейся" только когда из неё создан объект, а не когда она попала в пул. Это значит:

  • Если группа в пуле, но её элемент не выпал в выборке (точка выбрала другой элемент) - попытка не потрачена: при следующем цикле группа снова в пуле.
  • Комбо с chance группы ниже 1: пока chance не пропустит группу в пул, флаг не ставится.

Флаг НЕ снимается после смерти

spawnOnce означает "один раз за сессию", а не "один раз живой". Когда все объекты группы умрут, флаг не снимается - группа остаётся "израсходованной" до рестарта сервера или config-reload. Если нужно повторное появление после смерти - не используйте spawnOnce.

Сброс происходит при: рестарте сервера (in-memory состояние живёт только в RAM) и перезагрузке конфигурации (ResetTriggers).

Пример: уникальный босс, появляющийся один раз за рестарт:

json
{
  "groupName": "alphaWolf",
  "isDisabled": false,
  "spawnTime": "18-6",
  "chance": 0.3,
  "weather": [
    "fog",
    "storm"
  ],
  "spawnOnce": true,
  "notificationTextSpawn": "⚠️ Появился Альфа-волк!",
  "spawnList": [
    "Animal_CanisLupus_Grey"
  ]
}

notificationTextSpawn

notificationTextSpawn - собственная нотификация группы при реальном спавне её контента. Формат идентичен notifications.textSpawn точки: %1 = количество, %2..%5 = склонения через ; (см. GetDeclensionText).

Значение по умолчанию: "" (групповой нотификации нет).

Дополнительно к точечной

Групповая нотификация срабатывает в дополнение к точечной (если точечная задана). Игрок может получить обе за один цикл спавна: общую точечную и тематическую групповую. Они независимы - если у точки notificationTextSpawn пуст, групповая всё равно сработает.

%1 - это счётчик группы, а не общий

%1 в групповой нотификации = количество объектов именно этой группы, заспавненных в текущем цикле (а не общий queuedCount точки). Это чтобы "Появился 1 Альфа" было корректнее "Появилось 5 Альфа". Заголовок, иконка и время нотификации берутся из настроек точки - у группы их нет.

Пример:

группа-"волна" с тематическим текстом и склонением:
"notificationTextSpawn": "Накатило %1 %2.;заражённ|ый|ых|ых;"

→ при спавне 3 объектов группы: "Накатило 3 заражённых"
→ при спавне 1 объекта группы:  "Накатило 1 заражённый"

spawnList

spawnList группы - полностью идентичен spawnList точки: тот же формат "Class|chance|lifeTime|qty|health|foodStage". См. подробное описание в spawn.list точки.

Вложенные группы

В spawnList группы можно ссылаться на другие группы через @ - они развернутся рекурсивно. Циклы (@a@b@a) детектируются и пресекаются (в лог пишется WARN, повторное вхождение пропускается).

spawnMin

spawnMin - нижняя граница количества спавна самой группы. Работает в паре со spawnMax: если оба больше нуля, при "выборе" этой группы счёт берётся из её диапазона, а не из точечного или волнового. Приоритет: группа > волна > точка.

Условие срабатывания - однородный пул: за цикл в пуле остались записи только этой группы. Это гарантировано в exclusive-режиме; в combined правило действует, когда в spawnList точки одна эта группа. Смешанный пул (несколько групп, группа + прямые класснеймы) - счёт точечный, как раньше.

Значение по умолчанию: 0 - не задано. Выразить "спавнить 0" нельзя.

spawnMax

spawnMax - верхняя граница. Семантика и условие срабатывания - как у spawnMin. Правила нормализации при загрузке:

  • задан только один из пары - это фиксированное количество (второй подтягивается к первому);
  • spawnMax меньше spawnMin - поднимается до spawnMin, в лог пишется WARN;
  • у isAiBandits-группы пара игнорируется (количество задаёт DynamicAIB.json), при заданных значениях - WARN.

Вложенные @group наследуют группу-источник от top-level ссылки: собственные spawnMin/spawnMax вложенной группы не действуют - счёт определяет та группа, на которую ссылается точка или волна.

isAiBandits

isAiBandits - группа ботов из стороннего мода AI_Bandits. При true группа не разворачивается в пул выбора класснеймов - вместо этого триггер запрашивает спавн целой группы AI_Bandits по имени (через bridge-мод MPG_Spawner_AIBandits).

groupName такой группы должно совпадать с GroupLocations[].name в DynamicAIB.json. Состав ботов (лут, одежду, оружие) настраивают в DynamicAIB.json, а не в spawnList этой группы - spawnList у isAiBandits-группы игнорируется (мод напишет WARN, если он задан).

Условия (spawnTime/weather/chance/isDisabled/spawnOnce) применяются к бандитской группе как к обычной. Несколько бандитских групп в одной точке спавнятся независимо: все прошедшие условия группы заспавнятся целиком в одном цикле.

Значение по умолчанию: 0 (обычная группа спавна). Подробности - в AI_Bandits интеграция.

Пример группы бандитов:

json
{
  "groupName": "nightBandits",
  "isAiBandits": true,
  "isDisabled": false,
  "spawnTime": "18-6",
  "chance": 0.8,
  "weather": [],
  "spawnList": []
}

spawnCountLimit уважается

Повторный спавн бандитской группы блокируется, пока живы боты точки (spawnCountLimit). spawnMin/spawnMax для ботов игнорируются - группа спавнится целиком, кол-во берётся из DynamicAIB.json.

triggerGates 2.3

triggerGates - имена гейтов - вето внешних bridge-модов на разворот группы в пул.

Проверка выполняется после остальных условий группы (isDisabled/spawnOnce/spawnTime/chance/weather) и на общем пути combined/exclusive/волн. AND-семантика; имена регистрозависимы; незарегистрированный гейт - fail-open + WARN (once). Это собственный список гейтов группы: точечный triggerGates на группы не распространяется. Заблокированная группа просто пропускается в этом цикле (DEBUG-лог) - как при провале любого другого условия.

Значение по умолчанию: null/пусто - группа не гейтится. См. Интеграция → Гейты.

Пример:

"triggerGates": ["mpg_ranks"]

Полный пример

Groups/Animals.json

json
[
  {
    "groupName": "dayAnimals",
    "isDisabled": false,
    "spawnTime": "6-18",
    "chance": 1.0,
    "weather": [
      "clear",
      "cloudy"
    ],
    "spawnList": [
      "Animal_UrsusArctos",
      "Animal_CanisLupus_Grey|0.5"
    ]
  },
  {
    "groupName": "nightPredators",
    "isDisabled": false,
    "spawnTime": "18-6",
    "chance": 0.8,
    "weather": [
      "fog",
      "storm"
    ],
    "spawnList": [
      "Animal_CanisLupus_Grey",
      "Animal_UrsusArctos|0.3"
    ]
  }
]

Использование в точке (Points/MyPoint.json)

json
{
  "pointId": 100,
  "shape": {
    "position": "4246.0 0.0 5586.7",
    "radius": "40.0"
  },
  "spawn": {
    "positions": [
      "4246.0 0.0 5586.7"
    ],
    "min": 2,
    "max": 5,
    "list": [
      "Animal_UrsusArctos",
      "@dayAnimals",
      "@nightPredators"
    ]
  }
}

Что делает эта точка:

  • Днём (@dayAnimalsspawnTime 6-18) + в ясную/облачную погоду → в пуле медведи и волки (50%).
  • Ночью (@nightPredatorsspawnTime 18-6) + в туман/грозу → в пуле ночные хищники, и сама группа появляется лишь в 80% циклов спавна (chance 0.8).
  • Медведь Animal_UrsusArctos из прямого spawn.list точки - в пуле всегда, независимо от групп.
  • Из итогового пула точка выбирает случайный элемент, как обычно.

Крайние случаи

  • Несуществующая группа (@ghost, а такой группы нет ни в одном файле Groups/) → ERROR в лог при старте и в рантайме; элемент выбрасывается из пула; точка продолжает работу.
  • Отключённая группа (isDisabled: 1) → молча пропускается (как выключенный триггер).
  • Все группы отфильтрованы условиями (не то время/погода/chance), а прямых класснеймов в spawnList нет → эффективный пул пуст → спавна нет (без ошибок, легальное "сейчас нечего спавнить").
  • Цикл групп (@a@b@a) → WARN в лог, второе вхождение пропускается, бесконечной рекурсии нет.
  • spawnOnce-группа в пуле, но элемент не выпал в выборке → объект не создан → флаг не поставлен → попытка не потрачена, при следующем цикле группа снова в пуле.
  • Все объекты spawnOnce-группы умерли → флаг не снимается до рестарта/config-reload. Группа остаётся "израсходованной". См. spawnOnce.
  • Несколько групп с notificationTextSpawn в одном цикле → по одной нотификации на каждую группу (дополнительно к точечной). Порядок не гарантирован (флейвор-нотификации).
  • Вложенные группы и нотификация/spawnOnce → относятся к группе, указанной в точке (@boss), а не к вложенной (@minions внутри boss). Origin = ближайшая группа по ссылке точки.