Оба фикса подтверждены игрой, записи с разбором корней переехали в bug_closed.md. BUG-GATE-PASS-1 остался ждать сценария, но его оговорка про BUG-GATEMOD-1 обновлена (тот закрыт). BUG-SPIKE-1 понижен до низкого приоритета: маловоспроизводим, смертельность пик подтверждена замером. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
35 KiB
roomtest — ОТКРЫТЫЕ баги и незакрытые оптимизации
Только то, что не закрыто. Всё закрытое (и, что важнее, разбор корней)
переехало в bug_closed.md: прежде чем заводить новый баг,
грепни там по симптому.
Приоритеты работ — в TASKS.md, а не здесь. Правило проекта:
механику сверять с ../SDLPoP/src/ ДО кодинга.
Ревизия списка: 2026-08-03 (прогон всех комнат уровня 1). Одиннадцать
наблюдений с прогона свелись к шести корням; все шесть закрыты и проверены
в MAME — разбор в bug_closed.md: BUG-LVLSTATE-1 (уровень
стал мутабельным), BUG-RESPAWN-1 (респавн перезагружает уровень),
BUG-DEATH-1 (смерть от меча), BUG-GATE-ANIM-1 (анимация ворот), BUG-COLL-1
(полный порт check_collisions), BUG-STANDUP-1 (лишний guard в
bumped_floor). Клавиатурный BUG-KBD-3 доведён до конца во второй волне
(см. ниже); из первой волны открытым остался косметический BUG-SEAM-DRAW-1.
Ревизия 2026-08-03, вечер (вторая волна с прогона): все четыре наблюдения закрыты — BUG-KBD-4 (фантомный отжим Shift), BUG-RESPAWN-2 (стражи не оживают), BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (осколки только от одной из двух плит). У BUG-DRAWORDER-1 остался артефакт «ноги поверх головы», сверенный с SDLPoP и записанный в «НЕ БАГИ». Тогда же закрыт как невоспроизводящийся BUG-SEAM-DRAW-1 (Кид в шве рисуется) и заведён BUG-GATE-PASS-1 — однократное наблюдение прохода сквозь закрывшуюся решётку, которое ЖДЁТ надёжного сценария.
| ID | что | тип | статус |
|---|---|---|---|
| Уровень 2 | остальные баги с приёмки | — | принимаются по ходу |
| BUG-GATE-PASS-1 | проход сквозь закрывшуюся решётку (0,9) комнаты 5 | Major | ждёт сценария (BUG-GATEMOD-1, из-за которого решётка стартовала не в том состоянии, закрыт — перепроверить) |
| T-1 | пики перерисовываются безусловно | оптимизация | открыт |
| T-2 | Кид перерисовывается в покое | оптимизация | открыт |
| обход 24 комнат | таблица заполнена на 5 строк из 24 | ревизия | открыт |
| BUG-SPIKE-1 | пики залипают выдвинутыми рядом с Кидом | низкий | маловоспроизводимый: ни сценарием, ни попиксельной подгонкой X не поднимается |
Уровень 2 — баги с приёмки (заведено 2026-08-04)
Уровень 2 заиграл 2026-08-04 (см. TASKS.md запись L2).
Пользователь при первом прогоне увидел несколько багов отрисовки и
подаст их списком отдельно — раздел заведён под них заранее, чтобы
наблюдения не растеклись по переписке.
Закрыто с этой волны: BUG-LOOSE-3 — чёрный бар под упавшей плитой-потолком (запечка восстанавливала не всё, что стёрла).
Порядок работы по уровню 2 (2026-08-05): наблюдения СНАЧАЛА копятся здесь целиком — фиксы берём, когда уровень пройден до конца. Причина: косметика отрисовки почти всегда сводится к общему корню (ср. волну BUG-CEIL-1/2/3 + BUG-OCCL-1), и чинить по одному наблюдению — значит чинить один и тот же корень трижды.
Карта содержимого уровня (что где стоит по данным res2002.bin, какие
кнопки какие ворота открывают) — в TASKS.md,
запись L2-PASS: по ней видно, «механика не сработала» это или
«так и задумано».
Перед заведением записи — грепнуть bug_closed.md по
симптому: почти вся косметика окклюзии уровня 1 уже разбиралась
(BUG-CEIL-1/2/3, BUG-OCCL-1, BUG-DOOR-CLIP, BUG-DRAWORDER-1), и уровень 2
вводит ровно три новых фоновых тайла — большая колонна (низ 8 / верх 9)
и верх двери (12); если артефакт рядом с ними, это первый подозреваемый.
Уровень 3 — баги с приёмки (заведено 2026-08-05)
Smoke-прогон уровня 3 (пользователь, 2026-08-05) дал четыре наблюдения. Два из них — не баги, а неначатые задачи, и записаны как таковые:
| наблюдение | что это на самом деле |
|---|---|
| к.22: чомпер (2,6) не анимируется и вообще не рисуется | L3-CHOMP — механики чомперов НЕТ. В таблице тайлов pop_bg.c:211 строка 12 chomper рисует только основание, правую грань и низ; самих челюстей (спрайт из chtab, draw_tile_anim seg008) нет вовсе. Так и должно выглядеть до порта |
| к.10: скелет не оживает | L3-SKEL — check_skel (seg002:0E1F) не портирован. И комната другая: тайл skeleton(21), который оживает, лежит в к.1 (1,5) — это skeleton_room=1, skeleton_column=5, skeleton_row=1. Ещё два скелета уровня (к.17 (2,7), к.19 (2,2)) — просто декорация, они не оживают никогда. Плюс условие: скелет встаёт, только когда дверь уровня уже открыта и Кид стоит в колонке 2 или 3 |
Остальные два были настоящими багами и закрыты в тот же день — разбор
корней в bug_closed.md: BUG-JUMPWALL-1 (флаги
коллизий считались для одного ряда вместо трёх — бамп терялся на кадре
смены ряда) и BUG-SEAM-WEDGE-1 (сосед угла (2,0) безусловно считался
стеной).
BUG-SPIKE-1. Пики залипают выдвинутыми — НИЗКИЙ ПРИОРИТЕТ, МАЛОВОСПРОИЗВОДИМ
Статус 2026-08-05, вечер. Пользователь повторить не смог, а замер (ниже) показал, что чистый пробег по убранным пикам убивает штатно. То есть в смертельности бага, похоже, нет вовсе: наблюдался частный случай — пики, УЖЕ выдвинутые полностью (h = 1), для бегущего безвредны и в оригинале. Запись оставлена открытой ровно из-за визуального расхождения со скриншотом SDLPoP (у нас острия торчат, у него убраны) — см. конец.
Как получить состояние нарочно: подойти к пикам вплотную (выдвинутся), отступить на полшага, НЕ выходя из зоны срабатывания, и пробежать по ним. Пользователь пробовал и это, и попиксельную подгонку X читом
[/]— не поднялось. Вывод для будущего разбора: состояние не чисто позиционное, одной шириной габарита его не объяснить; следующий подозреваемый — момент, в которыйprocess_trobsзастаёт модификатор относительно кадра Кида.
Наблюдение (пользователь, 2026-08-05). Уровень 2, комната 6, пики (1,3):
| действие | что происходит |
|---|---|
| длинный прыжок с ряда 0 на пики | смерть — правильно (путь fell_on_spikes) |
| пробег по ряду 1 прямо по пикам | урона нет |
| после уборки пик | на экране остаются белые остатки остриёв (в оригинале чисто) |
| прыжок на месте, стоя на пиках | урона нет |
| просто стоять на выдвинутых пиках | можно сколько угодно |
Замер (MAME, чтение room_modif комнаты 6). Пока Кид стоит на тайле,
модификатор пики (индекс 13) = 0x8E, то есть «пики ПОЛНОСТЬЮ вышли и
идёт обратный отсчёт». Дальше вся арифметика сходится с оригиналом:
is_spike_harmful (seg007:1178): 0/-1 → 0; <0 → 1; 1..4 → 2; >=5 → 0
check_spiked (seg006:0658): убивает при h>=2 на кадрах бега 7..14
и при h!=0 на кадрах приземления 43/26
То есть при h = 1 (пики уже вышли) бегущий не гибнет и в оригинале —
смертельно только окно ВЫДВИЖЕНИЯ (модификатор 1..4, h = 2). Наши
animate_spike, start_anim_spike, is_spike_harmful, check_spiked
сверены с seg006/seg007 построчно и совпадают дословно.
Значит расходится ТАЙМИНГ, а не логика: у нас пики успевают полностью
выйти ДО того, как Кид на них вбежит, и он проскакивает мимо смертельного
окна 1..4. Триггер — check_spike_below (seg006:1199), и у нас он берёт
габарит спрайта из kid_fp — метрик ПОСЛЕДНЕГО отрисованного кадра, а
оригинал берёт char_x_left/right ТЕКУЩЕГО кадра (set_char_collision).
Это первый подозреваемый; второй — момент вызова process_trobs
относительно play_frame (сколько кадров модификатор успевает пройти,
пока Кид добегает).
ВТОРОЕ НАБЛЮДЕНИЕ (то же место, сравнение с оригиналом) — оно и уточняет гипотезу. Кид уронил плиту-потолок и спрыгнул вниз; пики выдвинулись и «спрятались не все — часть артефактов осталась». Скриншоты рядом: наш и SDLPoP в той же позе. У нас из-под щебня торчат белые острия, у оригинала пик не видно ВООБЩЕ.
Это стыкуется с замером: пока Кид стоит рядом, check_spike_below каждый
кадр зовёт start_anim_spike, а тот при отрицательном модификаторе
переставляет его обратно в 0x8F — то есть пики у нас «залипают выдвинутыми»
и отсчёт до уборки не доходит. В оригинале в той же позе они убраны,
значит его check_spike_below эту колонку УЖЕ не задевает.
ГИПОТЕЗА «ТРИГГЕР СРАБАТЫВАЕТ РАНО» ПРОВЕРЕНА И ОПРОВЕРГНУТА (замер
2026-08-05, MAME, watchpoint на room_modif[13] комнаты 6). Чистый
пробег по УБРАННЫМ пикам убивает штатно:
запись modif=1 : кадр 11 (беговой), x=112, curr_col=2 ← пики пошли вверх
запись modif=2 : кадр 12 (беговой), x=117, curr_col=3 ← Кид уже НА тайле, h=2
запись modif=3 : кадр 177 (frame_177_spiked) ← напоролся
То есть 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 текущего кадра); если разойдутся позиции — это отдельный
баг посадки, а пики — его следствие.
Ручная перепроверка фиксов (2026-08-03)
Шесть корней закрыты автоматической проверкой в MAME (мост mame-z80:
чтение _Kid, потиковые трассы, скриншоты) — этого достаточно, чтобы
показать, что конкретный сценарий больше не воспроизводится, но НЕ
достаточно, чтобы поймать регрессии в соседней механике. Ниже — сценарии
ровно в тех формулировках, в которых баги были заведены.
Собрано и лежит в образе (make + make hdd уже прогнаны; libc пересобран,
make size-check без роста).
| # | что проверить | ожидаемо |
|---|---|---|
| 1 | комната 22: выпить зелье (0,6), выйти в 16/23 и вернуться | кувшина нет, пузырька над пустым местом нет |
| 2 | то же для комнат 14 (0,5) и 17 (2,3) | так же |
| 3 | комната 15: подобрать меч (2,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_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 |
| 11 | страж (комнаты 3, 21) убивает Кида | смерть доигрывается, респавн в стартовой позиции уровня; цикла «убил-воскрес» нет |
| 12 | клавиатура: долгая игра с Shift+стрелка | ↑ и Shift не залипают; осторожный шаг не превращается в бег (доработано во второй волне — п.17) |
Вторая волна (2026-08-03, вечер)
| # | что проверить | ожидаемо |
|---|---|---|
| 17 | [BUG-KBD-4] долго играть Shift+стрелка, много тапов подряд | Shift не «отваливается»; если однажды залипнет — снимается первым же нажатием стрелки |
| 18 | [BUG-RESPAWN-2] убить стража (комнаты 3/21), умереть, вернуться в ту же комнату | страж снова жив, стоит на исходном тайле, HP полные |
Отдельно стоит посмотреть на регрессии от порта check_collisions — он
трогает всю горизонтальную коллизию: бамп в стену на бегу и в прыжке,
осторожный шаг у стены, проход через ОТКРЫТЫЕ ворота, разворот в проёме
решётки, переходы через швы (старый BUG-SEAM-PINGPONG).
Открытые баги уровня 1
BUG-GATE-PASS-1. Проход сквозь закрывшуюся решётку — ЖДЁТ СЦЕНАРИЯ
Статус: наблюдался один раз, воспроизвести повторно НЕ удалось. Заведён, чтобы наблюдение не потерялось; закрывать нельзя — ни как исправленный, ни как «не баг», пока нет надёжного сценария.
Что наблюдалось (2026-08-03). Комната 5: Кид стоял НА тайле решётки (0,9) и ждал, пока она опустится. После закрытия пошёл вправо — прошёл в комнату 1 и упал на (1,1).
Что уже измерено и в чём загвоздка. Сразу после наблюдения повторить не
получилось: в том же месте Кид стоит на 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 пока не удалось, поэтому гипотеза НЕ подтверждена.
Что снять в следующий раз (без этих чисел вопрос не закрыть):
Kid.xиKid.curr_colв момент, когда решётка уже закрылась, а Кид ещё стоит на её тайле — до шага вправо;- модификатор решётки (openness) комнаты 5, тайл 9 —
can_bump_into_gate()считает её препятствием только пока(modif >> 2) + 6 < char_height, то есть пока она опустилась достаточно низко относительно РОСТА кадра; Kid.xпокадрово на самом шаге вправо — где именно перестал блокировать.
Быстрый способ снять первое: отладочный стоп-кадр (1 заморозить, 2
продолжить), затем чтение _Kid из отладчика MAME.
Возможный корень, если гипотеза не подтвердится. Проверка идёт по колонке,
которая на шве уже принадлежит СОСЕДНЕЙ комнате (curr_row_coll_room[] в
оригинале); у нас межкомнатная коллизия на шве — исторически проблемное место
(ср. закрытый BUG-SEAM-PINGPONG). Второй кандидат — char_height в
can_bump_into_gate(): если он берётся не от того кадра, решётка может
перестать считаться препятствием раньше времени.
Оптимизация отрисовки (записано 2026-07-29)
Не баги — план работ. Оба пункта про одно: у оригинала пометка тайла к перерисовке стоит копейки (бит в таблице, которая всё равно чистится каждый кадр), а у нас каждая такая пометка превращается в реальный heal (копию из ОЗУ-копии акселератора) плюс блиты. Поэтому буквальный порт «перерисовываем безусловно» корректен, но дорог.
T-1. Пики: перерисовывать по причине, а не безусловно
Сейчас: pop_process_trobs зовёт pop_spike_redraw каждый кадр для
каждой живой пики в комнате (порт redraw_21h, который animate_spike
вызывает вне всяких if). Это корректно, но лишнее для пик, до которых
Киду дела нет.
Надо: перерисовывать тайл пики, только если
- сменился её видимый кадр (шаг выдвижения/уборки), ЛИБО
- её кто-то стёр — а стереть у нас может только 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, отдельно не окупается.
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).
Обход всех 24 комнат уровня 1 — поиск багов отрисовки
Инструмент: #define ROOMNAV в roomtest.c — +/- (цифровой блок либо
=/- основного ряда) переключают комнату по номеру (1..24, с обёрткой),
Kid ставится на первый пол, pop_trob_reset() возвращает пики/ворота в
исходное. Номер комнаты — полосками в верхнем борте: слева десятки, справа
единицы (|| |||| = 24). Убирается закомментированием одной строки.
Комнаты 13, 18, 24 недостижимы в обычной игре — это свойство данных
уровня, разбор в bug_closed.md («НЕ БАГИ»). Приоритет
багов в них низкий.
Таблица заполнена на 5 строк из 24 — доделать в рамках L1-TRIAGE
(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_y−3), подъём по 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.cKBD_DBG_STEP*. Первый шаг в сторону = разворот (как в оригинале safe_step), движение со второго. - Читы (
pop_cheat.h): K — убить стража, I — бессмертие (toggle), S — выдать меч. - Респавн после смерти — по ↑ (или авто через
RESPAWN_DELAY); ставит Kid в стартовую позицию УРОВНЯ (pop_start_level, порт do_startpos). - ROOMNAV (
=/-) — тоже наш чит, которого в оригинале не было, как иS. Все они со временем съедутся в общий блок читов, разрешаемый в настройках; пока просто включены (pop_cheats = 1вroomtest.c).
Сырые наблюдения (прогон 2026-08-03) → корень
Формулировки с прогона, как записаны. Закрытые корни — в
bug_closed.md.
| # | наблюдение (кратко) | корень | статус |
|---|---|---|---|
| 1 | кувшин выпит, а пузырёк рисуется / кувшин возвращается (14, 22, 17) | BUG-LVLSTATE-1 | закрыт |
| 2 | меч возвращается в 15 / мигает контур кладки | BUG-LVLSTATE-1 | закрыт |
| 3 | комната 12: пробегает сквозь закрытую решётку (0,9) | BUG-COLL-1 | закрыт |
| 4 | после respawn плиты остаются разбитыми, зелья выпитыми | BUG-RESPAWN-1 | закрыт |
| 5 | плита/зелье возвращаются и БЕЗ respawn (12→16, 17, 22) | BUG-LVLSTATE-1 | закрыт |
| 6 | комната 6: длинный прыжок (0,6)→(0,7) — влёт в стену, респавн | BUG-COLL-1 | закрыт |
| 7 | залипает ↑ | BUG-KBD-3 | закрыт (см. bug_closed.md) |
| 8 | залипает Shift | BUG-KBD-3 / BUG-KBD-4 | закрыт (см. bug_closed.md) |
| 9 | комната 5: кнопка (0,4) не открывает решётку (0,5) | BUG-GATE-ANIM-1 | закрыт |
| 10 | комната 5: с кнопки (0,6) на (2,7), присед — провал в комнату 6 | BUG-STANDUP-1 | закрыт |
| 11 | страж убил Кида → Кид воскресает на месте и его убивают снова | BUG-DEATH-1 | закрыт |