← Word Tangle · case study Баланс · формула и веса
Баланс · формула и веса

Balance notes — 100-level difficulty curve

Пара к balance-100-levels.xlsx / .csv. Модель, веса, логика ступеней, мостик к экономике и
ограничения. Deliverable фазы 5. Контракт с прототипом: строки 1, 12, 23, 34, 45, 56, 67, 78, 89, 100
воспроизводят P1–P8 и difficulty_score десяти уровней прототипа (levels.json) в пределах ±0.15.


1. Формула difficulty_score

Сложность — взвешенная сумма нормированных параметров P1–P8 (не «слова длиннее»). Каждый
параметр нормируется в [0,1] по своему дизайн-диапазону, поэтому вес = максимальный вклад
этого параметра в очки сложности при полном размахе
. В xlsx это формула в ячейке (лист Table,
колонка difficulty_score), ссылающаяся на веса на листе Model (B4–B12) и на P-ячейки своей строки:

score = FLOOR
      + w1 · (P1−1)/4          # words_count, диапазон 1..5
      + w2 · (P2−4)/4          # word_len_max, 4..8
      + w3 · (P3−1)/5          # zipf_band, 1..6
      + w4 ·  P4               # scramble_score, уже 0..1
      + w5 · (P5)/2            # trap_anagrams, 0..2
      + w6 · (P6−3)/11         # answer_letters, 3..14
      + w7 ·  enc(P7)          # pun_type: direct=0, idiom=.33, homophone=.66, double-layer=1.0
      + w8 · (5−P8)/4          # cartoon_transparency инвертирован: 5=легко→0, 1=сложно→1

enc(P7) в Excel реализован вложенным IF по строковому значению pun_type.

Веса (лист Model) и почему такие

Параметр Вес (макс. вклад) Доля от размаха Обоснование (вклад ≈ влияние на время решения)
P1 words_count 3.29 41 % Число слов — грубый регулятор длины уровня: каждое новое слово — отдельный акт unscramble + удержание в памяти. Линейно множит работу → сильнейший драйвер медианного времени.
P4 scramble_score 2.35 29 % Разрушение биграмм — главный рычаг «залипания» скрэмбла (research §4 п.5; jumble-analysis). На 0–1 шкале с большим весом: переход 0.33→0.70 в одном слове кратно удлиняет поиск.
P2 word_len_max 0.90 11 % Длина слова растит пространство перестановок (факториально), но с потолком читаемости на 6"; вклад заметный, но вторичный к «сколько слов».
P7 pun_type 0.60 7.5 % Когнитивная сложность кульминации: direct → idiom → homophone → double-layer. Двухслойный каламбур требует «додумать» связь — но это разовый акт на уровень, поэтому вклад умеренный.
P5 trap_anagrams 0.35 4.4 % Ложная анаграмма в пуле уводит в тупик; штраф времени есть, но игрок обычно выкарабкивается — не доминирующий фактор.
P6 answer_letters 0.33 4.1 % Длина финального ответа; сильно коррелирует с P1/P2, поэтому во взвешенной сумме несёт свой небольшой остаточный вклад, чтобы не задваивать.
P3 zipf_band 0.10 1.2 % Редкость лексики. Мал по одной причине (см. §5, ограничения): в 10 якорях P3 почти монотонно растёт вместе с P4/P8, и линейная модель не может отделить его собственный вклад — он «поглощён» P4. Оставлен положительным (не ноль), чтобы редкая лексика всё же добавляла сложности.
P8 cartoon_transparency (инв.) 0.10 1.2 % Прозрачность карикатуры. Та же коллинеарность, что у P3: держим маленький положительный вклад, чтобы «намекающая» карикатура читалась как облегчение.
FLOOR 0.0765 Пол шкалы (базовая когнитивная стоимость даже тривиального уровня).

Калибровка весов. Веса не подобраны «на глаз»: это решение минимаксной задачи (LP), которая
минимизирует максимальную ошибку воспроизведения 10 якорей, при ограничениях (а) все веса ≥ 0
(отрицательный вклад параметра бессмысленен), (б) иерархия дизайна: w(P2) ограничен сверху, чтобы
длина слова не перевешивала «сколько слов» и «насколько зол скрэмбл». Достигнутый максимум ошибки по
якорям — 0.149 < 0.15. Файл-калибратор и проверка — build_balance.py / verify_balance.py.

Почему нормированная сумма, а не «сырые» веса из levels-design.md. Рамочная формула из фазы 1
(0.9·P1 + … + 0.30·(6−P8)) была помечена как ориентировочная. При прямом применении она даёт
ошибку до 0.35 на краях (v1, v100 авторски заданы «круглыми» и не ложатся на чистую линейную
модель). Нормировка в [0,1] + минимакс дают попадание в допуск и одновременно человекочитаемые
веса («сколько очков максимум даёт параметр»).


2. Кривая: тренд + пила + передышки + майлстоуны

Расписание новинок (колонка notes, каждый 10-й)

Уровень Новинка
10 первый полноценный 3-словный «разогрев», пик пилы скрэмбла
20 омофонный каламбур закрепляется как стандарт блока
30 подход к первому 2-словному ответу; появляются ловушки
40 2-словные омофоны — рутина; P6 растёт до 9–10
50 в ротацию входят идиомы; более длинные слова (P2=6)
60 устойчивые ловушки; омофоны при 12-буквенных ответах
70 двухслойные каламбуры — стандарт блока; P8 падает до 2
80 4-словные уровни ужесточаются; реже лексика (P3=5)
90 почти максимальный скрэмбл + двухслойность; подход к «экзамену»
100 ТОП-СПАЙК (экзамен): 5 слов, редчайшая лексика, самая косвенная карикатура (P8=1)

3. Логика каждой ступени параметров

Ступени привязаны к якорям прототипа; между якорями значение держится и переключается один раз,
чтобы «новинка» ощущалась как событие. Фактические уровни переключения (из готового файла):


4. Мостик к экономике подсказок и офферам

Кривая — не самоцель, а насос для мягкой валюты и (в полной игре) для мест офферов. free_hint_worth
(4→10 монет) растёт медленнее стоимости подсказки: по research доход за уровень намеренно держат
ниже цены хинта (2–4 монеты дохода против 25–100 за раскрытие буквы), чтобы копился управляемый
дефицит. Спайки на каждом 10-м уровне — это точки максимального target_hint_usage (до ~70 % на
топ-уровнях), то есть места, где игрок с наибольшей вероятностью тратит валюту, а неплатящий смотрит
rewarded-video: майлстоун-спайк = естественный слот для оффера/rewarded-ad, а передышка сразу
после — момент «победы даром», оберегающий ощущение честности. Так difficulty-кривая напрямую задаёт
ритм монетизации: пилообразная сложность порождает пилообразный спрос на подсказки, а майлстоуны
служят якорями для IAP-промо и наградной рекламы, не ломая уютного тона (никаких таймеров и штрафов).


5. Ограничения модели и что калибровал бы плейтестом


6. Проверка (verify_balance.py)

python verify_balance.py открывает готовый xlsx (data_only=False) и проверяет:
[1] ровно 100 строк данных; [2] в колонке difficulty_score все 100 ячеек — формулы (начинаются
с =); [3] пересчёт формулы из P-ячеек воспроизводит 10 якорей в пределах ±0.15 и P1–P8 якорных
строк совпадают с прототипом; [4] тренд возрастает (early avg < late avg) и есть пила (дипы после
спайков). Текущий прогон: ALL CHECKS PASS, worst anchor err = 0.149.