BUG-SPIKE-1: замер опроверг гипотезу о раннем триггере

Watchpoint на модификатор пики (ур.2 к.6, тайл 13) на чистом пробеге:
  modif=1 — кадр 11 (беговой), x=112, col=2
  modif=2 — кадр 12 (беговой), x=117, col=3   (Кид на тайле, h=2)
  modif=3 — кадр 177 (frame_177_spiked)       (напоролся)

То есть check_spike_below/check_spiked/is_spike_harmful и тайминг
выдвижения верны, «раннего» триггера нет.  Настоящий корень: пики
ЗАЛИПАЮТ выдвинутыми — пока габарит Кида накрывает колонку, каждый кадр
start_anim_spike переставляет отрицательный модификатор обратно в 0x8F.
Выдвинутые пики (h=1) для бегущего безвредны по правилам оригинала, отсюда
обе жалобы: пробег не убивает и острия остаются на экране.

Открытый вопрос сузился до 2–3 пикселей: код start_anim_spike совпадает с
оригиналом дословно, значит на скриншоте SDLPoP Кид стоит чуть левее и
колонку пики не задевает.  План закрытия — в записи.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Александр Петров
2026-08-05 21:41:42 +03:00
parent dc8b2b7115
commit 2b17408609
+33 -14
View File
@@ -134,22 +134,41 @@ check_spiked (seg006:0658): убивает при h>=2 на кадрах б
и отсчёт до уборки не доходит. В оригинале в той же позе они убраны,
значит его `check_spike_below` эту колонку УЖЕ не задевает.
**Отсюда единая рабочая гипотеза на оба симптома: наш триггер шире/раньше
оригинального.** Оригинал берёт габарит ТЕКУЩЕГО кадра
(`char_x_left/right`, их ставит `set_char_collision` в этом же кадре), мы —
`kid_fp`, метрики ПОСЛЕДНЕГО ОТРИСОВАННОГО кадра. Если наш диапазон
колонок хоть на пиксель шире, получаем ровно это: пики выходят до подхода
Кида (он проскакивает окно 1..4 → не гибнет) и не убираются, пока он рядом
(→ белые остатки на экране).
**ГИПОТЕЗА «ТРИГГЕР СРАБАТЫВАЕТ РАНО» ПРОВЕРЕНА И ОПРОВЕРГНУТА (замер
2026-08-05, MAME, watchpoint на `room_modif[13]` комнаты 6).** Чистый
пробег по УБРАННЫМ пикам убивает штатно:
**Что снять при разборе:** покадрово `room_modif[13]` вместе с `Kid.x`,
`Kid.frame` и вычисленными `c0..c1` на подходе и пробеге через тайл; тот же
прогон в SDLPoP с печатью `left_checked_col`/`right_checked_col`. Сверять
надо не результат, а ДИАПАЗОН КОЛОНОК кадр в кадр.
```
запись modif=1 : кадр 11 (беговой), x=112, curr_col=2 ← пики пошли вверх
запись modif=2 : кадр 12 (беговой), x=117, curr_col=3 ← Кид уже НА тайле, h=2
запись modif=3 : кадр 177 (frame_177_spiked) ← напоролся
```
**Не регрессия правок 2026-08-05:** ни трёхрядные флаги коллизий, ни
`is_guard_notice`, ни правки отрисовки в путь пик не входят (`check_spiked`
сам зовёт `get_tile_at_char`, модификаторы читает из `pop_trob_modif`).
То есть `check_spike_below`, `check_spiked`, `is_spike_harmful` и тайминг
выдвижения работают правильно, и «раннего» триггера нет.
**Настоящий корень — пики ЗАЛИПАЮТ выдвинутыми.** Пока габарит Кида
накрывает колонку пики, `check_spike_below` каждый кадр зовёт
`start_anim_spike`, а тот при отрицательном модификаторе переставляет его
обратно в 0x8F — отсчёт до уборки не доходит. А выдвинутые пики (h = 1)
для бегущего БЕЗВРЕДНЫ по правилам оригинала. Отсюда обе жалобы: пробег
по уже вышедшим пикам не убивает, и они же остаются торчать на экране.
**Что осталось выяснить (и это единственный открытый вопрос).** Код
`start_anim_spike` у нас с оригиналом совпадает дословно, значит оригинал
тоже удерживал бы пики, стой Кид там же. На скриншоте SDLPoP в похожей
позе пики УБРАНЫ — то есть его Кид стоит чуть левее и его габарит колонку
пики уже не задевает. Разница в 2–3 пикселя посадки, а у нас такие
расхождения по X уже ловились (см. заметку в BUG-GRAB-1: после касания
площадки SDLPoP уводит Кида на 134, мы — на 141).
**Как закрывать:** инструментировать SDLPoP (печать `char_x_left/right`,
`left/right_checked_col` и модификатора пики каждый кадр), проиграть ту же
сцену — падение плиты-потолка в комнате 6 и остановку на щебне — и сверить
с нашей трассой ПОЗИЦИЮ КИДА после приземления. Если позиции совпадут, а
диапазоны колонок разойдутся — виноват габарит (`kid_fp` против
`set_char_collision` текущего кадра); если разойдутся позиции — это отдельный
баг посадки, а пики — его следствие.
---