-- Nerf weapon primaries (−15% base) and defense/mixed primaries (−30% base); recompute denormalized primary_stat (§6.4, same M(rarity) and tol as 000012).
-- Runtime: global enemy encounter stat multiplier + unequipped-hero multiplier (see tuning / BuildEnemyInstanceForLevel).
@ -67,6 +67,8 @@ go run ./cmd/balanceall -gear-overlay ./cmd/balanceall/testdata/gear_overlay_bal
Команда завершает работу после вывода SQL. Перенесите результат в миграцию (см. пример `backend/migrations/000012_gear_balance_overlay.sql`).
После миграций, меняющих `gear` или множители встреч в `runtime_config` (`enemyEncounterStatMultiplier`, `enemyStatMultiplierVsUnequippedHero`), имеет смысл прогнать `-gear-check` и при необходимости сетку с`-adjust-enemies=false`, чтобы увидеть метрики; `BuildEnemyInstanceForLevel` уже учитывает эти множители в симуляциях.
### Калибровка без полного перебора
Выберите типичных монстров (`-enemy-type`, `-gear-check-level-*`) и итерируйте **JSON оверлей**, пока `-gear-check` не проходит; затем зафиксируйте изменения миграцией. Глобальные множители редкости остаются в `runtime_config` / `ScalePrimary`.
@ -230,6 +230,13 @@ AutoHero — это idle/incremental RPG с изометрическим вид
Герой `L45` без временных баффов и без сильной экипировки остаётся относительно плоским по числам; основной рост mid/late-game должен ощущаться через экипировку, баффы и редкие уровни.
### 3.6 Множители экземпляра монстра при встрече
После расчёта `MaxHP` / `Attack` / `Defense` экземпляра из шаблона и `levelDelta` (см. `BuildEnemyInstanceForLevel`, `runtime_config`):
- **`enemyEncounterStatMultiplier`** (по умолчанию `1.2`) — умножает `MaxHP`, `HP`, `Attack`, `Defense`у всех боевых экземпляров монстров. Награды XP/Gold, скорость атаки врага и прочие поля шаблона не меняются.
- **`enemyStatMultiplierVsUnequippedHero`** (по умолчанию `0.75`) — если у героя нет ни одного надетого предмета в карте экипировки, те же боевые поля врага дополнительно умножаются на этот коэффициент (встречи легче для полностью неэкипированного героя).
`basePrimary` — целое из каталога для семейства предмета на «эталоне» `ilvl = 1`, `Common`.
В Postgres денормализованное поле `gear.primary_stat` на строке каталога пересчитывается миграциями по той же логике `L(ilvl) × M(rarity)` (и детерминированный `tol` по `id` строки, см. `000012_gear_balance_overlay.sql`). Миграция **`000027_gear_encounter_balance.sql`** ослабляет каталог: база оружия (`slot = main_hand`) умножается на **0.85**, база предметов с`stat_type` в **`defense`** или **`mixed`** — на **0.70**, затем `primary_stat` пересчитывается заново.
**Свойство баланса:** при данной кривой `ilvl`**уровень предмета даёт более сильный вклад**, чем раньше, а редкость заметно усиливает предмет **внутри одного уровня**. Пример (без привязки к слоту, `basePrimary = 10`):