docs: BUG-SEAM-DRAW-1 закрыт (не воспроизводится), заведён BUG-GATE-PASS-1
BUG-SEAM-DRAW-1: Кид упирается в решётку и встаёт на x=61, curr_col=-1, room=1 — и в комнате 1 РИСУЕТСЯ, за решёткой. При x=61 он уже внутри системы координат комнаты 1 (obj_x = 6), straddle-смещение не требуется. Остаток теоретический: при x <= 60 спрайт ушёл бы за левую кромку; полное лекарство — довести S3, но поводов нет, заводить обратно только по живому наблюдению. BUG-GATE-PASS-1: однократное наблюдение — Кид стоял НА тайле решётки (0,9) комнаты 5, дождался закрытия, пошёл вправо и прошёл в комнату 1. Повторить не удалось: в том же месте при x=196/col=9 решётка держит штатно. Плоскость блокировки для колонки 9 — x=205, а «колонка 9» по m7 это x ∈ [191,205), то есть при curr_col==9 проход невозможен по построению; значит наблюдался x >= 205, и поведение может оказаться штатным (решётка закрылась за спиной). Гипотеза НЕ подтверждена, поэтому баг оставлен открытым со списком того, что снять в следующий раз, и с двумя запасными кандидатами на корень. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -741,3 +741,30 @@ dir_56_none`. То есть стражи — такая же часть дан
|
||||
проверка занимает несколько строк — заспавнить кусок, сменить комнату, тикать
|
||||
до приземления, проверить щебень в данных уровня. Стоит первым в
|
||||
`../docs/host_tests_plan.md`.
|
||||
|
||||
<a id="bug-seam-draw-1"></a>
|
||||
## BUG-SEAM-DRAW-1. Кид, упершийся в решётку на шве, не рисуется — **ЗАКРЫТ (не воспроизводится)**
|
||||
|
||||
**Как было заведено.** Комната 5: Кид добегает до закрытой решётки (0,9),
|
||||
решётка его держит, но экран переключается на комнату 1, и в ней Кида не
|
||||
видно — он стоит на `x = 57..60`, левее кромки комнаты (col 0 начинается с 58).
|
||||
|
||||
**Проверка 2026-08-03.** Не воспроизводится: Кид упирается и встаёт на
|
||||
`x = 61`, `curr_col = -1`, `room = 1` — и в комнате 1 РИСУЕТСЯ, за решёткой,
|
||||
как и должен.
|
||||
|
||||
Почему сходится: при `x = 61` персонаж уже внутри системы координат комнаты 1
|
||||
(`obj_x = 2*61 − 116 = 6`), поэтому никакого straddle-смещения не требуется и
|
||||
обычная отрисовка справляется. Отрицательная `curr_col` тут не противоречие —
|
||||
это правило `get_tile_div_mod_m7`: `(61 − 7 − 58) / 14 = −1`.
|
||||
|
||||
**Что осталось за скобками.** Само переключение экрана штатное: `leave_room`
|
||||
(seg002:423) уводит вправо при `char_x_right >= 201`, а левая грань решётки как
|
||||
раз 201 — оригинал в этой позе тоже перелистнёт.
|
||||
|
||||
И остаётся теоретический остаток: при `x <= 60` (`obj_x <= 4`) спрайт уходил бы
|
||||
за левую кромку и обрезался. В текущей сборке Кид туда не встаёт, поэтому баг
|
||||
и не воспроизводится. Полное лекарство — довести модель straddle (S3 в
|
||||
`../docs/room_model_plan.md`): держать `Kid.room` отдельно от `drawn_room` и
|
||||
рисовать со смещением ±140, как `xpos_in_drawn_room` (seg004:0405). Пока
|
||||
поводов для этого нет — заводить обратно только по живому наблюдению.
|
||||
|
||||
@@ -20,11 +20,14 @@ BUG-DEATH-1 (смерть от меча), BUG-GATE-ANIM-1 (анимация во
|
||||
закрыты — BUG-KBD-4 (фантомный отжим Shift), BUG-RESPAWN-2 (стражи не оживают),
|
||||
BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (осколки только от одной
|
||||
из двух плит). У BUG-DRAWORDER-1 остался артефакт «ноги поверх головы»,
|
||||
сверенный с SDLPoP и записанный в «НЕ БАГИ».
|
||||
сверенный с SDLPoP и записанный в «НЕ БАГИ». Тогда же закрыт как
|
||||
невоспроизводящийся BUG-SEAM-DRAW-1 (Кид в шве рисуется) и заведён
|
||||
BUG-GATE-PASS-1 — однократное наблюдение прохода сквозь закрывшуюся решётку,
|
||||
которое ЖДЁТ надёжного сценария.
|
||||
|
||||
| ID | что | тип | статус |
|
||||
|----|-----|-----|--------|
|
||||
| [BUG-SEAM-DRAW-1](#bug-seam-draw-1) | у решётки на шве экран переключается, а Кид в шве НЕ рисуется | Minor | открыт |
|
||||
| [BUG-GATE-PASS-1](#bug-gate-pass-1) | проход сквозь закрывшуюся решётку (0,9) комнаты 5 | Major | **ждёт сценария воспроизведения** |
|
||||
| [T-1](#t-1) | пики перерисовываются безусловно | оптимизация | открыт |
|
||||
| [T-2](#t-2) | Кид перерисовывается в покое | оптимизация | открыт |
|
||||
| [обход 24 комнат](#обход-всех-24-комнат-уровня-1) | таблица заполнена на 5 строк из 24 | ревизия | открыт |
|
||||
@@ -51,7 +54,7 @@ BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (ос
|
||||
| 4 | комната 12: разбить плиты (0,1)/(0,2) и потолок в 16, выйти-вернуться | остаются разбитыми, проём не закрывается |
|
||||
| 5 | комната 17 из 23: разбить (1,5)/(1,6), выпить зелье (2,3), вернуться | всё остаётся |
|
||||
| 6 | **после смерти** зайти в те же комнаты | ВСЁ восстановлено (в оригинале смерть = `load_level`) |
|
||||
| 7 | комната 12: разбег в закрытую решётку (0,9) с полушага | не проходит насквозь; экран может перелистнуться — это [BUG-SEAM-DRAW-1](#bug-seam-draw-1) |
|
||||
| 7 | комната 12: разбег в закрытую решётку (0,9) с полушага | не проходит насквозь; перелистывание экрана штатно (см. BUG-SEAM-DRAW-1 в `bug_closed.md`) |
|
||||
| 8 | комната 6: бег справа налево от (0,9), длинный прыжок (0,6)→(0,7) | не влетает внутрь стены |
|
||||
| 9 | комната 5: с кнопки (0,6) падение на (2,7), присед, вставание | остаётся в комнате 5 (проверено трассой: `fr=111 x=177` → `seq_47` → `fr=15 x=173`) |
|
||||
| 10 | комната 5: нажать кнопку (0,4) | поднимаются ОБЕ решётки — (0,5) видно на экране, (0,9) проверять из комнаты 1 |
|
||||
@@ -74,28 +77,52 @@ BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (ос
|
||||
|
||||
# Открытые баги уровня 1
|
||||
|
||||
<a id="bug-seam-draw-1"></a>
|
||||
## BUG-SEAM-DRAW-1. Кид, упершийся в решётку на шве, не рисуется
|
||||
<a id="bug-gate-pass-1"></a>
|
||||
## BUG-GATE-PASS-1. Проход сквозь закрывшуюся решётку — ЖДЁТ СЦЕНАРИЯ
|
||||
|
||||
**Симптом.** Комната 5: Кид добегает до закрытой решётки (0,9), решётка его
|
||||
ДЕРЖИТ (проверено: x встаёт на 60 и дальше не растёт), но экран
|
||||
переключается на комнату 1, и в ней Кид не виден — он стоит на `x = 57..60`,
|
||||
левее кромки комнаты (col 0 начинается с 58).
|
||||
**Статус: наблюдался один раз, воспроизвести повторно НЕ удалось.** Заведён,
|
||||
чтобы наблюдение не потерялось; закрывать нельзя — ни как исправленный, ни как
|
||||
«не баг», пока нет надёжного сценария.
|
||||
|
||||
**Разбор.** Переключение экрана само по себе штатное: `leave_room`
|
||||
(seg002:423) уводит вправо при `char_x_right >= 201`, а левая грань решётки
|
||||
как раз 201 — то есть в оригинале экран тоже перелистнётся, если персонаж
|
||||
встанет ровно на грань. Не штатно то, что персонажа в шве **не рисуют**:
|
||||
`update_kid_render_dx` даёт смещение только когда `kid_room != cur_room`, а
|
||||
`enter_room` сразу выравнивает `kid_room = cur_room`. Это остаток
|
||||
непортированной модели straddle (S3 в `pop_kid_plan`).
|
||||
**Что наблюдалось (2026-08-03).** Комната 5: Кид стоял НА тайле решётки (0,9)
|
||||
и ждал, пока она опустится. После закрытия пошёл вправо — прошёл в комнату 1
|
||||
и упал на (1,1).
|
||||
|
||||
**Что делать.** Довести S3: держать `Kid.room` отдельно от `drawn_room` и
|
||||
рисовать персонажа со смещением ±140, как `xpos_in_drawn_room` (seg004:0405).
|
||||
**Что уже измерено и в чём загвоздка.** Сразу после наблюдения повторить не
|
||||
получилось: в том же месте Кид стоит на `x = 196`, `col = 9`, и решётка его
|
||||
ДЕРЖИТ — то есть штатно.
|
||||
|
||||
Арифметика оригинала объясняет разницу. `is_obstacle` (seg004) ставит
|
||||
плоскость блокировки в `x_bump[col + FIRST_ONSCREEN_COLUMN] + TILE_MIDX`, для
|
||||
колонки 9 это **x = 205**. При этом «колонка 9» по `get_tile_div_mod_m7` —
|
||||
это `x ∈ [191, 205)`. Пока `curr_col == 9`, Кид гарантированно левее
|
||||
плоскости и обязан блокироваться; чтобы пройти, он должен оказаться **правее
|
||||
205**, то есть уже на дальней стороне решётки, — и тогда уход вправо законен:
|
||||
решётка закрылась у него за спиной, в оригинале она блокирует плоскость, а не
|
||||
весь тайл.
|
||||
|
||||
Отсюда рабочая гипотеза: в момент наблюдения Кид стоял правее 205 (успел зайти
|
||||
по тайлу дальше, пока решётка была поднята), и поведение штатное. Но повторить
|
||||
эту позу и снять `x` пока не удалось, поэтому гипотеза НЕ подтверждена.
|
||||
|
||||
**Что снять в следующий раз** (без этих чисел вопрос не закрыть):
|
||||
|
||||
1. `Kid.x` и `Kid.curr_col` в момент, когда решётка уже закрылась, а Кид ещё
|
||||
стоит на её тайле — до шага вправо;
|
||||
2. модификатор решётки (openness) комнаты 5, тайл 9 — `can_bump_into_gate()`
|
||||
считает её препятствием только пока `(modif >> 2) + 6 < char_height`, то
|
||||
есть пока она опустилась достаточно низко относительно РОСТА кадра;
|
||||
3. `Kid.x` покадрово на самом шаге вправо — где именно перестал блокировать.
|
||||
|
||||
Быстрый способ снять первое: отладочный стоп-кадр (**1** заморозить, **2**
|
||||
продолжить), затем чтение `_Kid` из отладчика MAME.
|
||||
|
||||
**Возможный корень, если гипотеза не подтвердится.** Проверка идёт по колонке,
|
||||
которая на шве уже принадлежит СОСЕДНЕЙ комнате (`curr_row_coll_room[]` в
|
||||
оригинале); у нас межкомнатная коллизия на шве — исторически проблемное место
|
||||
(ср. закрытый BUG-SEAM-PINGPONG). Второй кандидат — `char_height` в
|
||||
`can_bump_into_gate()`: если он берётся не от того кадра, решётка может
|
||||
перестать считаться препятствием раньше времени.
|
||||
|
||||
# Оптимизация отрисовки (записано 2026-07-29)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user