Решили: вариант текстового ивента, который игроку не по карману, показывается погашенным; цена варианта вычисляется из его же последствий как нетто золота, а не объявляется отдельным полем; золото проводится одной нетто-записью до всего остального, и при нехватке не применяется ничего.
Сказано: «Вариант недоступен, если не хватает» (07.08.2026, сессия f61282ef). Это выбранный вариант опросника, а не свободная реплика Макса, — формулировка моя, решение его.
Почему: до правки цена уходила той же односторонней записью, что и награда, а
RunStateService.AddGold клампит остаток в ноль. Выбор «купить за 50» с десятью золотыми списывал
десять и всё равно выдавал реликвию. Отвергнутые альтернативы: «скрывать вариант» (игрок не узнаёт,
что упустил, — а в рогалике это часть давления) и «жать можно, транзакция откатится с сообщением»
(больше кода и нужен новый лок-ключ ради худшего чтения).
Цена считается, а не объявляется — отдельное поле стоимости было бы вторым владельцем и разъехалось бы с тем, что реально списывается: автор поправил бы одно число из двух. И считается именно нетто: вариант «получишь сотню, отдашь тридцать» обязан быть доступен с пустым кошельком, иначе гейт прячет выгодное предложение от того, кому оно нужнее всего.
Грабли: нетто-запись понадобилась не ради красоты, а из-за того же клампа — он ломает и порядок. Список «−30, потом +100» с нулём на руках дал бы 100 вместо 70, потому что первое списание упёрлось в дно. Промежуточная сумма не видна нигде, кроме лога, поэтому золото и проводится одной записью. Второе: старый тест закреплял дефект под видом защиты («золото не должно уходить в минус») — такой тест не краснеет, он охраняет.
Владелец правды: Data/Definitions/TextEventData.cs (EventChoice.GoldCost),
Game/Flow/EventEffectApplier.cs; тесты EventEffectApplierTests.Gold_WhenNotEnough_AppliesNothing,
EventEffectApplierTests.ChoiceGoldCost_IsNet_NotSpending.