← На главную

System.Random ломает случайность в Slay the Spire 2

16.06.2026 09:46 · hackernews

В Slay the Spire 2 обнаружилась серьёзная проблема с генерацией случайных чисел. Разные RNG в игре хоть и инициализируются разными сидами (например, new Rng(seed + hash("up_front"))), но используют стандартный System.Random из C#. А его псевдослучайная последовательность почти линейно зависит от начального сида. В результате зная первый вызов одного RNG, можно предсказать первый вызов любого другого.

Последствия заметны уже в первом акте. Например, если взял Neow's Bones в Underdocks, то случайное проклятие — Debt с вероятностью 54%. В Overgrowth это проклятие выпадает реже. Из-за той же корреляции в Underdocks первый бой в 76% случаев роняет зелье, а в Overgrowth — всего в 4%. Ивент Trash Heap в Underdocks вообще никогда не выдаёт карту Rebound — собрать полную коллекцию в игре невозможно. Large Capsule даёт редкий артефакт в 63% случаев в Underdocks и в 30% в Overgrowth, хотя сам появляется лишь в 1.65% забегов. Зная, какой артефакт предложил Neow, можно угадать, куда попадёт первая молния Дефекта в бою, или результат ивента Doll Room во втором акте.

Автор случайно наткнулся на проблему, когда пытался найти сид с трансформацией в The Scythe и Call of the Void через Leafy Poultice на Overgrowth — такой сид не существовал. Проверка показала, что значение для определения акта всегда было близко к 0.1, хотя должно было быть случайным. Разобравшись, он составил огромный список первых и вторых вызовов всех RNG — от содержимого первой лавки до музыки и внешности врагов. В оригинальном Slay the Spire 1 похожая корреляция была, но там использовался целочисленный генератор, и влияние было меньше. В Spire 2 генератор выдаёт дробные числа от 0 до 1, поэтому предсказывать можно почти всё.

Хорошая новость: исправление тривиальное. Достаточно заменить System.Random на любой некоррелированный генератор — даже 50-строчная замена убьёт все зависимости. Игра в раннем доступе, и Mega Crit наверняка это поправят.

Читать оригинал →