From 400f5cba633c3524e1d3388f7cb681b37d3f8e3f Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Wed, 2 Sep 2026 17:41:07 +0300 Subject: [PATCH] =?UTF-8?q?SprPoP:=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B2=20CLIMB-VS-GUARD=20=E2=80=94=20=D0=B7?= =?UTF-8?q?=D0=B2=D1=83=D0=BA=2011=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B8=D1=82?= =?UTF-8?q?=20=D0=9F=D0=A0=D0=9E=D0=9C=D0=90=D0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В записи стояло, будто оригинал играет звук 11 «сразу на кадре укола, ДО проверки расстояния», то есть при ЛЮБОМ уколе, попал тот или нет. Это было описание НАШЕГО кода, а не SDLPoP: ровно так звук у нас и стоял — внутри ветки «не парировано» и до присвоения Opp.action = 99_hurt (снято предыдущим коммитом). Классическое нарушение правила «источник истины — SDLPoP»: за оригинал приняли собственную реализацию, и вывод из неё уехал в доску как факт. На деле звук 11 в оригинале защищён условием Opp.action != 99_hurt, то есть звучит ТОЛЬКО на промахе: на попадании играет боль, на парировании Opp.frame уже 161. Что это меняет для самого бага: - УЦЕЛЕЛО наблюдение «в оригинале 11, у нас 8» — это данные. Арифметика приоритетов их подкрепляет: snd_prio[11] = 0x12 против snd_prio[8] = 0x4B (меньше значит важнее), взмах не мог быть заглушён упором в стену. - ОТПАЛ вывод «оригинал ведёт стража атакой с промахом, а мы — столкновением»: он опирался на неверную посылку. - УСИЛИЛАСЬ версия про ПОРОГ ДИСТАНЦИИ: раз в оригинале слышен именно 11, укол у стража СОСТОЯЛСЯ и ПРОМАЗАЛ. Прежняя «версия про столкновение» вытеснила дистанцию зря — возвращаем её в главные подозреваемые. Отдельно предупреждение тому, кто вернётся к багу: диагностика по звуку теперь значит другое, старые заметки прогона будут вводить в заблуждение, сцену надо переснимать. Положена таблица соответствий (11 = промах, 13 = попадание, 8 = столкновение, тишина = ранний выход из check_hurting). На механику урона правки не влияют — расхождение «удар убивает» остаётся открытым как было. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018T2k4VZrSyERwk6H97Sfi1 --- applications/SprPoP/docs/BUGS_OPEN.md | 68 +++++++++++++++++++++------ 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/applications/SprPoP/docs/BUGS_OPEN.md b/applications/SprPoP/docs/BUGS_OPEN.md index a17ae37..5bd5f4a 100644 --- a/applications/SprPoP/docs/BUGS_OPEN.md +++ b/applications/SprPoP/docs/BUGS_OPEN.md @@ -38,7 +38,7 @@ | [SND-PACE-DEAD](#snd-pace-dead) | пейсинг сцен по насосу CBL не включается: признак «часы идут» вычисляется двумя чтениями подряд | **тайминг/звук** | **снят 2026-08-28**: ветка удалена, сцена на единых часах по лучу | | [PV-RENDER-BOUND](#pv-render-bound) | сцена с принцессой рисуется дороже бюджета: ~49 тиков/с вместо 60, музыка уезжает от картинки | производительность | **исправлено 2026-08-28**: кадр разложен на блоки по интервалу, удешевлять не понадобилось | | [MUS-LEFT-TEAR](#mus-left-tear) | `pop_mus_left` (16 бит, пишет прерывание) читается из главного цикла неатомарно — возможен ложный «трек кончился» | **потенциальный** | открыт: хазард показан рассуждением, в прогоне не проявился | -| [CLIMB-VS-GUARD](#climb-vs-guard) | Кид подтягивается к стражу этажом выше: у нас удар засчитывается и убивает, в оригинале Кид просто срывается без урона; страж при этом способен провалиться сквозь пол вслед за Кидом | бой/физика | открыт: цепочка удара сверена — совпадает, расходятся входные данные (2026-08-31) | +| [CLIMB-VS-GUARD](#climb-vs-guard) | Кид подтягивается к стражу этажом выше: у нас удар засчитывается и убивает, в оригинале Кид просто срывается без урона; страж при этом способен провалиться сквозь пол вслед за Кидом | бой/физика | открыт: цепочка удара сверена — совпадает, расходятся входные данные; толкование звука ИСПРАВЛЕНО 2026-09-02 (звук 11 = промах, а не «любой укол») — главный подозреваемый снова ПОРОГ ДИСТАНЦИИ | | [HP-BAR-RESTART](#hp-bar-restart) | после гибели и Ctrl+A на ОДНОЙ из двух страниц остаётся полоса HP по результатам боя | дабл-буфер/UI | КОРЕНЬ НАЙДЕН, фикс есть, ждёт проверки (2026-08-31) | --- @@ -1374,23 +1374,63 @@ uint16_t pop_music_left(void) { uint16_t a, b; В той же сцене оригинал играет ВЗМАХ (звук 11, «клинок движется»), а у нас слышен звук, похожий на упор Кида в стену (звук 8, `bumped`). -Почему это важно. Звук 11 оригинал играет в `check_hurting` СРАЗУ на -кадре укола — ДО проверки расстояния и до отметки «ранен». То есть он -звучит при ЛЮБОМ уколе, попал тот или нет. Значит его отсутствие -означает не «промахнулись», а «до укола дело вообще не дошло»: страж не в -кадре укола, либо разбор вышел раньше (меч не вынут / ряды не совпали). -А звучащий вместо него упор в стену говорит, что у нас сработало -СТОЛКНОВЕНИЕ, а не атака. - Набор звуков проверен и НЕ виноват: в `assets/packed/SND/snd.idx` слот 11 на месте и содержит собственный короткий сэмпл (1280 Б), слот 8 — другой (1664 Б). Раскладка не сдвинута. -Отсюда рабочая версия: в этой связке оригинал ведёт стража по ветке -«атака с промахом», а мы — по ветке «столкновение с персонажем» -(`bump_into_opponent` / `check_bumped`). Это же объясняет и провалившегося -сквозь пол стража: столкновение двигает его координату, а не атака. -Проверять надо ветку выбора действия стража, а не только дистанцию. +**ПОПРАВКА 2026-09-02 — прежнее толкование звука было ОШИБОЧНЫМ.** + +Здесь стояло, будто оригинал играет звук 11 «сразу на кадре укола, ДО +проверки расстояния», то есть при ЛЮБОМ уколе, попал тот или нет. Это +описание НАШЕГО кода, а не оригинала: ровно так звук стоял у нас, внутри +ветки «не парировано» и до присвоения `Opp.action = 99_hurt`. В SDLPoP +(seg002:1039..1044) он стоит в ХВОСТЕ `check_hurting` и защищён условием +`Opp.action != actions_99_hurt`: + + if (Char.direction == dir_56_none) return; // Fix looping "sword moving" sound. + if (Char.frame == frame_154_poking && Opp.frame != frame_161_parry && + Opp.action != actions_99_hurt) + play_sound(sound_11_sword_moving); + +То есть звук 11 в оригинале — это индикатор **ПРОМАХА**, а не укола: на +попадании его нет (играет боль), на парировании нет (`Opp.frame` уже 161). +Расхождение найдено и исправлено 2026-09-02 по симптому «непрерывный взмах +клинка у безоружного Кида на подъёме» (звук опознан в живой сессии по +`snd_curr == 11`; указатели насоса при этом сошлись с `snd.idx` байт в +байт, то есть тракт звука был исправен). Заодно приехал и пропущенный +ранний выход по `dir_56_none` — тот самый, что автор SDLPoP подписал +«Fix looping sword moving sound». + +**Что из прежних выводов уцелело, а что нет.** + +* УЦЕЛЕЛО: наблюдение «в оригинале слышен 11, у нас 8» — это данные, и они + остаются. Арифметика приоритетов их подкрепляет: `snd_prio[11] = 0x12` + (18) против `snd_prio[8] = 0x4B` (75), меньше значит важнее, поэтому + взмах не мог быть заглушён упором в стену. При ТОГДАШНЕМ коде звук 11 + звучал на любом уколе, значит его отсутствие действительно означало, что + до кадра укола дело не дошло. +* ОТПАЛО: вывод «оригинал ведёт стража атакой с промахом, а мы — + столкновением» опирался на неверную посылку и больше не следует из звука + сам по себе. +* УСИЛИЛОСЬ: то, что в оригинале в этой сцене слышен ИМЕННО 11, теперь + доказывает, что укол у стража СОСТОЯЛСЯ и ПРОМАЗАЛ. А это ровно версия + про ПОРОГ ДИСТАНЦИИ (см. выше про пару пикселей и нижний порог 8), а не + про потерянную ветку. Прежняя «версия про столкновение» её вытеснила + зря — возвращаем дистанцию в главные подозреваемые. + +**ВНИМАНИЕ тому, кто вернётся к этому багу: диагностика по звуку с +2026-09-02 ЗНАЧИТ ДРУГОЕ.** Старые заметки прогона будут вводить в +заблуждение — переснимать сцену заново. Новая таблица: + +| слышно | что это значит | +|---|---| +| 11 (взмах) | укол состоялся и ПРОМАЗАЛ — поведение оригинала в этой сцене | +| 13 (боль Кида) | укол ПОПАЛ, `Opp.action = 99_hurt` | +| 8 (упор в стену) | укола не было вовсе, сработало столкновение | +| тишина | `check_hurting` вышел раньше: меч не вынут / ряды не совпали / кадр не 153-154 | + +На саму механику урона правка 2026-09-02 НЕ влияет (тронут только звук), +поэтому расхождение «удар убивает» остаётся открытым как было. **Решение пользователя:** отложено на будущее (2026-08-31) — поведение в этой связке расходится широко, чинить нужно целиком, а не по одному