Каскад уровня 13 не падал: в гейте P5 пропущено шестое место взвода

Нашёл пользователь на прогоне 13/23: плиты потолка трясутся, но не
падают.

Причина — моя ошибка в P5.  Гейт loose_any снимается циклом по факту
прохода без живых фаз, а взводиться обязан у КАЖДОЙ записи фазы.  Я
пометил пять мест и пропустил шестое: check_fall_flo, который на уровне 13
раздаёт плитам-потолкам отложенный старт (0xF0..0xFF).  В результате фаза
записывалась, а цикл её не досчитывал — ровно тот отказ, который я сам
описал в комментарии к loose_any: «ложный ноль стоит застывшей навсегда
плиты».

Исправлено, и в шапку loose_any добавлено предупреждение с этим случаем:
добавляя новое место записи фазы, добавляй и взвод.

Замер 13/23 после исправления (максимумы по секциям, 2367 кадров):

                эталон    сейчас
  работа       913 848   911 862
  синяя        159 810   149 106
  зелёная      440 418   436 494
  циан         393 000   382 770

Период: 3 растра в 2341 кадре, 4 в 23, 5 в 2 — как в эталоне.  Зелёная
по-прежнему выше растрового кадра (436 494 против 430 000).

Урок для процесса: сцену 13/23 надо прогонять после КАЖДОЙ правки
loose-механики, а не только когда меняешь её сознательно.  Хост-тесты
этот отказ не поймали: phys_loose_gate_survives_room_change проверяет
возврат в комнату, а не отложенный старт уровня 13.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 18:50:32 +03:00
parent d0de6dedf4
commit d0ac4b1c2a
+13 -2
View File
@@ -2227,9 +2227,14 @@ uint8_t pop_loose_modif[30]; /* публично: читает pop_bg п
* позициям всё равно отрабатывают: замер 11/15 — 9 852 такта на комнату, * позициям всё равно отрабатывают: замер 11/15 — 9 852 такта на комнату,
* где loose-плит нет вовсе. * где loose-плит нет вовсе.
* *
* Ставится ПРИ ВЗВОДЕ фазы — все пять мест записи ненулевого значения лежат * Ставится ПРИ ВЗВОДЕ фазы — все ШЕСТЬ мест записи ненулевого значения лежат
* в этом файле (make_loose_fall, ветка потолка в check_press, do_knock для * в этом файле (make_loose_fall, ветка потолка в check_press, do_knock для
* обоих рядов, восстановление из room_modif в pop_loose_reset). Снимает его * обоих рядов, восстановление из room_modif в pop_loose_reset и раздача
* отложенного старта в check_fall_flo — уровень 13).
*
* ИМЕННО ЗДЕСЬ УЖЕ ОШИБЛИСЬ ОДИН РАЗ: check_fall_flo забыли, и каскад
* уровня 13 перестал падать — плиты дрожали и застывали. Добавляя новое
* место записи фазы, добавляй и взвод. Снимает его
* САМ цикл, когда прошёл оба массива и не встретил ни одной ненулевой фазы. * САМ цикл, когда прошёл оба массива и не встретил ни одной ненулевой фазы.
* *
* Асимметрия намеренная: ложная единица стоит одного холостого прохода, * Асимметрия намеренная: ложная единица стоит одного холостого прохода,
@@ -2596,6 +2601,12 @@ void pop_check_fall_flo(void) __banked
if ((int8_t)pop_ceil_modif[col] > 0) continue; if ((int8_t)pop_ceil_modif[col] > 0) continue;
pop_ceil_modif[col] = pop_ceil_modif[col] =
(uint8_t)(-(int8_t)(pop_prandom(&loose_seed, 255) & 0x0F) - 1); (uint8_t)(-(int8_t)(pop_prandom(&loose_seed, 255) & 0x0F) - 1);
loose_any = 1; /* ШЕСТОЕ место взвода гейта — см. loose_any.
* Пропуск именно здесь стоил каскада на
* уровне 13: плиты получали отложенный
* старт, но цикл их не досчитывал, и они
* дрожали, не падая (нашёл пользователь
* 2026-08-19). */
pop_set_redraw_above(col, POP_RDA_CEIL, 1); pop_set_redraw_above(col, POP_RDA_CEIL, 1);
} }
} }