Skip to content

Repository files navigation

Общее

Прототип пошаговой боевой системы с юнитами на клеточной карте.

Правила симуляции

  • Карта представляет собой прямоугольную сетку размером W×H клеток.
  • Каждый юнит имеет уникальный целочисленный идентификатор.
  • Один ход соответствует одному действию одного юнита.
  • Юниты действуют в порядке их создания.
  • Некоторые юниты могут перемещаться:
    • за один ход юнит может перейти в любую из 8 соседних клеток, если она свободна;
    • если цель недостижима за один ход, юнит продолжает движение к ней в последующих ходах.
  • Некоторые юниты могут атаковать, уменьшая количество HP у цели:
    • при достижении 0 HP юнит умирает;
    • после смерти юнит больше не действует и освобождает занимаемую клетку.
  • Симуляция завершается, когда не остаётся юнитов, способных совершать действия.

Детали

При запуске приложение получает путь к файлу со сценарием симуляции. Сценарий содержит команды для создания карты, юнитов и их перемещения. Формат входных и выходных данных остаётся неизменным. Событие атаки содержит суммарный урон, который нанес один юнит другому.

Мечник

  • Ближняя атака: атакует случайного юнита в соседней клетке, нанося урон, равный Strength.
  • Способность: с вероятностью Chance / 1000 вместо обычной атаки применяет «Рваные раны», нанося Rending урона.
  • Поведение: если цель для атаки отсутствует, перемещается.

Охотник

  • Дальняя атака: стреляет в случайного юнита на расстоянии от 2 до Range клеток, нанося урон, равный Agility. Атака возможна только при отсутствии других юнитов в соседних клетках.
  • Ближняя атака: если дальняя атака невозможна, атакует случайного юнита в соседней клетке, нанося урон, равный Strength.
  • Способность: с вероятностью Chance / 1000 вместо обычной дальней атаки применяет отравленные стрелы, нанося в сумме Poison урона за пять ходов. Урон от яда удваивается в тот ход, когда отравленный юнит получает эффект «Рваные раны».
  • Урон от яда засчитывается как урон охотника, наложившего эффект.
  • Поведение: если цель для атаки отсутствует, перемещается.

Планы

Маг

  • Дальняя атака: стреляет в случайного юнита на расстоянии от 2 до Range клеток, нанося урон, равный Spirit.
  • Способность: с вероятностью Chance / 1000 призывает огненную стену из 3 клеток на 5 ходов. Стена не блокирует движение и наносит Firewall урона за ход каждому юниту, находящемуся на ней.
  • Поведение: если цель для атаки отсутствует, перемещается.

Башня

  • Дальняя атака: стреляет в случайного юнита на расстоянии от 2 до Range клеток, нанося урон, равный Power.
  • Поведение: не перемещается, неуязвима, занимает 2×2 клетки.

Ворон

  • Летающий юнит:
    • Не занимает клетку на карте.
    • Может перемещаться на 2 клетки за ход.
    • Не может быть атакован в ближнем бою.
    • Минимальная и максимальная дистанция дальней атаки на ворона снижена на 1.
  • Ближняя атака: атакует случайного юнита в соседней клетке, нанося Strength урона.
  • Поведение: если цель для атаки отсутствует, перемещается.

Детали реализации

В данной реализации мы отойдём от альтернативного предложения про Очередь Событий. Причина в том, что очередь событий сильно усложняет ответ на вопрос "с какой картиной мира работает каждое последующее событие?". Мы хотим объединить простоту (картина мира всегда одна) и убрать реактивную систему. Решение и нюансы:

  • Основная идея в том, чтобы упаковать Намерение действия в данные и прогнать их через этапы: препроцессинг, исполнение, постпроцессинг.
  • При этом каждый юнит будет иметь свою цепочку действий, которая последовательно будет создавать Намерение, прогонять через три этапа и, в случае выполнения действия, отменять все остальные.
  • Намерение, проходя через подсистемы, будет модифицироваться или генерировать новые намерения.
  • Фаза исполнения предобработанного Намерения меняет мир.
  • Постпроцессинг при необходимости создаёт новые намерения.
  • Текущий ход Юнита заканчивается, когда стек Намерений пуст, и очередь переходит к новому Юниту (на следующем тике), который работает уже в "новой реальности". Это тот момент, который помогает нам обойти ограничение Очереди Событий.
  • Архитектура данных базируется на упрощенном ECS-подходе, где свойства (HP, Позиция, Атака) — это компоненты, а логика вынесена в системы и планоровщики интентов.
  • System Tick Order: введен слой глобальных системных событий. Это позволяет реализовать «законы мира» (Яд, Смерть, Смерч), которые выполняются в строго определенном порядке (Pre-tick / Post-tick), независимо от «воли» конкретных юнитов.
  • Также мы хоть и оставляем Позицию как Кор фичу (контракт на событие ЮнитСпаунд требует этого), мы выносим логику, связанную с Маршем в Фичи. В идеале я бы перешёл от Юнита к Сущности и убрал Позицию как фундаментальное свойство.
  • Полное разделение Core/Features, нет связности (Позиция как компромиссное решение).
  • Решение более подходящее для TBS, чем Очередь Событий или Реактивная Системы.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages