Приёмка ур. 2–3: сквозь стену, клин в шве, бар под плитой, глухой страж
Четыре разбора с прогонов пользователя; три бага закрыты, четвёртый (BUG-SPIKE-1, пики) заведён с замером и гипотезой. BUG-JUMPWALL-1 (Critical) — недолетевший прыжок проходил СКВОЗЬ стену. check_collisions держал флаги перекрытия ОДНОГО ряда, а оригинал (seg004:0004) — трёх, и move_coll_to_prev (seg004:00DF) берёт «прошлые» флаги из нужного. Наш prev=3 («уже перекрывал») подавлял бамп ровно на кадре смены ряда, а в падении ряд меняется почти каждый кадр — переход 0→1 на стене приходился как раз на него. Порт трёх рядов дословно. Воспроизведено и закрыто на харнессе (новый набор t_wall: свип по 20 стартовым X, 4 давали проход сквозь кладку); 1723 трассы t_phys НЕ изменились — правка поведение-сохраняющая. Живьём подтвердил пользователь. BUG-GUARD-DEAF-1 (Major) — is_guard_notice не взводился НИГДЕ, поэтому неактивный страж не оборачивался на Кида за спиной никогда. Портированы все пять мест оригинала: опкод SOUND в play_seq (звуки 0..2), bumped_sound, мягкое/среднее приземление, обрушенная плита, щелчок кнопки. Ждёт игровой проверки боем в комнате 11 уровня 2. BUG-SEAM-WEDGE-1 — клин кладки в пустом (2,0). Сосед угла снизу-слева лежит в комнате по диагонали (room_BL); мы безусловно считали его стеной, оригинал (load_rowbelow, seg008:368) — только когда такой комнаты нет. Ряд «снизу» стал 11-байтным: [10] = тайл (0,9) диагональной комнаты. BUG-LOOSE-3 — чёрный бар под упавшей плитой-потолком. pop_ceil_bake_empty стирал полосу и восстанавливал только два тайла ряда −1, а в полосу лезет графика соседа слева и верхушки ряда 0. Теперь перерисовываются ряды −1 и 0, колонки col−1..col+1. Проверено попиксельной сверкой с эталонной перерисовкой: 0 различий. Плюс карта связности комнат уровней 1–3 (TASKS.md): на ур. 2 недостижимых нет, на ур. 3 это 23 и 24 — те же односторонние ссылки, что дали 13/18/24 на уровне 1, только комнаты полностью пустые. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,99 @@
|
||||
|
||||
---
|
||||
|
||||
## BUG-JUMPWALL-1. Недолетевший прыжок проходил СКВОЗЬ стену — **ЗАКРЫТ 2026-08-05**
|
||||
|
||||
**Симптом (пользователь, приёмка уровня 3).** Комната 14: Кид на (0,8)
|
||||
лицом влево, прыжок с места — пролетает сквозь кладку и падает в комнату 13
|
||||
на (2,3). Обобщение пользователя (оно и оказалось верным): «если Кид
|
||||
прыгает, недолетает и должен врезаться в стену и упасть ВДОЛЬ неё, у нас он
|
||||
летит по свободной траектории, как будто ему никто не мешает».
|
||||
|
||||
**Корень — упрощение в `check_collisions`, про которое там же стояла
|
||||
оговорка.** Оригинал (seg004:0004) каждый кадр считает флаги перекрытия для
|
||||
ТРЁХ рядов (`curr`/`above`/`below`), а `move_coll_to_prev` (seg004:00DF) в
|
||||
начале следующего кадра выбирает из них тот, что соответствует ряду прошлого
|
||||
кадра. Так «прошлые» флаги остаются настоящими и на кадре СМЕНЫ РЯДА.
|
||||
|
||||
У нас ряд был один, и на смене ряда `prev` заполнялся тройками («уже
|
||||
перекрывал всё»), что подавляло бамп на этом кадре. В падении ряд меняется
|
||||
почти каждый кадр, а переход флага 0→1 на стене приходится ровно на него —
|
||||
поэтому удар не регистрировался и `bumped_fall` (который и гасит `fall_x`)
|
||||
не вызывался.
|
||||
|
||||
**Как ловили.** Не в MAME, а на харнессе: набор
|
||||
[`tests-host/t_wall.c`](tests-host/t_wall.c) — комната 14 уровня 3 с
|
||||
подложенным дном шахты, свип по всей ширине стартовой плиты (x = 177..196).
|
||||
Из 20 стартовых позиций 4 давали проход сквозь кладку (Кид оказывался в
|
||||
колонке 4 при стене в колонке 5). Первый вариант сценария (одна стартовая
|
||||
X, из центра плиты) БАГА НЕ ПОКАЗАЛ — отсюда свип.
|
||||
|
||||
**Фикс.** Три ряда как в оригинале + дословный `move_coll_to_prev`
|
||||
(включая условия ±3 на заворот ряда при смене комнаты). Цена — 3×14
|
||||
`get_tile` на кадр вместо 14, банк 3 +115 Б.
|
||||
|
||||
**Чем проверено.** `t_wall` зелёный; **все 1723 существующие трассы
|
||||
`t_phys` не изменились ни на байт** — правка поведение-сохраняющая для
|
||||
всего остального. В живой игре подтвердил пользователь: «ударились и
|
||||
падаем вертикально вниз».
|
||||
|
||||
---
|
||||
|
||||
## BUG-SEAM-WEDGE-1. Клин кладки в пустом углу (2,0) — **ЗАКРЫТ 2026-08-05**
|
||||
|
||||
**Симптом (пользователь, приёмка уровня 3).** Комната 18: в тайле (2,0)
|
||||
нарисован кусок кладки, хотя по данным там пусто.
|
||||
|
||||
**Корень.** У тайла (2,0) «сосед снизу-слева» — это колонка −1 ряда 3, то
|
||||
есть тайл ЧУЖОЙ комнаты (`room_BL` — левая от нижней). `load_rowbelow`
|
||||
(seg008:368) резолвит его через `get_tile_to_draw(room_left, 9, 0, …)` и
|
||||
подставляет стену ТОЛЬКО когда такой комнаты нет. Мы клали стену
|
||||
безусловно, а `draw_topright` для стены рисует угловой кусок — он и был
|
||||
клином. Для комнаты 18 диагональ — комната 13, её тайл (0,9) пуст, значит
|
||||
рисовать нечего.
|
||||
|
||||
**Фикс.** Ряд «снизу» стал одиннадцатибайтным: `[0..9]` — колонки комнаты
|
||||
снизу, `[10]` — тайл (0,9) комнаты снизу-слева (дефолт «стена», если её
|
||||
нет). Затронуты `pop_level.c` (заполнение), `pop_bg.c` (чтение),
|
||||
`roomtest.c` (размер массива).
|
||||
|
||||
**Проверено** в MAME: комната 18 уровня 3, клина нет.
|
||||
|
||||
---
|
||||
|
||||
## BUG-LOOSE-3. Чёрный бар под упавшей плитой-потолком — **ЗАКРЫТ 2026-08-05**
|
||||
|
||||
**Симптом (пользователь, приёмка уровня 2).** Комната 6: Кид сбивает
|
||||
плиту-потолок (−1,2) — плита падает, но на её месте остаётся чёрный бар.
|
||||
Два уточнения пользователя оказались диагностическими:
|
||||
|
||||
1. «бар попал в фоновое изображение» — Кид прыгает поверх, уходит, бар
|
||||
остаётся → чернота лежит в ОЗУ-копии, и heal возвращает её каждый кадр;
|
||||
2. «когда возвращаемся в комнату после выхода — бара нет» → статическая
|
||||
отрисовка комнаты рисует всё правильно, виновата ЗАПЕЧКА.
|
||||
|
||||
**Корень.** `pop_ceil_bake_empty` стирал полосу потолка чёрной плитой
|
||||
(`bar`, банк NORMAL — пишет и в ОЗУ-копию) шириной 64 px, а восстанавливал
|
||||
только ДВА тайла ряда −1: `(−1,col)` и `(−1,col+1)`. Но куски тайлов
|
||||
рисуются ВВЕРХ от своей нижней грани и свисают ВПРАВО, поэтому в стёртую
|
||||
полосу попадает графика и соседа СЛЕВА, и тайлов ряда 0 — их верхушки.
|
||||
Незакрашенным оставался прямоугольник ~13×3 px.
|
||||
|
||||
**Замер (он же метод).** Плита роняется без игры — записью
|
||||
`pop_ceil_modif[col] = 1` в отладчике MAME (это ровно то, что делает
|
||||
`make_loose_fall` для потолка). Дальше попиксельная сверка скриншота
|
||||
«после запечки» со скриншотом «комната перерисована заново» (выйти и
|
||||
вернуться): различие локализовалось в прямоугольник **экранные x 230..255,
|
||||
y 47..52** при полосе потолка y 44..52.
|
||||
|
||||
**Фикс.** Запечка восстанавливает всё, чья графика попадает в полосу:
|
||||
ряды −1 И 0, колонки `col−1..col+1`.
|
||||
|
||||
**Проверено:** та же попиксельная сверка после фикса даёт **0 различий** в
|
||||
полосе; пользователь подтвердил в игре.
|
||||
|
||||
---
|
||||
|
||||
## BUG-RJUMP-1. Разбег-прыжок не берёт провал в три тайла — **ЗАКРЫТ 2026-08-04**
|
||||
|
||||
**Симптом (пользователь, приёмка уровня 2).** Комната 1: Кид с разбегу
|
||||
|
||||
Reference in New Issue
Block a user