Бычков Андрей andrey
  • Joined on 2020-04-23
andrey pushed to main at andrey/fishing-game 2026-09-24 22:25:10 +03:00
ad079b08f3 Инструмент: релизная сборка tools/minify.mjs (index.html −35%). (1) Методы: JS — terser compress passes:2 + mangle.toplevel:false (глобалы из буллета «Подводные камни» держатся именами — артефакт прогоняется обычной тестовой суитой); CSS — csso в каждом <style> КРОМЕ блока EMOJI-FONT (base64 woff2 держится побайтово, csso мог бы перенормировать кавычки); FISH-SVG — вырезаны HTML-комменты (~50 КБ описаний анатомии) и whitespace между тегами (в SVG текст-ноды не рендерятся — безопасно); прочие HTML-комменты — кроме маркеров EMOJI-FONT/FISH-SVG BEGIN/END (нельзя: whitespace внутри отрицательного lookaхeda, иначе <!-- EMOJI-FONT:BEGIN съедался бэктреком); whitespace DOM — только между блок-тегами (div/section/… + canvas/svg), inline-текст и пробелы между <b>…</b> и словом не трогаются. (2) Самопроверка 6 пунктов при любом FAIL exit 1: (a) размер, (b) node --check вынутого JS (паттерн tools/check.mjs), (c) маркеры по одному, (d) набор id идентичен (104), (e) видимый текст DOM идентичен, (f) блок EMOJI-FONT побайтово. (3) Артефакт dist/index.release.html: 541029 → 349886 байт (−35,3%), gzip 183366 → 128565; разбивка релиза: JS 112 КБ, SVG 120 КБ, шрифт 93 КБ, CSS 18 КБ, DOM ~5 КБ. (4) Валидация: ПОЛНАЯ тестовая суита на самом артефакте (подставлен под index.html) — 222/222 PASS, exit 0, headless Chromium. (5) Зависимости tools/: terser 5.51.2 + csso 5.0.5 (package.json + package-lock.json, npm i --prefix tools; tools/node_modules не коммитится — .gitignore +node_modules/, заодно прикрыл tests/node_modules). (6) index.html, balance, тесты, скриншоты НЕ тронуты. Доки: README (секция «Релизная (уменьшенная) сборка» в «Публикация в Яндекс Играх»), AGENTS.md (пункт 6 в «Проверка»: команда + методы + обязательный прогон tests/test.js на артефакте перед публикацией).
andrey pushed to http_auth at SHS/pip 2026-09-24 11:49:45 +03:00
64a9fc3dae more gtests and fix piauth
9e663a7501 test: add HTTPS/TLS coverage for HTTP server with PIHTTPClient
Compare 2 commits »
andrey pushed to main at andrey/fishing-game 2026-09-23 18:03:18 +03:00
7437240cae Этап 48: размер рыбы в аквариуме — от абсолютного веса (общая шкала вываживания) + десктоп ×2. (1) aqFishSize(sp,w) → aqFishSize(w): вместо w/wMax+rarity читает общую с drawHookedFish кривую Этапа 41 — fishSizeFromW(w) (узловая таблица FISH_SIZE_KNOTS, log2 веса) — так «крупнее вес → крупнее рыба» работает в банке как в воде. Формула: clamp(fishSizeFromW(w)·AQ_FISH_SCALE·k, AQ_FISH_SIZE_MIN·k, min(W,H)·AQ_FISH_SIZE_REL·k); константы AQ_FISH_SCALE=0.7, AQ_FISH_SIZE_MIN=7, AQ_FISH_SIZE_REL=0.16. (2) Ревизия по просьбе владельца: мобильный вид одобрен как есть, поэтому десктопный множитель k=AQ_DESKTOP_SCALE=2 включается только при min(W,H)>=AQ_DESKTOP_MIN=600 (иначе k=1) — телефон 390×844 и mobile-landscape 800×450 остаются 1×, десктоп 1280×720 получает жильцов вдвое крупнее (щука 7.4 кг: 40→79 px DOM, кит 100 кг: 125→293 px). Оба клампа (MIN и REL) масштабируются на k вместе с телом — иначе на десктопе мелкая рыба застревала бы на мобильном минимуме, а верхний кламп резал бы увеличенных гигантов. Порог по min(W,H), а не IS_TOUCH: не ломает headless-скриншоты и работает при resize (initAquarium). (3) Обновлены 3 вызова — aqBuildFishEl/drawAquarium/aqTap (sp больше не нужен как аргумент; в drawAquarium sp остался для sp.glow); радиус тапа (size*1.2+10), рамка выбора и ореол свечения читают ту же size — согласованы автоматически. Таблицу/кривую НЕ дублируем (fishSizeFromW объявлен в «ОТРИСОВКА» раньше секции аквариума). Имя aqFishSize сохранено (глобал тестов/AGENTS). (4) Не тронуто: FISH_SIZE_KNOTS/fishSizeFromW/drawHookedFish (вода), wMin/wMax, формат/миграция save.aqFish, баланс/роллы/физика. (5) Тесты не правились — §AQ размеры не пинит (проверяются .aqfish/use href/варианты/transform; aqTap жмёт центр): 222/222 PASS, exit 0. check.mjs OK; balance.mjs — пины без изменений (Река 65.1/125.9 · Озёра 194.1/249.0 · Болото 240.3/328.9 · Море 297.3/476.7 · Океан 329.1/552.7). (6) Скриншоты: перегенерированы только кадры aquarium (6 PNG, оба набора — паттерн ревизии Этапа 47); остальные 84 кадра возвращены (набор не побитово-детерминирован из-за анимаций). (7) Доки: AGENTS.md (пункт «Аквариум» — формула + константы + десктоп-множитель), README.md (размер по весу, на десктопе ×2), DEVLOG (Этап 48 с таблицей мобильный/десктоп).
0a0595c3c1 Этап 47: ревизия SVG-портретов рыб — детализация до уровня болотных + биологическое правдоподобие. (1) Полная перерисовка 32 портретов, кроме 5 болотных (эталон стиля, Этап 45): 8 речных (carass, perch, bream, carp, pike, catfish, sturge, gold), 10 озёрных (zander, chuch, crayfish, bleak, roundel, eelpout, tench, navaga, rudd, cisco), 5 морских (herring, mackerel, flounder, tuna, swordfish), 9 океанских (moray, grouper, turtle, angler, octopus, manta, shark, squid, whale). (2) Единый стиль: послойные заливки без градиентов/defs (--f1 тело, --f3 плавники — перекрашиваются вариантами; --f2 брюхо/светлое, --f4 тёмный узор/кромка — НЕ перекрашиваются), спинная кромка f4-серпом, жаберная пластина+дуга, глаз 5 кругов (ободок→склера→радужка фикс-hex→зрачок→блик), составные узоры (полосы/пятна/чешуя/жучки/финлеты) — одним compound-path, ≤38 элементов, фикс-hex-акценты разрешены. (3) Видовые отличия и разведение «двойников»: карась↔карп (усы), окунь↔судак (горб/полосы/красное vs косая полоса/клыки), лещ↔густера (длинная анальная «юбка» vs короткий анальный+крупный глаз+киль), плотва↔краснопёрка (красный vs жёлтый глаз, рот конечный vs вверх), сом↔вьюн (голова-¼/длинные усы vs лента/10 усиков), мурена↔вьюн, осьминог↔кальмар (мешок+8 равных рук vs мантия-ракета+2 ловчих+крылышки), кит↔акула (флоскулы/фонтан/ус vs треуг. D/гетероцерк/5 щелей), сельдь↔скумбрия↔тунец↔меч, манта↔камбала↔рак, черепаха (вид сверху). (4) «Не рыбы»: crayfish (рак, вид сверху, клешни/ноги/веер), turtle (черепаха, вид сверху, щитки/4 ласты/клюв), octopus/squid/whale — иная анатомия (присоски/ловчие щупальца/флоскулы/фонтан), допустимые отклонения от рыбьего протокола. (5) Двойные боссы sturge (Река) и whale (Океан) проверены под золотой аурой #card.boss-card — контраст держат f4-детали. (6) Дефекты, найденные на приёмке и исправленные точечно (композиция не менялась): octopus — 2 щели с фоном; swordfish — светлый стык голова↔меч; tuna — прозрачная «дыра» в выемке хвоста-полумесяца; grouper — щель пасть↔нижняя челюсть; angler — просвет между римом и эской. (7) viewBox (0 0 160 100) и id/имена файлов не менялись; данные/логика/баланс не тронуты. (8) Интеграция: node tools/embed-fish.mjs — блок FISH-SVG обновлён (202478 байт / 1512 строк, 37 symbol); проверено совпадение всех 37 symbol с текущими assets/fish/*.svg; tools/fish-preview.html — блок «Варианты» (8 инлайн-копий carass синхронизированы с источником) + секция «Читаемость в UI» (44×28 / 40×26 / 240×150). Тесты не правились: 222/222 PASS, exit 0; check.mjs OK; balance.mjs — пины без изменений (Река 65.1/125.9 · Озёра 194.1/249.0 · Болото 240.3/328.9 · Море 297.3/476.7 · Океан 329.1/552.7). Скриншоты перегенерированы (45 RU + 45 EN). Доки: DEVLOG Этап 47.
e0ba750568 Доки: убрать все упоминания KODA.md (файл удалён — используется только AGENTS.md).
Compare 3 commits »
andrey pushed to http_auth at SHS/pip 2026-09-23 09:02:10 +03:00
6bf50344fd fix: harden PIHTTPServerSessionAuth session table
e1a24a98f7 fix: accept case-insensitive Basic scheme and guard HTTP test target
Compare 2 commits »
andrey pushed to http_auth at SHS/pip 2026-09-23 08:29:37 +03:00
994cf64838 feat: add optional sliding idle timeout to PIHTTPServerSessionAuth
2f63a49c69 refactor: make PIHTTPServerSessionAuth own sessions only, delegate credentials
78fbebe6b0 fix: accept case-insensitive Bearer scheme in HTTP server
Compare 3 commits »
andrey pushed to main at andrey/fishing-game 2026-09-22 23:02:08 +03:00
a168e830cc Этап 46 ревизия: жильцы аквариума — те же SVG-портреты, что на карточке улова. (1) Слой #aqFishLayer (body, после canvas): position:fixed/inset:0/z-index:5/pointer-events:none, включается только под сценой (body.aq-open) — тапы по рыбам по-прежнему ловит canvas (aqTap). (2) aqBuildFishEl(i) — <div class=aqfish><svg viewBox="0 0 160 100"><use href="#fish-<id>"/></svg></div>, тот же спрайт FISH-SVG, что у дневника/карточки; размер от прежнего aqFishSize (длина 2·size, высота по 160:100); aqPlaceFish(el,rt) каждый кадр из updateAquarium ставит translate(x,y)+translate(-50%,-50%)+rotate(±4° по tail)+scale(dir,1). (3) Вариант — 1:1 с карточкой: перекраска --f1/--f3 inline (AQ_VARIANT_RECOLOR, цвета из CSS #card.<variant>-card) + класс .var<id> (AQ_VARIANT_CLASS/aqApplyVariant; silver — grayscale+brightness, rainbow — aqrainbowhue, остальные — цветной drop-shadow). Вместо hue-хака AQ_VARIANT_FX/AQ_VARIANT_HUE (удалены) и прежней искры. (4) initAquarium() пересобирает слой с clip-path по банке (index aqFishEls = index save.aqFish, битый вид → null без сдвига индексов); aqReleaseSel() удаляет DOM-элемент точечно (без телепорта остальных); на canvas остались вода/грунт/растения/пузыри/стекло + аура болотных (уходит ЗА портрет) и рамка выбора. drawFishShape в банке больше не используется (в сценах ловли не тронут). Геймплей/баланс/сейв/экономика не менялись. (5) Тесты 218→222: блок «портреты» в §AQ (use href = #fish-<id> на каждый экземпляр; .var<id>/--f1 по варианту; transform следует за aqFishRt индекс-в-индекс; вне сцены display:none/body без aq-open, pointer-events:none) + обновлён список глобалов в шапке §AQ. (6) Скриншоты: перегенерированы только кадры aquarium (6 PNG, оба набора). (7) Доки: AGENTS.md (пункт «Аквариум» + глобалы), KODA.md (код-карта/глобалы/грабли), README.md, docs/PLAN-AQUARIUM.md (риск №1 закрыт), DEVLOG (подраздел «Ревизия Этапа 46»). Проверено: 222/222 PASS exit 0, check.mjs OK, balance.mjs — пины без изменений (Река 65.1/125.9 · Озёра 194.1/249.0 · Болото 240.3/328.9 · Море 297.3/476.7 · Океан 329.1/552.7), pack.mjs 5/5 + pack-smoke 6/6.
andrey pushed to main at andrey/fishing-game 2026-09-22 21:34:25 +03:00
3d7a67c957 Этап 46: Аквариум — сцена коллекции на главном canvas (не локация, баланс не тронут). (1) Данные: save.aqFish[] {id,v,w} + save.aqSlots (старт AQ_BASE_SLOTS=6, макс AQ_MAX_SLOTS=12), AQ_SLOT_COSTS=[1500,4000,9000,20000,45000,100000]; миграция loadSave() — фильтр id по SPECIES, Number.isFinite(w)&&w>0, вариант→'normal', Math.trunc+клампы aqSlots, обрезка хвоста. (2) Модель C: catchFish() не изменён (пины/квесты/ачивки/реклама не тронуты); #btnKeep '🐠 В аквариум' на карточке — бесплатная КОПИЯ (cardSpec/syncKeepBtn, disabled+«Нет места» при лимите), persist+checkAchievements+тост+закрытие+tryInterstitial. (3) Сцена: секция АКВАРИУМ (aqOpen/aqFishRt/aqSel=-1/aqTank), initAquarium/updateAquarium/drawAquarium (вода hexLerp по nightMix, грунт/растения/пузыри, drawFishShape+подкраска варианта AQ_VARIANT_FX/HUE, свечение болотных drawGlowAura), точки frame/draw/onDown(px,py)/resize/syncDom; вход #btnGmAquarium из #gamemenu (openAquarium/closeAquarium, паттерн fromMenuShop), бар #aqBar (#btnAqBack/#aqCount/#btnAqSlot) с pointer-events:none+пилюли auto, поповер #aqPop (вес·редкость, без цены). (4) «Выпустить» #btnAqRelease→aqReleaseSel(): точечное удаление БЕЗ монет/earned/questHit (решение владельца: продажа из банки удалена — закрывает луп ×2 дохода модели C), без телепорта сцены (позиции остальных сохраняются); aqValue() удалён. (5) HUD под сценой: body.aq-open (syncDom+open/close) прячет #hud — клик по #coins/#btnShop из банки невозможен (находка ревью). (6) Слоты: #btnAqSlot по AQ_SLOT_COSTS, sfx('no')+not_enough, disabled на максимуме, гард Number.isFinite(cost). (7) Ачивки 36→38: aq_first 'Первый жилец'/aq_full 'Аквариум полон', обе bonus:{} — пин achBonus().coinPct=0.18 не сдвинут. (8) i18n: gm_aquarium/aq_title/aq_keep/aq_back/aq_slots/aq_buy_slot/aq_max/aq_release/aq_released/aq_no_room/aq_kept (RU/EN), setLang→renderAqBar. (9) Emoji: 🐠 U+1F420 во встроенный субсет (53 глифа, --check OK). (10) Тесты 204→218: блок 'Этап 46' (14 проверок: данные/миграция битых/keep id-v-w/модель C/лимит/сцена вход-выход/слот/выпуск без монет/телепорт), pин a22d 36→38+noCoinBonus. (11) Скриншоты: gen-screenshots.js +кадр aquarium (14→15 × 3 вьюпорта), RU+EN по 45 PNG (EN-набор приведён в синхрон: +swamp/aquarium). (12) Доки: AGENTS.md (пункт 'Аквариум', глобалы, 38 ачивок, 15 кадров, 218 тестов), KODA.md, README.md, DEVLOG (Этап 46), PLAN-AQUARIUM.md (статус 'реализован' + заметка о замене продажи на выпуск). Проверено: 218/218 PASS exit 0, check.mjs OK, emoji --check OK, balance.mjs — пины без изменений (Река 65.1/125.9 · Озёра 194.1/249.0 · Болото 240.3/328.9 · Море 297.3/476.7 · Океан 329.1/552.7), pack.mjs 5/5 + pack-smoke 6/6, ревью @oracle — все блокирующие находки закрыты.
andrey pushed to main at andrey/fishing-game 2026-09-21 23:40:59 +03:00
5701685dd7 Этап 45 ревизия: свечение рыб — плавный ramp с потемнением неба + компактный ореол (контур не размывается); лягушки крупнее. (1) glowIntensity(): 0 при nightMix()<=0.35 (старт как у фонаря), smoothstep k²(3−2k) по k=(nm−0.35)/0.55, до 1 при nightMix()>=0.9 — вместо мгновенного включения на порге; drawGlowAura(x,y,r,hex,I) — параметр интенсивности (globalAlpha, ранний выход при I<=0.02 — градиент не создаётся); fishGlow()/drawAmbientFish() — жёсткий гейт nightMix()>0.35 заменён на ramp. (2) Контур: радиус ауры 2.6→1.5 (ambient/bite/hooked; боссовая золотая не тронута), профиль градиента круче (стопы 0→0.55·I, 0.45→0.30·I, 1→0 — свет собран у тела, «шар» не заезжает на силуэт), силуэты светящихся видов — непрозрачные (hooked/bite/approach/out: alpha=1 при sp.glow; ambient: a+(1−a)·glowI — к глубокой ночи 1.0); у локаций 0..3 (glow=null) альфы не менялись. GLOW_RGBA-кэш +поле mid, save/restore и 'lighter' сохранены. (3) Лягушки: frogs[].s 4.5–7 → 9–14 (≈×2, отрисовка drawSwampDecor масштабируется от s), jh 10–22 → 16–30. Пиксель-приёмка (headless, Болото, фоновые рыбы): I монотонна 0.000→0.023→0.502→1.000 (t 0.30/0.55/0.70/0.85), день без свечения, excess(0.55)=7.4 < excess(0.85)=18.6, тело насыщенное sat≈93 / «мыла» 0% (контур чёткий); лягушки bbox 28×21.5 px при s=12 (×2.07), initScenery даёт s∈[9,14]. Проверено: 204/204 PASS exit 0, check.mjs OK. Скриншоты перегенерированы (42 RU + 42 EN; swamp-night заметно «чище»: компактные ореолы). Доки: AGENTS.md (ramp 0.35→~0.9, ореол 1.5/профиль 0.55/0.30, frogs s≈9–14), DEVLOG (блок «Ревизия свечения и лягушек» в Этапе 45). По просьбе пользователя (плейтест на телефоне).
andrey pushed to main at andrey/fishing-game 2026-09-21 22:59:26 +03:00
7f545347b4 Этап 45: локация «Волшебное болото» (id 4, 90 000 🪙) — светящиеся рыбы, лягушки, кувшинки/лилии. (1) Данные: LOCATIONS[4] (тёмно-моховая вода 6 hex, слабая рябь; в массиве ПОСЛЕДНИЙ, по цене — между Озёрами 65536 и Морем 131072); 5 новых видов строго в КОНЕЦ SPECIES (32→37, по одному на редкость r0–r4, у каждого glow:'#hex' — 5 разных цветов): glowfin Светлячок #5ff2ff 8🪙, moonfish Лунная рыбка #b9c8ff 13, emberfin Изумрудный светляк #57ffa8 20, violetlure Фиалковый огонёк #d17bff 38, spiritfin Дух болота #ffe07a 70; SWAMP_IDS/SWAMP_DAY_WEIGHTS/SWAMP_NIGHT_WEIGHTS/SWAMP_SPECIES(_NIGHT) — паттерн LAKE/SEA/OCEAN без пересечений; NIGHT_WEIGHTS — ключи всем 37 id. (2) pickSpecies(): вложенный тернарник → табличный доступ SPECIES_BY_LOCATION(_NIGHT) по save.location + guard (вне 0..4 → Река); роллы 0..3 бит-в-идентичны (lc3/lc4/lc4b/lc4c + речные §9j/M4/M6 не тронуты). (3) Свечение (только ночь): nightMix()>0.35 — тот же порог, что у фонаря; drawGlowAura() (радиальный градиент + 'lighter', save/restore, кэш GLOW_RGBA) — фоновые рыбы болота (AMBIENT_FISH[4] — 7 рыб + palette из 4 цветов, цвет стабильно по индексу), зацепившаяся/вываживаемая (fishGlow — вид с glow), боссовая золотая аура сохранена; карточка — класс glow-card + --glow (только normal-вариант, drop-shadow, не конфликтует с фильтрами вариантов), дневник — drop-shadow на SVG. (4) Декорации: initScenery() ветка i===4 (bank+reed+snag+pine в болотной гамме), ГЛОБАЛЬНЫЕ pads[] (8–14 кувшинок с вырезом, 45% с лилиями — жёлтые/белые/розовые) и frogs[] (3–5, sit→jump по параболе на соседнюю кувшинку, 3–7 с) — очищаются/пересобираются в initScenery() (resize + обе ветки shopClick); updateDecor(dt) — покачивание/прыжки; drawSwampDecor() — ОТДЕЛЬНЫЙ слой после drawWater/drawAmbientFish и до drawBoat (дusk берега не гасит; локальное притухание ночью). (5) Босс: BOSS_BY_LOCATION[4]='spiritfin' (Дух болота, 20–50 кг, ×5 — паттерн Этапа 37). (6) Магазин/i18n/ачивки: тост welcome_swamp (ru/en, тернарник → if/else), ачивки 34→36: swamp_first (bonus:{coinPct:0.02}, locations-based) + swamp_boss (bonus:{}, bosses.spiritfin) → пин achBonus().coinPct 0.16→0.18; species_8 = все 37. (7) Баланс: SWAMP_DAY_WEIGHTS {glowfin:3,moonfish:4,emberfin:28,violetlure:13,spiritfin:4.5}, SWAMP_NIGHT_WEIGHTS {glowfin:2.5,moonfish:2.5,emberfin:20,violetlure:30,spiritfin:4} — Болото 240.3/328.9 🪙 (ночь/день ×1.37), порядок по цене Озёра 194.1/249.0 < Болото < Море 297.3/476.7 в ОБЕ фазы; пины остальных вод не изменились (Река 65.1/125.9 · Озёра 194.1/249.0 · Море 297.3/476.7 · Океан 329.1/552.7). (8) tools/balance.mjs: 8→10 таблиц, +SWAMP_SPECIES(_NIGHT) в return, сводка/пары отношений — сортировка ПО ЦЕНЕ (болото встает между Озёрами и Морем), пины в шапке. (9) Портреты: 5 flat-SVG (каждый — отдельным художником) assets/fish/fish-{glowfin,moonfish,emberfin,violetlure,spiritfin}.svg (viewBox 0 0 160 100, var(--f1..f4,hsl-fallback)); embed-fish.mjs IDS 32→37 (в конец), 37 <symbol> в index.html; fish-preview.html 32→37 карточек. (10) Тесты (тот же коммит): lc1 (37/5 локаций/90000/names/sprites 37/oceanOrder slice(23,32)/swampOrder/swampGlow/swampRar), lc2 (+SWAMP-таблицы, пересечения, nightW 37), lc4d (новый: 3000+3000 роллов болота — все 5 ≥1, чужих нет), lc5 (+location:4 не сбрасывается, location:5→0), lc8w (новый: покупка 90000 + welcome_swamp), lc9 (37), lc10 (mid29), lc11 (новый: glow #rrggbb, 5 цветов различны, веса покрывают id, NIGHT_WEIGHTS — все 37), a22d (36), a36loc (+swamp_first), пин 0.18, §9k2 (+{loc:4, spiritfin, swamp_boss}). 198→204 PASS, exit 0. (11) Скриншоты: gen-screenshots.js +кадры swamp/swamp-night (12→14 × 3 вьюпорта, dayTime 0.3/0.85) — 42 RU + 42 EN PNG (screenshots-wiki/, screenshots-wiki-en/). (12) Доки: AGENTS.md (локации/босс/баланс/баланс-скрипт/награды/портреты/скриншоты), README (5 локаций, 37 видов, 36 ачивок, 204 теста, 14 кадров, mobp-swamp*), KODA.md (SWAMP_*, SPECIES_BY_LOCATION, drawGlowAura/fishGlow/GLOW_RGBA, drawSwampDecor, pads/frogs), DEVLOG (Этап 45), PLAN-SWAMP.md (статус «реализован»). Проверено: 204/204 PASS exit 0, check.mjs OK, balance.mjs — пины без изменений + Болото в цели, emoji-font --check OK (52 глифа, новых emoji нет), ревью @oracle — критичных замечаний нет (.gitignore + .opencode/, fish-preview, осколок комментария species_8 — закрыты в этом же коммите). Миграция сейва не тронута (граница из LOCATIONS.length; location=4 покрыт lc5(f)).
andrey pushed to main at andrey/fishing-game 2026-09-21 18:36:23 +03:00
3e9c5b7b45 Этап 41 ревизия 5 (px узлов — ручная подгонка) + закрытие диалогов по тапу мимо (backdropClose) + тест §X. (1) FISH_SIZE_KNOTS: 0.1 кг → 12 px (0.19× лодки), 0.2 → 16, 0.4 → 20, 0.8 → 24, 1.6 → 36, 3.2 → 48 (0.75×), 6.4 → 64 (= лодка, не тронут), 12.8 → 80, 25.6 → 96, 51.2 → 160, 100 → 256 px (= 4× лодки, не тронут) — мелкие рыбы мельче, средние узлы пересчитаны; интерполяция (линейно по log2 веса) и клампы не менялись: диапазон таблицы = диапазон функции 0.1–100 кг, fishSizeFromW() без правок; босс 20–50 кг → 90–158 px (1.41–2.47×), 1 кг → 27.9 px, диапазон 12..256 px ≈ ×21. (2) backdropClose(el,fn) (секция «КНОПКИ», после Y2-хендлеров): тап по подложке (e.target === сам оверлей, не .panel) закрывает диалог тем же действием, что и кнопка: #shop → closeShop, #resetDlg → «Отмена», #pause → closePause, #gamemenu → «Продолжить», #card → «Отлично!» (вкл. интерстишел); #menu — экран старта, вне списка. Подводный камень: pop-анимация #card (300 мс) сужает hit-area подложки — тест ждёт 400 мс после showCard. Тест §X (tests/test.js, 5 проверок: лавка/пауза/«Меню»/сброс/карточка, вкл. сохранение save.coins при «Отмене» и YG.counts.start +1 при «Продолжить») — 193→198. Проверено: все 11 узлов 0% отклонения, монотонность 2001 точки, клампы (0.05 кг → 12 px, 200 кг → 256 px); 198/198 PASS, exit 0; check.mjs OK; пины balance.mjs без изменений. Скриншоты перегенерированы (36 ru + 36 en; кадр reel 12.5 кг → ~79.5 px ≈ 1.24× лодки). Доки: AGENTS.md (строка backdropClose), DEVLOG (Этап 41 — пятая ревизия: узлы, размеры, 198/198), коммент над таблицей в index.html.