Боец присел за мешками с песком. Интерфейс показывает шанс выстрела — а противник в это же время планирует свой ход, и мешки ещё можно развалить. Чему вообще верить в этой цифре?
Я делаю Ferrohex — пошаговую тактическую MMO-RPG на гексах в браузере. После восстания ИИ люди воюют с машинами и перешедшими на их сторону. Бои — в тёмных шахтах и дренажах, между боями — экономика игроков: шахты, лаборатории, заводы, рынок. Дух старых браузерных тактик, осовременённый: одновременное планирование хода и превью с процентами и честной оговоркой об условиях. Проект делает один человек, сейчас пре-альфа, публичной демки ещё нет.
В этом разборе — укрытия и позы: что уже работает в сборке, а что ещё в проекте. Кадры из реальной сборки, визуал временный.
Плоский штраф меня не устроил
Первый вариант был простой: стоит в укрытии — минус к шансу попадания по нему, цифра одна на все случаи. Так делает много игр, и это работает. Пока вы не зададите два вопроса.
Первый: штраф от чего? Боец стоит за мешками по пояс — это одно. Лёг за мешком и выставил ствол — другое. Встал в полный рост за железным листом — третье. Одна цифра на все три ситуации врёт хотя бы в двух.
Второй: что делает выстрел, который «попал в укрытие»? В моём первом варианте такой выстрел просто считался промахом. А если пуля остаётся в мешках, у укрытия появляется жизнь: его можно развалить и открыть проход.
Поэтому я отказался от плоского штрафа и стал считать попадание от позиции, позы и состояния укрытия. Чем заплатил — в конце.
Поза меняет числа, а не только картинку
Позы сейчас три: стоя, в приседе и лёжа. В приседе вас хуже видно, но и двигаться тяжелее: цена шага растёт внутри хода (первый шаг 2 ОД, второй 4, третий 6 — как в старых тактиках, я вынес это в данные). Лёжа — меньше видимая часть тела: многие линии выстрела упираются в землю или в низкое укрытие.
И поза связана с прицелом по зонам. Прежде чем выстрелить, вы выбираете часть тела: голова, торс, руки, ноги. По каждой зоне видны свой шанс попадания и диапазон урона. Попадание в голову чаще уходит в крит — на кадре шанс крита 20%, критический урон ×1,5. Попадание в руки сбивает прицел, в ноги — замедляет. На учебной мишени: вся цель — 57% (8–13 урона), голова — 34% (12–18). Одно движение мыши — и вы выбираете: надёжнее попасть или рискнуть ради крита.
Мешки, которые можно развалить
Укрытие в билде — не флаг «защищён». У мешков 50 HP; попавшие в них пули уменьшают прочность. Разрушили — линия открылась, и боец за мешками внезапно стал виден в полный рост. На кадрах ниже — реальный прогон: план из четырёх выстрелов, мешки ловят все четыре (−14, −15, −17, −17), 50 HP кончаются — «проход открыт».
Отсюда вилка, которой не было с плоским штрафом: тратить выстрелы на мешки или по врагу. Противник видит те же проценты, понимает, что проход вот-вот откроется, — и уходит с линии огня. Укрытие стало расходником.
Что значит эта цифра процента
Процент в превью — это шанс попадания при известных на момент планирования условиях: где стоит цель, какая у неё поза, целы ли мешки, сколько до неё шагов. К моменту выстрела условия могут измениться.
Цель может уйти за угол или сменить позу; ваш же первый выстрел может развалить мешки, за которыми стоял второй план. В превью стоит пометка «если цель останется на месте» — она называет главное условие; поза и укрытие тоже входят в расчёт и тоже могут измениться до выстрела.
Оба бойца планируют одновременно, план исполняется по таймлайну — противник может уйти до вашего выстрела. Я выбрал точный процент с пометкой, а не диапазон «если останется / если уйдёт»: два числа читаются как «система сама не знает», одно число с честным условием — как расчёт, у которого есть входные данные. Понятность здесь победила полноту. Если видите в этом проблему — поспорим в комментариях.
Для любопытных: как считается линия
Поле — гексы. Выстрел идёт по линии гексов от стрелка к цели, и я проверяю каждый гекс на пути: есть ли препятствие. Самая противная часть — когда линия проходит ровно по грани между двумя гексами: формально она касается обоих. Моё правило: проверяются оба, и если хотя бы в одном препятствие достаточной высоты — пуля ловится (у препятствий есть высота: низкое укрытие ловит только низкие линии). Это щедро к обороне и жестоко к стрелку, зато не возникает спора «повезло или не повезло» на ровном месте.
Что это мне стоило
Плоский штраф был одной строкой. Теперь в расчёте позиция, поза, прочность укрытия и условия превью. Это больше полей, пограничные случаи вроде «мешок разрушился пулей предыдущего выстрела того же плана» и постоянная проверка, что превью совпадает с фактом: при одинаковых входных данных и превью, и разрешение выстрела считает одна и та же логика — журнал боя можно проверять построчно.
Что дальше: одновременные ходы и первые крысы
Следующий этап боя уже спроектирован, сроков не обещаю. Что в нём появится:
— Одновременное планирование под таймером 3:00: не успел — исполняется то, что успел спланировать; паузы нет.
— Выстрелы одного тика не отменяют друг друга: убили друг друга — мертвы оба.
— Промах не исчезает — пуля летит дальше по линии и не разбирает своих.
— Первый живой противник — крысы-мутанты: укус из смежного гекса, догон до конца хода; труп освобождает гекс.
— Тумана войны не будет вообще: вся карта видна всем — воевать будете за укрытия, а не за информацию.
Следующий разбор — как разрешается одновременный план: тик за тиком, что раньше — шаг или выстрел, и что происходит, когда двое идут в один гекс.
Ferrohex — пре-альфа, соло-разработчик; часть ассетов сгенерирована нейросетями, отбор и дизайн за человеком.