Files
Sprinter-SDCC/applications/PoP/roomtest/bug_list.md
T
Александр Петров d552cbaca9 docs: bug_list — только открытые баги; закрытые → bug_closed.md
Три Critical'а (BUG-1 провал на row 1 при боковом переходе, BUG-2 ping-pong
при возврате, BUG-3 окклюзия climb-up на кнопке) висели непроверенными с
2026-07-21.  Прогнал в MAME:

- BUG-1 не воспроизводится: room6 → кнопка (0,2) → открытая решётка →
  переход влево даёт room8, y=55, curr_row=0.  Заодно снят и сам диагноз
  записи — репроекция Y при БОКОВОМ переходе не нужна: goto_other_room
  (seg002.c:390) меняет только x, наш check_leave делает то же.
- BUG-2 не воспроизводится: шов room2↔room3, четыре пересечения с
  разворотом сразу после входа — комната меняется ровно раз на пересечение.
- BUG-3 закрыт фиксом tile_code_drawn от 2026-07-28 (это дубль уже
  записанного «спуск с кнопки»); оговорка про непереснятый подъём — в
  bug_closed.md.

bug_list.md теперь только открытое (BUG-CEIL-1/2/3, BUG-OCCL-1, T-1, T-2,
таблица обхода 24 комнат) + индекс с якорями.  bug_closed.md — закрытое
вместе с разбором корней (odd-pixel char_x, подстановка тайла кнопки, баг
кодогенератора SDCC), он и есть главная ценность архива.

TASKS.md: кросслинки на открытые баги в шапке, в L1-TRIAGE, L1-PASS и
«Отложено».  Указатели в CLAUDE.md/README/room_model_plan/layout_plan_v2
переведены на нужный из двух файлов.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 20:57:33 +03:00

193 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# roomtest — ОТКРЫТЫЕ баги и незакрытые оптимизации
Только то, что **не закрыто**. Всё закрытое (и, что важнее, разбор корней —
odd-pixel арифметика `char_x`, подстановка тайла нажатой кнопки, баг
кодогенератора SDCC) переехало в [`bug_closed.md`](bug_closed.md): прежде чем
заводить новый баг, грепни там по симптому.
Приоритеты работ — в [`TASKS.md`](TASKS.md), а не здесь. Правило проекта:
механику сверять с `../SDLPoP/src/` ДО кодинга.
Ревизия списка: **2026-08-01** (задача L1-TRIAGE). BUG-1, BUG-2 и BUG-3
стояли как Critical с 2026-07-21 — все три прогнаны в MAME и закрыты,
протокол в [`bug_closed.md`](bug_closed.md). Critical'ов сейчас нет.
| ID | что | тяжесть |
|----|-----|---------|
| [BUG-CEIL-1](#bug-ceil-1) | прыжок вверх: руки Kid поверх потолка | Medium |
| [BUG-CEIL-3](#bug-ceil-3) | анимация ворот стирает потолок над ними | Medium |
| [BUG-OCCL-1](#bug-occl-1) | тень дальней колонны перекрывает Kid | Medium |
| [BUG-CEIL-2](#bug-ceil-2) | loose-плита в потолке не трясётся | Medium, отложен |
| [T-1](#t-1) | пики перерисовываются безусловно | оптимизация |
| [T-2](#t-2) | Кид перерисовывается в покое | оптимизация |
| [обход 24 комнат](#обход-всех-24-комнат-уровня-1) | таблица заполнена на 5 строк из 24 | ревизия |
---
<a id="bug-ceil-1"></a>
## BUG-CEIL-1. Прыжок вверх: руки Kid рисуются ПОВЕРХ потолка — **Medium**
**Симптом (2026-07-22):** при прыжке вверх (SEQ up, кадры 67..79) руки/голова
Kid заходят в полосу кладки у потолка (row -1) и рисуются ПОВЕРХ неё — потолок
должен окклюдить руки (как передняя грань).
**Где:** `pop_bg.c` — полоса потолка (`draw_tile(-1)`) сейчас только фон
(запечена в pop_room_draw), не окклюдер поверх Kid. Нужен ceiling-overlay в
`pop_fore_over_kid` (перерисовать срез полосы над Kid поверх спрайта), по
аналогии с fore-тайлами. Инфраструктура `g_clip_top`/`gfx_blit_part` уже есть.
<a id="bug-ceil-3"></a>
## BUG-CEIL-3. Анимация ворот стирает потолок над ними — **Medium**
**Симптом (2026-07-22):** при опускании/поднятии решётки шва (анимация openness)
полоса кладки у потолка НАД воротами пропадает (см. потолок над левым швом).
**Где:** `pop_bg.c` `pop_room_redraw_seam_left``pop_button_redraw`/
`pop_spike_redraw` — общий класс): чёрный `bar` по col0 row0 стирает потолочную
полосу (row-1), а redraw рисует только сам гейт, не восстанавливая полосу.
Нужно: при перерисовке шва/тайла у потолка перерисовать и срез потолочной полосы
(draw_tile(-1,col) с g_clip_top) над затронутыми колонками.
<a id="bug-occl-1"></a>
## BUG-OCCL-1. Тень дальней колонны перекрывает Kid в (0,4)-(0,5) — **Medium**
**Симптом (2026-07-22):** Kid, стоя/прыгая у (0,4)-(0,5), частично перекрыт
тёмной штриховкой — это ТЕНЬ/боковая грань ДАЛЬНЕЙ колонны (сзади по глубине),
которая НЕ должна окклюдить персонажа. Over-occlusion fore-слоя.
**Где:** `pop_bg.c` `pop_fore_over_kid`/`fore_tile` — рисует fore футпринт-тайлов
без учёта глубины (какая грань РЕАЛЬНО перед Kid). Порт seg003 redraw_at_char
окклюдит только передние грани; дальняя колонна (за Kid) не должна. Сверить с
SDLPoP redraw_at_char (какие тайлы/грани идут в fore vs back по y-сортировке).
<a id="bug-ceil-2"></a>
## BUG-CEIL-2. Тряска/разбитие loose-плиты в потолке (row -1) не работает — **Medium, ОТЛОЖЕН**
**Симптом (2026-07-22):** loose-плита в ряду 2 верхнего соседа (room5 (2,5) →
потолок room6 над (0,5)) при прыжках Kid на (0,5) НЕ трясётся и не разбивается.
**Где:** верхний сосед не «живой» — `above_fg` берётся из статики уровня,
loose-состояние соседней комнаты не тянем (per-room loose/modif не персистятся).
check_press/knock работают только по текущей комнате. Нужно: (а) пробой
loose сверху через границу комнаты, (б) персистентное loose-состояние соседа +
его отрисовка в полосе. Пока полоса рисует loose статически (кадр покоя).
**Почему отложен:** требует персистентного per-room modifier соседей — это
фаза P0 из [`../docs/gates_spikes_plan.md`](../docs/gates_spikes_plan.md), а не
точечный фикс. См. «Отложено осознанно» в [`TASKS.md`](TASKS.md).
---
# Оптимизация отрисовки (записано 2026-07-29)
Не баги — план работ. Оба пункта про одно: у оригинала пометка тайла к
перерисовке стоит копейки (бит в таблице, которая всё равно чистится каждый
кадр), а у нас каждая такая пометка превращается в реальный heal (копию из
ОЗУ-копии акселератора) плюс блиты. Поэтому буквальный порт «перерисовываем
безусловно» корректен, но дорог.
<a id="t-1"></a>
## T-1. Пики: перерисовывать по причине, а не безусловно
**Сейчас:** `pop_process_trobs` зовёт `pop_spike_redraw` каждый кадр для
каждой живой пики в комнате (порт `redraw_21h`, который `animate_spike`
вызывает вне всяких `if`). Это корректно, но лишнее для пик, до которых
Киду дела нет.
**Надо:** перерисовывать тайл пики, только если
1. **сменился её видимый кадр** (шаг выдвижения/уборки), ЛИБО
2. **её кто-то стёр** — а стереть у нас может только heal, то есть тайл
попал в прямоугольник `kid_heal` этого кадра.
Это и есть модель оригинала, просто выраженная флагами: `redraw_at_char`
(seg003:0576) каждый кадр помечает `set_redraw_fore` тайлы персонажа, причём
**объединение текущего и предыдущего** прямоугольника
(`MIN(char_top_row, prev_char_top_row)` и т.д.), а `animate_spike` помечает
свой тайл. Итог = {тайл сменил кадр} ∪ {тайлы Кида}.
**Как:** слой Кида и так считает `cL..cR`/`rT..rB` в `pop_fore_over_kid`
пусть публикует их (плюс предыдущие, как в оригинале), а цикл trob'ов
сравнивает `tilepos` с диапазоном целочисленно. Никаких пересечений
прямоугольников (см. память `manual_hints_over_auto_detect`).
**Приоритет:** отдаётся почти бесплатно ПОСЛЕ T-2, отдельно не окупается.
<a id="t-2"></a>
## T-2. Idle-skip: не перерисовывать Кида, когда ничего не происходит
**Сейчас:** `kid_heal``kid_draw``pop_fore_over_kid` идут каждый кадр,
даже когда Kid стоит и в его тайлах ничего не меняется. Это ровно поведение
оригинала (`draw_game_frame`, seg000:917 — `draw_moving()` + `draw_tables()`
безусловно), но у него это дёшево, а у нас нет.
**Надо:** пропускать heal+draw Кида, когда кадр/поза/координаты не менялись
и в его тайлах нет активной анимации.
**Осторожно (дабл-буфер):** пропускать можно **не раньше второго подряд**
неизменного кадра — иначе одна из двух страниц останется со старым
содержимым. Условие «обе страницы уже получили это состояние».
**Связь с T-1:** после T-2 пики отпадают сами — раз Кида не перерисовываем,
heal'а нет, стирать пики нечем, редрой не нужен.
**Связь с KBD-1:** это ещё и минус DI-окна в самых спокойных кадрах — ровно
там, где тапают Shift+стрелку (см. остаток KBD-1 в [`TASKS.md`](TASKS.md)).
---
# Обход всех 24 комнат уровня 1 — поиск багов отрисовки
Инструмент: `#define ROOMNAV` в `roomtest.c``+`/`-` (цифровой блок либо
`=`/`-` основного ряда) переключают комнату по номеру (1..24, с обёрткой),
Kid ставится на первый пол, `pop_trob_reset()` возвращает пики/ворота в
исходное. Номер комнаты — полосками в верхнем борте: слева десятки, справа
единицы (`||` `||||` = 24). Убирается закомментированием одной строки.
Комнаты **13, 18, 24 недостижимы** в обычной игре — это свойство данных
уровня, разбор в [`bug_closed.md`](bug_closed.md) («НЕ БАГИ»). Приоритет
багов в них низкий.
Таблица заполнена на 5 строк из 24 — доделать в рамках L1-TRIAGE
([`TASKS.md`](TASKS.md)).
| комната | статус | что не так |
|---------|--------|------------|
| 1 | пофикшено | падающая плита (2,6): правая грань видна через пол (2,7) и перекрывает его переднюю грань — `mob_render` брал ряд соседа из `m->row` (счётчик, уже ушедший на ряд вперёд), а не из координаты |
| 2 | | |
| 3 | | |
| 4 | | |
| 5 | пофикшено | прыжок в решётку: Kid оставался стоять на 6 px ВЫШЕ пола и без приземления-приседания — от `bumped()` (seg004) был портирован только хвост (`seq_47`), не хватало `bumped_floor` (прижатие Y к полу + `seq_46_hardbump` на кадрах прыжка 24/25/40..42/102..106) и `bumped_fall` |
| 6 | | |
| 7 | | |
| 8 | | |
| 9 | сделано | дверь уровня (1,3)-(1,4) рисовалась чёрным проёмом: не был портирован `draw_leveldoor` (seg008:1D29) — створка (слайсы 33 + верх 34), лестница за ней (99/144) и анимация подъёма по кнопке (`animate_leveldoor`, seg007:05F1, modif 0→43). Спрайты 33/34/99/144 добавлены в атлас явным набором (render_room.py дверь не рисует) |
| 10 | | |
| 11 | | |
| 12 | пофикшено | вис/подтягивание на кромке loose-плиты: плита рисовалась ПОД Кидом. Не хватало двух кусков `draw_tile`: (а) `draw_loose` кладёт нижнюю грань плиты И в foretable (поверх персонажа), (б) `draw_tile_base` подставляет верх плиты из `loose_fram_left`, а в нашем midtable-оверлее стоял голый `base_id` (у loose он 0). Голова Кида поверх падающей на него плиты — см. «НЕ БАГИ» в `bug_closed.md` |
| 13 | недостижима в игре | |
| 14 | | |
| 15 | сделано | меч (2,2) не рисовался: тайл 22 в draw_tile_anim не был портирован. Добавлены отрисовка предмета (chtab_1 id 10/11 на draw_main_y3), подъём по Shift (check_get_item/get_item/do_pickup: присед → seq_91 pickupsword → меч исчезает с пола) и статус `pop_have_sword` |
| 16 | | |
| 17 | | |
| 18 | недостижима в игре | |
| 19 | | |
| 20 | | |
| 21 | | |
| 22 | | |
| 23 | | |
| 24 | недостижима в игре | |
---
## Заметки (отладка)
- Тестовые клавиши осторожного шага: **J** = шаг влево, **L** = шаг вправо
(эмуляция Shift+стрелка), см. `pop_ctrl.c` `KBD_DBG_STEP*`. Первый шаг в
сторону = разворот (как в оригинале safe_step), движение со второго.
- Читы (`pop_cheat.h`): **K** — убить стража, **I** — бессмертие (toggle),
**S** — выдать меч.
- Респавн после смерти — по **↑** (или авто через `RESPAWN_DELAY`); ставит
Kid в `START_ROOM`.
- `START_ROOM=1 / COL 3 / ROW 0` — жёстко зашитый тестовый старт; перевести
на `pop_level_start_*` (задача L1-START в [`TASKS.md`](TASKS.md)).