Баланс игры с нейросетью: что LLM считает сама, а что проверяет код
Нейросеть может помогать с балансом игры: накидать черновик конфига экономики, написать симуляцию и найти перекосы. Считать в голове и выбирать финальные числа ей нельзя: LLM легко выдаёт правдоподобный конфиг, где доход растёт быстрее цен. Проверяет баланс код симуляции, решение по метрикам принимает геймдизайнер.
Баланс игры с нейросетью: что LLM делает в игровой экономике, где ошибается и как проверить конфиг симуляцией на Python. Код, цифры прогона и пример из DnD-бота.

В статье · 7 разделовразвернутьсвернуть
Баланс игры - это настройка чисел, от которых зависит, насколько игре интересно и честно играть: цены, награды, урон, скорость прокачки. Может ли нейросеть его делать? Частично. LLM быстро накидывает черновик конфига и пишет симуляцию, но считать в голове ей нельзя: проверяет баланс код, а решение по метрикам остаётся за человеком.
Я в мобильном геймдеве с 2020 года: Plarium, GAMETEQ, MetaPlayLab, Redneck, MadOut Games, от продукт-менеджера до ведущего геймдизайнера и продюсера. Баланс я сводил в таблицах задолго до того, как нейросети научились писать код. Сейчас у меня есть свой проект, DnD-бот с ИИ-мастером, где LLM прямо в проде выбирает противников. Ниже один сквозной пример, мобильная игра с монетами и зданием, которое качается до 20-го уровня, симуляция на Python и то, как я развёл работу между нейросетью и кодом у себя в боте.
Что такое баланс игры и игровая экономика?
Игровая экономика - это система ресурсов игры: откуда они приходят, где копятся и куда уходят. Баланс экономики - это подбор чисел так, чтобы ресурсов было ровно столько, чтобы игроку хотелось играть дальше: не нищета, от которой бросают на второй день, и не горы золота, на которые нечего купить к концу недели.
В сквозном примере у меня условная мобильная игра. Игрок закрывает дейлики, получает монеты, плюс копится пассивный доход с главного здания. Монеты уходят на апгрейд того же здания, у него 20 уровней. Почти любая экономика раскладывается на одни и те же элементы, их ещё в Machinations называли источниками, стоками и конвертерами (Machinations primer):
| Элемент | Что делает | В сквозном примере | Что ломается, если перекрутить |
|---|---|---|---|
| Источник (faucet) | создаёт ресурс из ничего | дейлики, 300 монет в день при полном закрытии | инфляция, ресурс обесценивается |
| Пассивный источник | капает со временем, часто растёт с прогрессом | доход здания, 100 монет в день на 1-м уровне | доход обгоняет цены, копилка пухнет |
| Сток (sink) | уничтожает ресурс | апгрейд здания, цена растёт с уровнем | дефицит, игрок упирается в стену |
| Пул | копит ресурс у игрока | кошелёк с монетами | огромный пул = нечего покупать |
| Конвертер | меняет один ресурс на другой | уровень здания превращает монеты в доход | петля "доход растёт от трат" разгоняет всю систему |
| Потолок | ограничивает прогресс | 20-й уровень здания | после потолка сток пропадает, монеты копятся вхолостую |
Главная метрика в такой системе - доля потраченного. Если игрок за месяц тратит 85-90% заработанного, стоки работают. Если 15% - экономика уже сломалась, просто игрок этого пока не заметил.
Может ли нейросеть балансить экономику игры?
Нейросеть может делать черновую работу по балансу: предложить стартовые цифры конфига, написать скрипт симуляции, разобрать таблицу на перекосы, объяснить, почему кривая уезжает. Чего она не может - надёжно считать в голове и отвечать за решение. Финальные числа выбирает человек по метрикам, а проверяет их код.
Индустрия при этом уже вовсю пробует. По опросу GDC State of the Game Industry 2025 (больше 3000 респондентов), 52% разработчиков работают в компаниях, где внедрили генеративный ИИ, лично пользуются им 36%. Одновременно 30% считают, что он вредит индустрии, на 12 пунктов больше, чем годом раньше (Game Developer).
Где LLM реально полезна в балансе, а где нет, я свёл в таблицу:
| Задача | Справляется? | Что проверять |
|---|---|---|
| Накидать стартовый конфиг цен и наград | да, быстро | соотношение скоростей роста дохода и цен |
| Написать симуляцию Монте-Карло по описанию | да, это обычный код | что формулы в коде совпадают с твоим описанием |
| Посчитать "сколько дней до 20-го уровня" в голове | нет, ошибается в экспонентах | всегда гонять скриптом |
| Найти перекос в готовой таблице баланса | частично | пересчитать найденное руками |
| Сыграть в прототип вместо первого тестера | частично, сложность чувствует | интересно ли играть, она не скажет |
| Решить, какая кривая правильная | нет | это продуктовое решение по метрикам |
Есть и исследования посерьёзнее моих таблиц. В работе NetEase Fuxi AI Lab на KDD 2025 LLM-агенты, собранные по логам 16 294 реальных игроков MMO, торговали на аукционе, и цены коррелировали с разрывом спроса и предложения на 0,67. Но авторы сами пишут про галлюцинации: агенты делали недопустимые в игре действия (arXiv:2506.04699). А в исследовании Чан Сяо и Бренды Янг (октябрь 2024) LLM играла хуже людей в Slay the Spire, но где тяжело было ей, там было тяжело и людям (arXiv:2410.02829). Подробнее про это исследование и рогалики я писал в разборе мета-прогрессии и симуляции прокачки.
Читайте такжеМета-прогрессия в рогалике: как сбалансировать прокачку между забегамиМета-прогрессия в рогалике: что это, как сбалансировать прокачку между забегами и проверить кривую симуляцией на Python до плейтеста. Код и цифры.Как проверить экономику игры симуляцией?
Проверить экономику симуляцией - значит прогнать тысячу виртуальных игроков через месяц игры и посмотреть на итог: когда они упираются в потолок, сколько монет лежит мёртвым грузом и какую долю заработанного они тратят. Скрипт пишет нейросеть за пару минут, прогон занимает доли секунды.
Беру сквозной пример и два конфига. В конфиге A пассивный доход растёт на 25% с каждым уровнем здания, а цена апгрейда только на 15%. Так выглядит типичный "щедрый" черновик: кажется, что игрок прогрессирует бодро. В конфиге B доход растёт на 8%, цена на 32%. Всё остальное одинаковое: дейлики 300 монет, игрок закрывает от 40% до 100% заданий, первый апгрейд стоит 200 монет.
Скрипт целиком, Python 3.10, без зависимостей:
import random, statistics
DAYS = 30 # горизонт: первый месяц игрока
PLAYERS = 1000 # виртуальных игроков
MAX_LVL = 20 # потолок уровня здания
def simulate(cfg, seed=1):
rng = random.Random(seed)
stock7, stock30, maxed_day, spent_share, levels = [], [], [], [], []
for _ in range(PLAYERS):
coins, lvl, earned, spent, maxed = 0, 1, 0, 0, None
activity = rng.uniform(0.4, 1.0) # какую долю дейликов игрок закрывает
for day in range(1, DAYS + 1):
income = cfg["quests"] * activity + cfg["idle"] * cfg["idle_growth"] ** (lvl - 1)
coins += income
earned += income
while lvl < MAX_LVL:
price = cfg["base"] * cfg["growth"] ** (lvl - 1)
if coins < price:
break
coins -= price
spent += price
lvl += 1
if lvl == MAX_LVL and maxed is None:
maxed = day
if day == 7:
stock7.append(coins)
stock30.append(coins)
levels.append(lvl)
spent_share.append(spent / earned)
maxed_day.append(maxed or DAYS + 1)
return {
"медиана дня макс. уровня": statistics.median(maxed_day),
"уровень на 30-й день": statistics.median(levels),
"копилка на 7-й день": round(statistics.median(stock7)),
"копилка на 30-й день": round(statistics.median(stock30)),
"доля потраченного, %": round(100 * statistics.mean(spent_share), 1),
}
configs = {
"A: доход x1.25, цена x1.15": dict(quests=300, idle=100, idle_growth=1.25, base=200, growth=1.15),
"B: доход x1.08, цена x1.32": dict(quests=300, idle=100, idle_growth=1.08, base=200, growth=1.32),
}
for name, cfg in configs.items():
print(name, simulate(cfg))Вывод прогона (seed=1, 20.10.2026), свёл в таблицу:
| Конфиг | Медиана дня 20-го уровня | Уровень на 30-й день | Копилка на 7-й день | Копилка на 30-й день | Доля потраченного |
|---|---|---|---|---|---|
| A: доход x1,25, цена x1,15 | 14-й день | 20 | 335 монет | 115 286 монет | 13,5% |
| B: доход x1,08, цена x1,32 | не дошли за 30 дней | 11 | 342 монеты | 1 462 монеты | 87,2% |
Самое коварное тут - 7-й день. По нему конфиги не отличить: 335 и 342 монеты в копилке. Если смотреть на экономику глазами только первую неделю, A выглядит нормально. Ломается он на второй: к 14-му дню половина игроков уже на потолке, сток пропал, и к концу месяца у медианного игрока лежит 115 тысяч монет, на которые нечего купить. Тратит он 13,5% заработанного. В B к 30-му дню медианный игрок на 11-м уровне из 20, тратит 87,2% и ещё есть куда расти.
Причина видна даже без скрипта, если знать, куда смотреть: в A доход растёт быстрее цены. Любая экономика, где конвертер "уровень → доход" обгоняет сток "уровень → цена", рано или поздно разгоняется. Нейросеть такой конфиг выдаёт легко, потому что он "правдоподобный", а правдоподобие и баланс - разные вещи.
Мой критерий-граница: если доля потраченного за первый месяц ниже 70% или копилка на 30-й день больше цены трёх следующих апгрейдов, в экономике нет стока, и её надо чинить до релиза, а не live-ops ивентами потом.
Как это работает у меня в DnD-боте: LLM предлагает, код режет
В моём DnD-боте с ИИ-мастером нейросеть каждый раз выбирает, с кем драться игроку. Это тот же баланс, только боевой: противник должен быть опасным, но не убивать персонажа за ход. Схема, на которой я в итоге остановился: LLM выбирает врагов из заранее подобранного пула, а функция balance_encounter пересчитывает их по таблицам опыта и выкидывает лишних.
Конфиг сложности лежит в отдельном JSON, encounter_target_weights.json. Это веса того, какой бой выпадет при каждой настройке сложности:
{
"easy": { "easy": 0.50, "medium": 0.35, "hard": 0.15, "deadly": 0.00 },
"normal": { "easy": 0.20, "medium": 0.40, "hard": 0.30, "deadly": 0.10 },
"hard": { "easy": 0.05, "medium": 0.25, "hard": 0.50, "deadly": 0.20 }
}До этого выбор был взвешенным рандомом 20/50/25/5 без учёта настроек игрока. А балансер ошибался в самой формуле: персонаж 5-го уровня против четырёх лютоволков CR 1 получал скорректированные 1600 XP вместо 2000, потому что для одиночного героя множитель должен быть 2,5, а не 2,0. 2000 XP - это 1,82 от порога "смертельно" для соло на 5-м уровне. Почти гарантированный вайп, который балансер считал просто тяжёлым боем.
Веселее всего было с самой нейросетью. Нарратор-LLM нашёл обход: через поле combat_state_update в своём ответе он сам дописывал врагов с HP 11 и AC 12, и балансер их вообще не видел. На QA-прогоне из трёх боёв через балансер прошёл только один. Промптом это не лечилось, лечилось архитектурой: канал удалили, и все бои пошли через init_combat → balance_encounter. Теперь LLM может предложить что угодно, но если противник по CR больше рекомендованного в 1,5 раза, код его выбросит.
Вывод, который я переношу на любую экономику: нейросеть не должна иметь права записывать числа в игру в обход проверки. Она предлагает, валидатор режет. Про то, как принимать работу у нейронки, если сам не эксперт в теме, у меня есть отдельный разбор ревью AI-кода.
Как сбалансировать игру с нейросетью: пошагово
Сбалансировать игру с нейросетью значит поделить работу: LLM пишет черновик конфига и код симуляции, симуляция считает, человек смотрит на метрики и решает. Весь цикл на одной петле экономики занимает вечер. Главное правило - ни одного числа "на глаз" от нейросети в финальный конфиг.
- Опиши петлю экономики словами: источники, стоки, конвертеры, потолки. Как в таблице из первого раздела.
- Попроси LLM накидать стартовый конфиг. Отдельно спроси, где доход растёт быстрее цен: это первая точка разгона.
- Попроси написать симуляцию на 1000 игроков и 30 дней с разной активностью. Зафиксируй seed, иначе сравниваешь шум.
- Задай метрики заранее: день выхода на потолок, копилка на 7-й и 30-й день, доля потраченного.
- Меняй один параметр за прогон. Два сразу - и уже не понятно, что сработало.
- Конфиг в игре держи отдельно от кода и ставь валидатор на границы, как
balance_encounterв боте. - После релиза сверяй симуляцию с живыми метриками и правь модель, а не только конфиг.
Промпт, с которого я бы начал:
Напиши на Python без зависимостей Монте-Карло симуляцию экономики мобильной игры.
Источники: [дейлики N монет в день, игрок закрывает от X до Y процентов],
[пассивный доход M в день, растёт на G процентов с уровнем здания].
Сток: апгрейд здания, первый стоит P, каждый следующий дороже на K процентов,
потолок L уровней.
Прогони 1000 игроков на 30 дней, seed фиксированный, два-три конфига.
Для каждого выведи: медиану дня выхода на потолок, медианный уровень на 30-й день,
медиану копилки на 7-й и 30-й день, среднюю долю потраченного от заработанного.
Отдельно перечисли места, где доход растёт быстрее цен.Сам код такого размера агент пишет за минуты. Что ещё агент успевает собрать по игре за выходные, я разбирал в статье про создание игр с Claude Code.
Когда нейросеть для баланса игры не нужна
Нейросеть для баланса не нужна, когда чисел мало и их проще проверить руками, или когда ответ даёт только живой игрок. Симуляция и LLM отсекают заведомо сломанные конфиги, но не скажут, весело ли играть, и не заменят метрики после релиза.
- Чисел меньше десятка. Три цены и две награды проще свести в таблице за десять минут, чем объяснять модели.
- Баланс про ощущения, а не про ресурсы. Скорость персонажа, отзывчивость управления, тайминги атак - это game feel, его проверяют руками на прототипе, а не формулой.
- Есть живые метрики. Когда у игры уже есть игроки, лучший источник правды - их данные и A/B-тест конфигов. Модель тут вторична.
- Нет валидатора. Если некому и нечем проверить, что выдала нейросеть, лучше не пускать её числа в игру вообще. Так у меня в боте и появились враги с HP 11, которых никто не считал)
Моя граница: если в экономике больше одного конвертера (ресурс превращается в доход или в другой ресурс) и игрок играет дольше недели, симуляция окупается за вечер. Меньше - садись и считай в таблице сам.
Частые вопросы
Чем источник отличается от стока в игровой экономике?
Источник (faucet) создаёт ресурс: награды за задания, пассивный доход, лут. Сток (sink) его уничтожает: апгрейды, ремонт, покупки у NPC. Если источники растут быстрее стоков, ресурс копится и обесценивается, это и есть игровая инфляция.
Можно ли доверить ChatGPT или Claude расчёт баланса без кода?
Нет. Языковые модели ошибаются в расчётах экспонент и длинных цепочек, а ошибку выдают уверенно. Пусть модель напишет скрипт симуляции, а числа считает интерпретатор Python: так результат можно воспроизвести и проверить.
Чем Machinations отличается от симуляции на Python?
Machinations - браузерный редактор, где экономика собирается схемой из источников, пулов и стоков и прогоняется Монте-Карло без кода. Скрипт на Python гибче и бесплатен, а с LLM пишется за минуты, но схему в Machinations проще показать команде.
Как готовился материал: черновик собран моим AI-конвейером по темам и заметкам из практики, факты сверены с первоисточниками, финальный текст я прочитал, поправил и утвердил перед публикацией. Обложку к статье тоже рисует нейросеть. Про сам конвейер — в разделе обо мне.
