BUG-GATE-PASS-1: история флагов коллизии переживает боковой переход
Оригинал (seg004:0004) индексирует флаги перекрытия колонкой ВНУТРИ разрешённой комнаты и хранит рядом её номер, поэтому решётка комнаты 8 остаётся в своём слоте и после перехода 8->6: переход флага 0->1 виден, bumped() срабатывает. У нас индекс — колонка отрисованной комнаты, тот же тайл менял слот, и enter_room вынужден был выбрасывать историю целиком — на кадре входа бампа не было, и Кид с разбега уходил сквозь закрытые ворота. Вариант B (сдвиг вместо тега комнаты): при БОКОВОМ переходе история не выбрасывается, а перенумеровывается на 10 слотов. check_leave двигает x ровно на ∓140 = 10 тайлов, координата грани едет на те же 140 вместе с габаритом Кида — сами флаги инвариантны, меняется только номер слота. Сдвигаются curr/above/below (prev на следующем кадре всё равно перезапишет move_coll_to_prev), освободившиеся слоты = 3 «уже перекрывал». Вверх/вниз и прочие входы в комнату — по-прежнему полная инвалидация. Дословный вариант A (10 слотов + массив номеров комнат) не взят: он тянет за собой сужение окна перебора колонок, то есть отказ от FIX_COLL_FLAGS. Заведён docs/impl_diff.md — список осознанных расхождений с SDLPoP; правило «фиксировать расхождение» в обоих CLAUDE.md теперь указывает туда. tests-host: все 5 наборов прошли. Приёмка в MAME впереди. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
| ID | что | тип | статус |
|
||||
|----|-----|-----|--------|
|
||||
| [BUG-CHEAT-FIGHT-1](#bug-cheat-fight-1) | `+`/`−` в бою с вынутым мечом → Кид теряет управление | Major (чит) | открыт |
|
||||
| [BUG-GATE-PASS-1](#bug-gate-pass-1) | проход сквозь закрытую решётку шва (комн. 8 -> 6) | Major | **воспроизведён, корень найден 2026-08-08**: история флагов коллизии не привязана к комнате |
|
||||
| [BUG-GATE-PASS-1](#bug-gate-pass-1) | проход сквозь закрытую решётку шва (комн. 8 -> 6) | Major | **фикс сделан 2026-08-09** (сдвиг истории флагов, вариант B) — ждёт приёмки в MAME |
|
||||
| [BUG-SPIKE-1](#bug-spike-1) | пики залипают выдвинутыми рядом с Кидом | **низкий** | маловоспроизводимый: ни сценарием, ни попиксельной подгонкой X не поднимается |
|
||||
| [BUG-CHOMP-JUMP-1](#bug-chomp-jump-1) | прыжок с места вплотную к чомперу: кадр с отступом назад | **низкий** | маловоспроизводимый: на повторе не поднялся; на пререлиз |
|
||||
| [T-1](#t-1) | пики перерисовываются безусловно | оптимизация | открыт |
|
||||
@@ -255,17 +255,42 @@ if (curr_row_coll_room[column] >= 0 &&
|
||||
есть ПОДАВЛЯЕТ бамп на кадре входа. А к следующему кадру Кид уже за
|
||||
плоскостью ворот — перехода 0->1 не будет никогда.
|
||||
|
||||
### Что делать
|
||||
### Фикс сделан 2026-08-09 (вариант B — сдвиг истории), ЖДЁТ ПРИЁМКИ В MAME
|
||||
|
||||
Порт индексации оригинала: хранить флаги в 10 слотах ПО КОЛОНКЕ РАЗРЕШЁННОЙ
|
||||
комнаты плюс параллельный массив её номера, и сравнивать prev/curr только при
|
||||
совпадении номеров. Тогда `pop_coll_invalidate()` не нужен вовсе — история
|
||||
сама «не совпадает» там, где колонка сменила комнату.
|
||||
Рассматривались два пути:
|
||||
|
||||
- **A, дословный порт.** 10 слотов + параллельный массив номера комнаты,
|
||||
индекс по колонке разрешённой комнаты, бамп только при совпадении номеров;
|
||||
`pop_coll_invalidate()` тогда не нужен вовсе. **Не взят:** оригиналу
|
||||
хватает десяти слотов только потому, что он перебирает узкое окно вокруг
|
||||
Кида, а мы намеренно считаем все четырнадцать колонок (FIX_COLL_FLAGS,
|
||||
чтобы не оставалось протухших ячеек) — при таком переборе колонки −2/−1 и
|
||||
8/9 сядут в одни слоты 8/9. То есть A тянет за собой ещё и сужение окна.
|
||||
- **B, сдвиг истории (сделано).** Индексацию оставляем свою, но при
|
||||
БОКОВОМ переходе историю не выбрасываем, а перенумеровываем на 10 слотов:
|
||||
`check_leave` двигает `x` ровно на ∓140 = 10 тайлов, координата грани
|
||||
(`pop_x_bump`) едет на те же 140 вместе с габаритом Кида, значит сами
|
||||
флаги инвариантны — меняется только номер слота.
|
||||
|
||||
Реализация: `pop_coll_shift(int8_t dcol)` в `pop_map.c` сдвигает
|
||||
`coll_curr/above/below` (не `prev` — его на следующем кадре всё равно
|
||||
перезапишет `move_coll_to_prev`), освободившиеся слоты = 3 («уже
|
||||
перекрывал», бампа нет — ровно то, что в оригинале даёт несовпадение номера
|
||||
комнаты). `enter_room_side` зовёт её сразу после `pop_map_set_edges`:
|
||||
`side == 0` (ушёл влево) → `+10`, `side == 1` (вправо) → `−10`. Переходы
|
||||
вверх/вниз и все прочие входы в комнату остаются на полной инвалидации —
|
||||
там колонки не сдвигаются, но тайлы под ними уже из другой комнаты.
|
||||
|
||||
Расхождение с дословным вариантом A записано в `../docs/impl_diff.md` (D-1).
|
||||
|
||||
**Осторожно:** это сердце коллизии, вокруг которого разбирался
|
||||
BUG-SEAM-PINGPONG (см. `bug_closed.md`). После правки обязателен прогон
|
||||
швов: комнаты 6/8 первого уровня в обе стороны, осторожный шаг и разбег, плюс
|
||||
проверка, что пинг-понг не вернулся.
|
||||
BUG-SEAM-PINGPONG (см. `bug_closed.md`). Приёмка:
|
||||
|
||||
1. Комнаты 6 ↔ 8 уровня 1, закрытая решётка, **обе** стороны.
|
||||
2. Мелким шагом (упереться) И с разбега (не пройти насквозь) — сценарий
|
||||
выше воспроизводится с `Kid.x = 170`, комната 8, ряд 0, лицом вправо.
|
||||
3. Пинг-понг у шва не вернулся (экран не перескакивает туда-сюда).
|
||||
4. `make -C tests-host` — прошли все 5 наборов (2026-08-09).
|
||||
|
||||
**Инструмент для сверки готов:** SDLPoP собран с трассой, включается
|
||||
`POP_TRACE=1` (правки в `seg000.c` play_kid_frame, `seg004.c` bumped,
|
||||
|
||||
Reference in New Issue
Block a user