Перейти к основному содержимому

Система диких встреч

Система встреч определяет, когда и какие дикие монстры появляются, пока игрок исследует мир. MCE поддерживает несколько типов встреч, взвешенные таблицы, диапазоны уровней, встречи в зависимости от времени суток и погоды, а также репелленты.

Высокая трава на Маршруте 1

Тайлы, на которых стоит игрок, — это весь триггер. EncounterTile отмечает тайл и его тип, WildEncountersSet говорит, что там обитает и на каких уровнях, SceneInfo карты связывает их, а каждый шаг на тайл встречи проверяется по шансу.

Как работают встречи​

  1. Игрок завершает шаг на тайл, несущий EncounterTile (или, в сцене-подземелье, на любой тайл).
  2. Шаг проверяется по шансу встречи для EncounterType этого тайла.
  3. Если проверка успешна, SceneInfo карты предоставляет WildEncountersSet для этого типа. Строится список возможных встреч для текущего времени суток и погоды, и одна запись выбирается по весу.
  4. Уровень выбирается между MinLevel и MaxLevel записи.
  5. Репеллент или лидер команды всё ещё могут отменить встречу (ниже).
  6. Создаётся объект BattleParameters с видом, уровнем и формой выбранного монстра, и BattleLauncher переходит в сцену сражения.

Типы встреч​

Перечисление EncounterType называет виды встреч:

ТипТипичное применение
GrassВысокая трава
Water, SurfingТайлы воды; сёрфинг по ним
CaveПолы пещер. Сцена, помеченная как подземелье (IsDungeon в её SceneInfo), использует Cave на каждом тайле, и рисовать тайлы не нужно
FishingOldRod, FishingGoodRod, FishingSuperRodРыбалка каждой удочкой
DivingПод водой
RockSmash, HeadButtРазбивание камня; удар по дереву
BugContestКонкурс ловли жуков
OtherВсё, что определит ваша игра

Настройка зон встреч​

Шаг 1: Тайлы встреч​

Тайл встречи — это тайл, префаб которого содержит компонент EncounterTile. У компонента одна настройка, Encounter Type. Сделайте свой, создав префаб с этим компонентом, выбрав тип и используя префаб как GameObject тайла-ассета; затем нарисуйте этот тайл на слое тайлмапа, где должны появляться монстры. Движок включает готовые, например Assets/OpenMon/Game/Prefabs/World/Water/Water/WaterEncounterTile.prefab.

Шаг 2: WildEncountersSet​

Создайте его через Assets > Create > MCE > Battle > Encounters > WildEncountersSet (или New Wild Encounter Set на вкладке Database в Hub). У набора три списка:

СписокЗначение
Base EncountersМонстры, которые появляются всегда
Encounters Per MomentДополнительные монстры для Night, Dawn, Day или Dusk
Encounters Per WeatherДополнительные монстры при определённой погоде вне сражения (Sunny, Rain, Fog, Sandstorm, Snowstorm)

Возможные встречи в данный момент — это базовый список плюс записи текущего времени суток плюс записи текущей погоды.

Каждая запись — это WildEncounter:

ПолеОписание
MonsterСсылка на MonsterEntry
Form CalculatorАссет, решающий, какая форма появится (см. ниже)
Min Level / Max LevelДиапазон уровней, от 1 до 100 (максимум никогда не бывает ниже минимума)
WeightОтносительный вес этой записи (больше = чаще)

Шаг 3: SceneInfo карты​

Ассет SceneInfo карты связывает типы встреч с наборами. В его группе Encounters добавьте по одной записи на тип: Grass → ваш набор для травы, Surfing → ваш набор для воды и так далее. У типа без записи нет диких монстров. Тот же ассет может содержать для каждого типа:

  • сценарий сражения (боевой фон/местность для этого вида встречи; если не задан, используются собственные данные тайла),
  • собственный шанс встречи карты (ниже),
  • можно ли здесь ловить рыбу и является ли сцена подземельем.

Расчёт вероятности​

Веса относительные, а не проценты. Система суммирует все веса, и шанс каждой записи — это её вес, делённый на сумму:

Chance = Entry Weight / Sum of All Weights
МонстрВесФактический шанс
Leafpup4040/100 = 40%
Windling3030/100 = 30%
Silkworm2020/100 = 20%
Sparkbit1010/100 = 10%

Шанс встречи на шаг​

Вызовет ли шаг встречу вообще — это вторая, отдельная проверка:

  • Глобальный шанс — это таблица TileEncounterChance ассета MCESettings: одно значение (от 0 до 1) на каждый тип встречи. Тип, отсутствующий в таблице, считается равным 0 и один раз пишет предупреждение.
  • Карта может переопределить его для типа с помощью собственного шанса в её SceneInfo (OwnEncounterChances). Такой тип также использует множители карты для бега (по умолчанию 1) и езды на велосипеде (по умолчанию 0,8). Без собственного шанса глобальное правило снижает проверку на велосипеде на те же 0,8.
  • Для типов, перечисленных в EncountersWithModifiableChances (MCESettings), способность и удерживаемый предмет лидера команды умножают шанс (например, предмет, уменьшающий число диких встреч).
  • Предмет-флейта встреч меняет шанс до следующей смены карты.
  • Рыбалка использует собственный шанс карты для применяемой удочки; без него рыба клюёт всегда.

Шанс дикого шайни — WildShinyChance в MCESettings (по умолчанию 1/512).

Встречи по времени суток и погоде​

Время суток следует за TimeManager.DayProgress (от 0 до 1 за игровые сутки, длина которых — DayLengthInSeconds в MCESettings):

Время сутокЧасы
Dawn05:00 - 06:59
Day07:00 - 16:59
Dusk17:00 - 18:59
Night19:00 - 04:59

Монстров, которые появляются только в определённое время (или при определённой погоде), помещайте в список Encounters Per Moment (или Per Weather) того же набора; отдельные ассеты не нужны.

Встречи с формами​

WildEncounter выбирает форму через свой Form Calculator — ассет EncounterFormCalculator с двумя методами: GetEncounterForm(sceneInfo, encounterType) возвращает форму, которую нужно создать, а GetAllPossibleForms() перечисляет все формы, которые он может выдать (этим пользуется декс).

MCE поставляется с SingleFormEncounter (Create > MCE > Battle > Encounters > Calculators > SingleFormEncounter), который всегда возвращает одну фиксированную форму. Для форм, зависящих от региона или календаря, создайте подкласс EncounterFormCalculator:

[CreateAssetMenu(menuName = "MyGame/Encounters/Form By Region")]
public class FormByRegion : EncounterFormCalculator
{
[SerializeField] private Region NorthRegion;
[SerializeField] private Form NorthForm;
[SerializeField] private Form SouthForm;

public override Form GetEncounterForm(SceneInfo sceneInfo, EncounterType encounterType) =>
sceneInfo.Asset.Region == NorthRegion ? NorthForm : SouthForm;

public override List<Form> GetAllPossibleForms() => new() { NorthForm, SouthForm };
}

Особые схемы встреч​

Рыбалка​

Для встреч при рыбалке нужны CanFishHere в SceneInfo карты и WildEncountersSet для каждого типа удочки (FishingOldRod, FishingGoodRod, FishingSuperRod) в её группе Encounters. Какая удочка используется игроком, определяет, какой набор отвечает.

Легендарные / разовые встречи​

Для особых встреч, которые должны произойти только один раз:

  1. Используйте событие CommandGraph с узлом SingleWildFight вместо случайных встреч.
  2. Защитите его узлом IfBool по игровой переменной (например, LegendaryDefeated).
  3. После сражения установите переменную узлом SetBoolVariable, чтобы предотвратить повторные встречи.
  4. Такой подход даёт полный контроль над контекстом встречи (кат-сцены, диалоги, местность).

Двойные дикие сражения​

Узел DoubleWildFight запускает парное сражение с двумя дикими монстрами из CommandGraph.

Репелленты и предотвращение встреч​

Игроки могут использовать предметы, чтобы избегать встреч. Репеллент — это предмет Repel с числом шагов RepelAmount, используемый через эффект UseRepel:

ПредметЭффект
Репеллент (любой предмет Repel)В течение RepelAmount шагов отменяет встречи, уровень которых ниже уровня лидера команды

Репелленты реализованы как счётчик шагов у игрока (repelCounter, уменьшается на каждом шаге). Проверка выполняется после выбора встречи и определения её уровня: если счётчик больше нуля, а уровень ниже уровня лидера, встреча отменяется. Способность лидера команды тоже может отменить встречу (ShouldPreventEncounter). Количество шагов каждого репеллента вы задаёте в его ассете.

Онлайн-игра​

В слое MMORPG встречу решает сервер: клиент запрашивает (StartWildEncounter) с именем сцены и типом встречи, а сервер отвечает видом и уровнем. Если сервер отказывает, встреча отменяется; локально она никогда не разрешается. См. Авторитет сражений.

Рекомендации​

  1. Сбалансируйте шансы встреч. Слишком высокий (>25 %) раздражает. Слишком низкий (<5 %) делает мир пустым. Типично 8–15 %.
  2. Масштабируйте уровни вместе с прогрессией. На Маршруте 1 должны быть монстры 2–5 уровней, а не 50.
  3. Различайте таблицы встреч между картами. Каждый маршрут должен ощущаться по-своему.
  4. Добавляйте редкие встречи. Одна запись с малым весом в таблице даёт игрокам повод для охоты.
  5. Тестируйте встречи по времени суток. Игрок не должен чувствовать себя наказанным за игру в определённое время.
  6. Размещайте репелленты рано. Игроки ценят возможность управлять встречами ещё до середины игры.