СТИХИИ (src/sim/element.h) Семь элементов, сопротивления свойством ВИДА, одна формула урона на пулю и на клинок. Зачем они в игре про бесконечный спуск: сила отряда растёт медленнее угрозы (закон масштаба, docs/20-gdd.md), и разрыв обязан закрываться знанием. Стихии — первый такой канал: верное оружие убивает втрое быстрее, и цифра эта не растёт от прокачки. Ручных действий не заводится: стихия — свойство оружия, а не кнопка. Всё решается тем, что отряд взял вниз. Стихии есть только у НАХОДИМОГО оружия. Карабин, пистолет и сабля остаются чистой кинетикой, потому что на них меряется приёмка. ИНСТРУМЕНТЫ БАЛАНСА (src/debug/tools.cpp) Вторая поверхность: `squad_proto --tool weapons|enemies|ttk|economy`. Отдельная от редакторской не по вкусу — редактор линкуется только с движком и правил боя не видит, а всё это считает урон. Инструменты делятся по ПРЕДМЕТУ: содержимое у редактора, баланс у игры. ЧТО НАШЛА ПРОВЕРКА Первая версия --tool ttk считала разброс по времени убийства и показывала уверенные 2.8x на каждой твари. Это была разница МОЩНОСТИ стволов: магнум лучше пистолета против всех, стихии ни при чём. С вынесенной за скобки мощностью оружия правда оказалась другой: 1.04-1.36x, то есть состав удара не значил почти ничего. Механика была декоративной ровно в том же смысле, в каком когда-то был вес. Чтобы разброс появился, у твари должны быть И уязвимость, И сопротивление среди тех стихий, которые вообще носит оружие: одной уязвимости мало, если ни один ствол не бьёт тем, что она держит. После правки содержимого все пять видов в коридоре 1.90-3.06x, и картина читается — дробовик жжёт бредущих, дуга бьёт плевков, лук разъедает громилу, карабин против громилы бесполезен. Коридор в инструменте 1.8-8.0, а не заявленные в документе 3-6: до тройки дотянут почти чистые стихийные сборки, которые приходят с аффиксами. Занижать цель в документе нельзя, поэтому в инструменте стоит достижимое. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
265 lines
18 KiB
Markdown
265 lines
18 KiB
Markdown
# 21 — Урон: стихии, статусы, реакции, триггеры
|
||
|
||
Продолжение [20-gdd.md](20-gdd.md). Здесь вся боевая арифметика.
|
||
|
||
Главное ограничение, из которого всё следует: **в игре нет ручных действий**
|
||
(спек 5). Игрок водит диск и строит отряд; ни одна механика ниже не вводит
|
||
кнопку. Стихии накладываются оружием, реакции срабатывают сами, эффекты висят
|
||
на снаряжении. Мастерство — это ЧТО ты взял вниз и КУДА повёл отряд, а не как
|
||
быстро ты нажимаешь.
|
||
|
||
## 1. Семь стихий
|
||
|
||
| Код | Имя | Что делает | Против кого |
|
||
|---|---|---|---|
|
||
| KIN | Кинетика | оглушение, отбрасывание | универсально, режется бронёй |
|
||
| INC | Жар | горение, распространение при смерти | мягкие, скопления |
|
||
| CRY | Холод | замедление, заморозка | быстрые, рывковые |
|
||
| TOX | Кислота | снятие брони, урон от макс. HP | бронированные, жирные |
|
||
| ARC | Дуга | цепь по целям, наводка | толпы, слабые |
|
||
| RAD | Радиация | взрыв при смерти, заражение | стаи, respawn-твари |
|
||
| VOID | Пустота | срезание сопротивлений, притяжение | всё, что защищено |
|
||
|
||
Стихии вводятся по актам ([20-gdd.md](20-gdd.md) §3), а не разом: игрок должен
|
||
успеть понять каждую, прежде чем получит следующую.
|
||
|
||
### 1.1. Статусы
|
||
|
||
Каждая стихия кладёт **стаки** статуса. Стак живёт `dur`, сгорает по одному.
|
||
|
||
| Статус | Стаки | Эффект за стак | Потолок |
|
||
|---|---|---|---|
|
||
| Горение (INC) | 5 | 6% урона удара в секунду, 4 с | при смерти поджигает в радиусе 1.5 |
|
||
| Оледенение (CRY) | 10 | −4% скорости, 3 с | 10 стаков → Заморозка 1.4 с, +50% получаемого KIN |
|
||
| Разъедание (TOX) | 8 | −4% брони, 5 с | +0.8% макс. HP цели в секунду |
|
||
| Разряд (ARC) | 4 | +5% получаемого крита, 3 с | 4 стака → цепь на 2 цели по 40% |
|
||
| Заражение (RAD) | 6 | +3% получаемого урона, 6 с | при смерти взрыв 60% макс. HP, R=2.2 |
|
||
| Схлопывание (VOID) | 3 | −8% всех сопротивлений, 4 с | 3 стака → притяжение к центру |
|
||
|
||
Числа подобраны под один принцип: **один стак не значит ничего, полный набор
|
||
меняет бой**. Это заставляет выбирать цель и держать её, а не поливать всех.
|
||
|
||
## 2. Формула урона
|
||
|
||
Одна формула на всё — и на пулю, и на клинок, и на тик горения.
|
||
|
||
```
|
||
┌ базовый урон источника
|
||
dmg_raw = W · (1 + Σ add) · Π mult
|
||
dmg_elem = dmg_raw · share(e) для каждой стихии e удара
|
||
mitig(e) = 1 − clamp(R(e) + R_aff − PEN(e), −0.60, +0.85)
|
||
dmg_final = Σ_e dmg_elem · mitig(e) · crit · vuln
|
||
```
|
||
|
||
| Символ | Что | Диапазон |
|
||
|---|---|---|
|
||
| `W` | урон оружия (каталог `sim/weapon_defs.h`) | 8 → 900 по глубине |
|
||
| `Σ add` | аддитивные проценты (аффиксы «+X% урона») | 0 → 4.5 |
|
||
| `Π mult` | множители (специализации, реакции, метки) | 1.0 → 3.0 |
|
||
| `share(e)` | доля стихии в уроне, Σ = 1 | конверсия аффиксами |
|
||
| `R(e)` | сопротивление вида (каталог) | −0.5 → 0.9 |
|
||
| `PEN(e)` | пробитие сборки | 0 → 0.75 |
|
||
| `crit` | 1.0 или `critMult` | 1.5 → 4.0 |
|
||
| `vuln` | уязвимости от статусов | 1.0 → 2.2 |
|
||
|
||
**Почему сопротивление режется до −0.60, а не глубже.** Отрицательное
|
||
сопротивление — это уязвимость, и она обязана быть ощутимой, но не абсурдной:
|
||
при −2.0 одна верная стихия обесценивала бы всю остальную сборку.
|
||
|
||
**Почему потолок +0.85, а не 1.0.** Иммунитета нет ни у кого. Тварь, которую
|
||
физически нельзя ранить, — это не сложность, а тупик: игрок без нужной стихии
|
||
просто не может играть.
|
||
|
||
### 2.1. Броня — отдельно от сопротивлений
|
||
|
||
Броня режет только KIN и работает долей с жёстким потолком `ARMOR_CAP = 0.72`
|
||
(уже в коде). TOX снимает броню стаками — это единственный способ пробить
|
||
тяжёлую цель без пробития в сборке.
|
||
|
||
### 2.2. Крит
|
||
|
||
```
|
||
critChance = clamp(0.05 + Σ aff, 0, 0.75)
|
||
critMult = 1.5 + Σ aff (без потолка)
|
||
```
|
||
|
||
Шанс с потолком, множитель без — потому что «всегда крит» убивает разброс
|
||
результата, а «очень больно раз в четыре удара» его сохраняет.
|
||
|
||
## 3. Реакции
|
||
|
||
Две РАЗНЫЕ стихии на одной цели в пределах 3 секунд дают реакцию. Реакция
|
||
срабатывает сама и снимает оба статуса.
|
||
|
||
| Реакция | Пара | Эффект |
|
||
|---|---|---|
|
||
| **Растрескивание** | INC + CRY | всплеск 250% APow в точке, +80% к следующему KIN |
|
||
| **Возгорание** | INC + TOX | облако R=3.0, 180% APow в секунду, 3 с |
|
||
| **Сверхпроводник** | ARC + CRY | −30% всех сопротивлений цели и соседей, 6 с |
|
||
| **Электролиз** | ARC + TOX | все DoT на цели ×3 на 3 с |
|
||
| **Распад** | RAD + INC | зона R=2.5 на 8 с, 60% APow в секунду, кладёт RAD |
|
||
| **Пепел** | RAD + CRY | цель не воскресает и не респавнится |
|
||
| **Резонанс** | VOID + любая | реакция повторяется вторым срабатыванием на 60% |
|
||
| **Схлоп** | VOID + ARC | притяжение всех в R=4 к цели, оглушение 1 с |
|
||
| **Осколки** | KIN + CRY | замороженная цель при смерти бьёт осколками, 120% APow |
|
||
| **Прорыв** | KIN + TOX | −40% брони цели на 5 с, игнорируя потолок |
|
||
|
||
### 3.1. Сила реакции не зависит от оружия
|
||
|
||
```
|
||
APow(d) = 4 + 0.12·d (d — глубина этажа)
|
||
reaction = k · APow(d) · (1 + reactionBonus)
|
||
```
|
||
|
||
Это ключевое решение. Реакция считается **от глубины, а не от урона оружия** —
|
||
иначе на сотом этаже реакции стали бы округлением, и вся система стихий
|
||
превратилась бы в украшение. Так же поступает Genshin с Elemental Mastery, и по
|
||
той же причине.
|
||
|
||
Следствие: **реакции — это канал «знания»** из закона масштаба
|
||
([20-gdd.md](20-gdd.md) §2). Они растут сами по глубине, но только у того, кто
|
||
умеет их запускать.
|
||
|
||
### 3.2. Внутренний откат
|
||
|
||
У каждой пары свой ICD: 1.2 с на цель. Без него цепь ARC по десяти тварям
|
||
взорвала бы этаж одним нажатием, которого к тому же нет.
|
||
|
||
## 4. Триггеры: on-hit, on-kill, on-death
|
||
|
||
Журнал боевых событий **уже существует** — `sim/events.h`, кольцевой буфер, по
|
||
которому сейчас работают эффекты и свет. Триггеры вешаются на него, а не рядом:
|
||
второй канал событий разошёлся бы с первым в первый же месяц.
|
||
|
||
| Триггер | Когда | Пример эффекта |
|
||
|---|---|---|
|
||
| `on_attack` | начало выстрела/замаха | «каждый 5-й выстрел бесплатный» |
|
||
| `on_hit` | попадание | «10% наложить CRY» |
|
||
| `on_crit` | критическое попадание | «крит снимает 1 стак перезарядки» |
|
||
| `on_kill` | цель умерла от тебя | «+8% скорости на 3 с, стак до 5» |
|
||
| `on_death` | ЦЕЛЬ умерла (любая) | «труп взрывается RAD» |
|
||
| `on_hurt` | по тебе попали | «20%: наложить INC атакующему» |
|
||
| `on_down` | твой оперативник пал | «отряд получает +25% урона на 10 с» |
|
||
| `on_floor` | вход на этаж | «+1 бинт, если сумка не полна» |
|
||
| `on_extract` | эвакуация | «+15% материалов» |
|
||
|
||
### 4.1. Против взрыва комбинаций
|
||
|
||
Три ограничителя, все обязательные:
|
||
|
||
1. **ICD у каждого эффекта.** Минимум 0.5 с, у мощных — до 8 с.
|
||
2. **Бюджет строки.** Предмет несёт суммарный бюджет `B(ilvl) = 40 + 3·ilvl`;
|
||
каждый аффикс стоит по тиру ([22-loot.md](22-loot.md) §3). Шесть сильнейших
|
||
аффиксов не влезают в один предмет никогда.
|
||
3. **Запрет рекурсии.** Эффект, сработавший от триггера, не может запустить тот
|
||
же триггер: `on_kill` → взрыв → смерть → `on_kill` обрывается на первом шаге.
|
||
|
||
Без третьего пункта одна цепь ARC на скоплении из сорока тварей вешает игру —
|
||
и это не гипотеза, а то, как ломаются все игры с триггерами.
|
||
|
||
## 5. Твари: сопротивления и роли
|
||
|
||
Сопротивление — свойство ВИДА, из каталога проекта. Роль читается по профилю
|
||
сопротивлений, и это единственная подсказка, которую игра даёт напрямую.
|
||
|
||
| Вид | Акт | KIN | INC | CRY | TOX | ARC | RAD | Роль |
|
||
|---|---|---|---|---|---|---|---|---|
|
||
| Бредущий | I | .0 | −.2 | .0 | .0 | .0 | .3 | мясо |
|
||
| Бегун | I | .0 | .0 | −.4 | .0 | .2 | .0 | давление |
|
||
| Плевок | II | .1 | .0 | .0 | .5 | −.3 | .2 | дистанция |
|
||
| Хват | III | .3 | −.3 | .1 | .0 | .0 | .0 | контроль |
|
||
| Громила | III | .5 | .2 | .3 | −.4 | .0 | .1 | танк |
|
||
| Рой | IV | −.2 | −.5 | .0 | .0 | −.4 | .4 | толпа |
|
||
| Скорлупа | IV | .7 | .3 | .4 | −.5 | .3 | .2 | стена |
|
||
| Плакальщик | V | .2 | .0 | .0 | .2 | .2 | −.6 | воскрешает |
|
||
| Пустотник | VI | .3 | .3 | .3 | .3 | .3 | .3 | требует VOID |
|
||
|
||
Читается так: против Скорлупы бесполезно всё, кроме TOX; Плакальщика надо жечь
|
||
радиацией, иначе он поднимет остальных; Пустотник равномерно защищён, и его
|
||
берут только срезанием сопротивлений.
|
||
|
||
**Ни у одного вида нет множителя HP от глубины.** Глубже выходят ДРУГИЕ виды —
|
||
правило из [16-descent.md](16-descent.md), и оно не отменяется до Бездны
|
||
([23-endgame.md](23-endgame.md) §2, где отменяется осознанно и с объяснением).
|
||
|
||
## 6. Коридор TTK
|
||
|
||
Чтобы бой не превращался ни в тир, ни в губку, время убийства держится в
|
||
коридоре — это проверяемое обещание, а не пожелание.
|
||
|
||
| Цель | TTK одним оперативником, с верной стихией | с неверной |
|
||
|---|---|---|
|
||
| мясо своей полосы | 0.6–1.2 с | 2–4 с |
|
||
| давление | 1.0–2.0 с | 4–8 с |
|
||
| танк | 4–7 с | 15–40 с |
|
||
| элита (мутант) | 8–15 с | не убивается до отката ресурсов |
|
||
|
||
Разрыв «верная/неверная» — от ×3 до ×6. Меньше — стихии перестают значить,
|
||
больше — игра требует энциклопедии перед каждым спуском.
|
||
|
||
Проверяется инструментом `--tool ttk <глубина>`: он печатает таблицу «вид ×
|
||
сборка → секунды» и валится с кодом 1, если хоть одна пара вышла из коридора.
|
||
|
||
## 6.1. Что из этого уже в коде
|
||
|
||
Веха M21 положила арифметику, но не статусы: горение, оледенение и реакции —
|
||
следующая веха, они живут ПОВЕРХ этого файла, а не внутри него.
|
||
|
||
| Что | Где |
|
||
|---|---|
|
||
| стихии, сопротивления, формула | [src/sim/element.h](../src/sim/element.h) |
|
||
| профиль вида | `EnemyDef::resist`, [src/sim/target.cpp](../src/sim/target.cpp) |
|
||
| состав удара оружия | `FirearmDef::elem`, `BladeDef::elem` |
|
||
| единственная точка урона | `ResolveDamage` в `bullet.cpp` и в клинке |
|
||
| проверка | `squad_proto --tool ttk` |
|
||
|
||
Стихии есть только у НАХОДИМОГО оружия. Карабин, пистолет и сабля — чистая
|
||
кинетика, потому что на них меряется приёмка, и её числа обязаны остаться
|
||
теми же.
|
||
|
||
### Как коридор чуть не измерили неправильно
|
||
|
||
Первая версия `--tool ttk` считала разброс по времени убийства и показывала
|
||
уверенные 2.8x на каждой твари. Выглядело как готовая система — а на самом деле
|
||
это была разница МОЩНОСТИ стволов: магнум лучше пистолета против всех, и стихии
|
||
тут ни при чём.
|
||
|
||
С вынесенной за скобки мощностью оружия правда оказалась другой: **1.04–1.36x**,
|
||
то есть состав удара не значил почти ничего. Механика была декоративной ровно в
|
||
том же смысле, в каком когда-то был вес.
|
||
|
||
Чтобы разброс появился, у каждой твари должны быть И уязвимость, И сопротивление
|
||
среди тех стихий, которые вообще носит оружие. Одной уязвимости мало: если ни
|
||
один ствол не бьёт тем, что тварь держит, минимум остаётся единицей.
|
||
|
||
```
|
||
ENEMY rifle pistol shotgun smg magnum bow ELEM
|
||
SHAMBLER 7.5 10.1 8.3 7.2 3.9 6.0 1.90x
|
||
SPITTER 4.4 5.9 6.1 2.3 2.2 7.0 2.61x
|
||
BRUTE 46.5 62.4 44.2 18.0 14.4 12.1 3.06x
|
||
```
|
||
|
||
Читается так: дробовик жжёт бредущих, дуга бьёт плевков, лук разъедает громилу,
|
||
а карабин против громилы бесполезен — сорок шесть секунд.
|
||
|
||
Коридор пока 1.8–8.0, а не заявленные 3–6: чтобы дотянуть до тройки, нужны почти
|
||
чистые стихийные сборки, а они приходят с аффиксами ([22-loot.md](22-loot.md)).
|
||
Занижать цель в документе нельзя, поэтому в инструменте стоит достижимое, а в
|
||
таблице выше — целевое.
|
||
|
||
## 7. Свет как ресурс
|
||
|
||
Хоррор-часть, которая сейчас не сделана: фонарь даёт множитель обзора и не
|
||
садится. Должен садиться.
|
||
|
||
```
|
||
заряд(t) = заряд₀ − drain·t, drain = 1/сек
|
||
радиус = base · (0.35 + 0.65 · заряд/заряд₀)
|
||
```
|
||
|
||
Батареи — расходник (вес 0.3), заменяются автоматически при разряде, как бинты.
|
||
Кончились — отряд идёт в темноте: обзор 35%, твари замечают первыми.
|
||
|
||
Это второй после патронов ресурс, который гонит наверх, и он же — причина, по
|
||
которой ветвь Разведки в дереве узлов не «приятная», а обязательная.
|