BUG-GATE-PASS-1: воспроизведён и разобран; SDLPoP собран с трассой
Сценарий: ур.1 комн.8, ряд 0, x=170, лицом вправо, решётка шва закрыта — разбежаться вправо и не отпускать. Кид проходит сквозь решётку. Корень (две трассы, наша и оригинала, стартовая позиция совпала до пикселя): смена комнаты в этой точке ШТАТНАЯ и у нас, и в оригинале — leave_room вправо блокируют только doortop. Оригинал держит Кида бампом СРАЗУ ПОСЛЕ перехода, потому что check_collisions хранит флаги по паре (колонка в СВОЕЙ комнате, номер комнаты) и сравнивает prev/curr только при совпадении номеров: решётка комнаты 8 и до, и после перехода лежит в слоте 9 с room=8, история не рвётся. У нас индекс — колонка относительно отрисованной комнаты, при переходе все индексы уезжают на 10, поэтому enter_room зовёт pop_coll_invalidate, тот подавляет бамп на кадре входа, а дальше перехода флага 0->1 уже не будет. Что делать — порт индексации оригинала (10 слотов по колонке своей комнаты + массив её номера); тогда pop_coll_invalidate не нужен вовсе. Осторожно: это сердце коллизии из BUG-SEAM-PINGPONG. SDLPoP инструментирован для сверки: POP_TRACE=1 включает покадровую печать Char + обе пары краёв, плюс маркеры BUMPED и LEAVE. В bug_list записана и команда сборки на macOS (штатный Makefile требует pkg-config, которого нет).
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) | проход сквозь закрывшуюся решётку (0,9) комнаты 5 | Major | **ждёт сценария**: прогоном 2026-08-07 не воспроизведён |
|
||||
| [BUG-GATE-PASS-1](#bug-gate-pass-1) | проход сквозь закрытую решётку шва (комн. 8 -> 6) | Major | **воспроизведён, корень найден 2026-08-08**: история флагов коллизии не привязана к комнате |
|
||||
| [BUG-SPIKE-1](#bug-spike-1) | пики залипают выдвинутыми рядом с Кидом | **низкий** | маловоспроизводимый: ни сценарием, ни попиксельной подгонкой X не поднимается |
|
||||
| [BUG-CHOMP-JUMP-1](#bug-chomp-jump-1) | прыжок с места вплотную к чомперу: кадр с отступом назад | **низкий** | маловоспроизводимый: на повторе не поднялся; на пререлиз |
|
||||
| [T-1](#t-1) | пики перерисовываются безусловно | оптимизация | открыт |
|
||||
@@ -193,7 +193,89 @@ Smoke-прогон уровня 3 (пользователь, 2026-08-05) дал
|
||||
# Открытые баги уровня 1
|
||||
|
||||
<a id="bug-gate-pass-1"></a>
|
||||
## BUG-GATE-PASS-1. Проход сквозь закрывшуюся решётку — ЖДЁТ СЦЕНАРИЯ
|
||||
## BUG-GATE-PASS-1. Проход сквозь закрывшуюся решётку — **КОРЕНЬ НАЙДЕН 2026-08-08**
|
||||
|
||||
> **ВОСПРОИЗВЕДЁН И РАЗОБРАН.** Сценарий: уровень 1, комната 8, ряд 0,
|
||||
> `Kid.x = 170`, лицом ВПРАВО, решётка шва (комната 8, колонка 9) ЗАКРЫТА.
|
||||
> Разбежаться вправо и НЕ ОТПУСКАТЬ клавишу. Кид проходит сквозь решётку и
|
||||
> убегает вглубь комнаты 6.
|
||||
>
|
||||
> Ниже — новый разбор; всё, что было раньше (гипотеза про x > 205), не
|
||||
> подтвердилось и оставлено в конце для истории.
|
||||
|
||||
### Корень: история флагов коллизии индексируется НЕ ТАК, как в оригинале
|
||||
|
||||
Сняты две трассы — наша (брейкпоинт на резидентном `kid_tick`) и оригинала
|
||||
(SDLPoP, собран с `POP_TRACE=1`, печать в `play_kid_frame` + маркеры в
|
||||
`bumped` и `exit_room`). Стартовая позиция совпала до пикселя, поэтому
|
||||
сравнение построчное.
|
||||
|
||||
**Оригинал:**
|
||||
|
||||
```
|
||||
LEAVE dir=1 x=61 cxl=184 cxr=201 room=6 смена комнаты — ШТАТНАЯ
|
||||
BUMPED dx=-2 push=-1 x=63 tile=4 col=9 и СРАЗУ бамп о решётку, откат
|
||||
KID f=15 x=60 act=0 col=-1 room=6 drawn=6 сел за решёткой, стоит
|
||||
```
|
||||
|
||||
**Мы:**
|
||||
|
||||
```
|
||||
x 170 -> 196 бегом, col 7 -> 8 -> 9, НИ ОДНОГО бампа
|
||||
x=198 -> room 8 -> 6
|
||||
при удержании ВПРАВО доезжает до col 1 комнаты 6 и бежит дальше
|
||||
```
|
||||
|
||||
Смена комнаты в этой точке правильна и у нас, и у оригинала: `leave_room`
|
||||
(seg002:423) вправо блокируют ТОЛЬКО `doortop`-тайлы, решётки в списке нет, а
|
||||
порог `char_x_right >= 201` совпадает с плоскостью ворот
|
||||
(`x_bump[9+FIRST_ONSCREEN_COLUMN] + TILE_MIDX + wall_dist_from_left[1]`
|
||||
= 191 + 10). Оригинал полагается не на запрет ухода, а на бамп СРАЗУ ПОСЛЕ
|
||||
перехода.
|
||||
|
||||
**Почему бамп есть у них и нет у нас.** `check_collisions` (seg004:0004)
|
||||
хранит флаги так:
|
||||
|
||||
```c
|
||||
row_coll_flags_ptr[tile_col] = curr_flags; // индекс — колонка В РАЗРЕШЁННОЙ комнате
|
||||
row_coll_room_ptr [tile_col] = curr_room; // и рядом — НОМЕР ЭТОЙ КОМНАТЫ
|
||||
...
|
||||
if (curr_row_coll_room[column] >= 0 &&
|
||||
prev_coll_room[column] == curr_row_coll_room[column]) { /* только тогда сравниваем */ }
|
||||
```
|
||||
|
||||
То есть история привязана к паре **(колонка внутри своей комнаты, комната)**.
|
||||
Решётка комнаты 8 и до перехода, и после лежит в слоте 9 с `room = 8` —
|
||||
переход 8->6 историю НЕ рвёт, переход флага 0->1 виден, бамп срабатывает.
|
||||
|
||||
У нас массив `coll_prev/coll_curr` индексируется колонкой ОТНОСИТЕЛЬНО
|
||||
отрисованной комнаты (−2…11). При смене комнаты все индексы уезжают на 10,
|
||||
сопоставить прошлый кадр с текущим нечем, и `enter_room` вынужден звать
|
||||
`pop_coll_invalidate()`; тот ставит «прошлые флаги = уже перекрывал» (3), то
|
||||
есть ПОДАВЛЯЕТ бамп на кадре входа. А к следующему кадру Кид уже за
|
||||
плоскостью ворот — перехода 0->1 не будет никогда.
|
||||
|
||||
### Что делать
|
||||
|
||||
Порт индексации оригинала: хранить флаги в 10 слотах ПО КОЛОНКЕ РАЗРЕШЁННОЙ
|
||||
комнаты плюс параллельный массив её номера, и сравнивать prev/curr только при
|
||||
совпадении номеров. Тогда `pop_coll_invalidate()` не нужен вовсе — история
|
||||
сама «не совпадает» там, где колонка сменила комнату.
|
||||
|
||||
**Осторожно:** это сердце коллизии, вокруг которого разбирался
|
||||
BUG-SEAM-PINGPONG (см. `bug_closed.md`). После правки обязателен прогон
|
||||
швов: комнаты 6/8 первого уровня в обе стороны, осторожный шаг и разбег, плюс
|
||||
проверка, что пинг-понг не вернулся.
|
||||
|
||||
**Инструмент для сверки готов:** SDLPoP собран с трассой, включается
|
||||
`POP_TRACE=1` (правки в `seg000.c` play_kid_frame, `seg004.c` bumped,
|
||||
`seg002.c` exit_room, чтение переменной — `main.c`). Сборка на macOS:
|
||||
`make CFLAGS="-std=gnu99 -O2 -I/opt/homebrew/include -Wno-implicit-function-declaration" LIBS="-L/opt/homebrew/lib -lSDL2 -lSDL2_image"`
|
||||
(в системе нет pkg-config, штатный Makefile без этого не собирается).
|
||||
|
||||
---
|
||||
|
||||
### История: прежний разбор (гипотеза НЕ подтвердилась)
|
||||
|
||||
**Статус: наблюдался один раз (2026-08-03), воспроизвести не удалось ни
|
||||
тогда, ни прогоном всех комнат уровня 1 (2026-08-07).** Заведён, чтобы
|
||||
|
||||
Reference in New Issue
Block a user