Бычков Андрей andrey
  • Joined on 2020-04-23
andrey pushed to main at andrey/fishing-game 2026-09-21 15:14:26 +03:00
ea428bb4fb Карточка улова: SVG-портрет рыбы ×2. #card .bigemoji svg 120×75 → 240×150 (моб. ≤420px: 94×59 → 188×118, низкий экран ≤620px: 81×50.6 → 162×101.2 — соотношение 160:100 сохранено). Панель min(92vw,370px) с паддингом 22 px — контентная ширина до 326 px, 240 px влезает; на низких экранах панель скроллится (max-height:92vh). Чисто CSS: роллы/баланс/физика не тронуты. Тесты: пинов на размер портрета нет (M6-пин — href #cardFishUse) — 193/193 PASS, exit 0; check.mjs OK.
andrey pushed to main at andrey/fishing-game 2026-09-20 23:26:43 +03:00
48c54491dd Этап 44: береговые силуэты на горизонте (полный вариант различения локаций) + ревизия Реки. scenery/initScenery() по локации: Река — береговая полоса на всю ширину {k:'bank',h} (трава 12–17 px + тёмная кромка у воды) + хвойный лес в 2 ряда, посаженный на её кромку ({k:'pine',layer,by} — by=waterY−bankH, база ствола); Озёра — холмы {k:'hill',rx,ry} (2–3 дуги за деревьями) + лиственные деревья {k:'tree'}; Море — парусник {k:'ship',dir,v,s} (медленно дрейфует по курсу, паруса светлые) + 3 чайки {k:'gull',y,v,ph} (летят, машут крыльями); Океан — ПУСТО (открытый горизонт без берега). drawScenery() — между drawSky() и drawWater() (вода перекрывает базу силуэтов); ночь — dusk()=hexLerp(·,'#0b1220',nm*0.8) гасит силуэты, чайки почти гаснут; дрейф — updateDecor(dt). Река без волн (ревизия): LOCATIONS[0].waves — все нули, drawWater() рисует линию только при amp>0/amp2>0 — спокойная вода, ровный край. Провозировка initScenery(): resize(), обе ветки смены локации shopClick (рядом с initFish), кадры lake/sea/ocean в gen-screenshots.js (без него кадр Моря показал бы лес с Реки). Скриншоты перегенерированы (72 PNG: screenshots-wiki/ + screenshots-wiki-en/). Чисто визуал: роллы/баланс/физика не тронуты. Тесты: 193/193 PASS, exit 0; check.mjs OK; balance.mjs — пины без изменений. Приёмка: headless 1280×720, 4 локации × день/ночь + кроп-контроль горизонта (пиксельная выборка неба — чистый градиент, «точки» в превью — артефакт даунскейла). Доки: DEVLOG (Этап 44), AGENTS.md (строка «Локации» — waves/сценарий silhouette + вызовы initScenery), README (строка локаций — «свой берег»).
andrey pushed to main at andrey/fishing-game 2026-09-20 21:44:44 +03:00
4e7a9ddab0 Этап 43: визуальное различение локаций (лёгкий вариант). Вода различима по цвету (Море — светлая бирюза #41b1e8/#2287c9/#0b3d6e, Океан — глубокий тёмно-синий #1a5fa8/#0c3d74; Река/Озёра не тронуты — тест пинит только формат 6 hex), характер волн поверхности по локации: LOCATIONS.waves {amp,amp2,freq,freq2,speed,speed2} в drawWater() — Река мелкие гребни, заметно текут в сторону (speed 3.2), Озёра медленная гладь (1.2 px), Море умеренная волна (3.5 px), Океан крупные зыби (6–8 px); фоновые рыбы по воде: AMBIENT_FISH[4] {n,sMin,sMax,hMin,hMax} в initFish() — Река 9×8–22 как было, Озёра 9×10–26 зелёные, Море 8×12–32 синие, Океан 6×18–44 крупные тёмно-синие; initFish() добавлен в обе ветки смены локации shopClick (buylocation/selectlocation) — раньше рыбы не знали о смене воды. gen-screenshots.js: +кадры sea/ocean (10→12 кадров, save.location=2/3 + initFish), кадр lake и сброс — initFish. README: строка локаций «своя вода (цвет, характер волн, рыбы в толще)» + 3 изображения lake/sea/ocean, «12 кадров × 3 вьюпорта». Скриншоты перегенерированы: screenshots-wiki/ и screenshots-wiki-en/ по 36 PNG. Чисто визуал: роллы/баланс/физика не тронуты (небо/облака/лодка — общие, по выбранному варианту). Тесты: 193/193 PASS, exit 0; check.mjs OK; balance.mjs — пины без изменений (Река 65.1/125.9 · Озёра 194.1/249.0 · Море 297.3/476.7 · Океан 329.1/552.7). Доки: DEVLOG (Этап 43), AGENTS.md (строки «Локации»/«Скриншоты»).
andrey pushed to main at andrey/fishing-game 2026-09-20 20:41:15 +03:00
cfdb93bf7c Этап 41 ревизия 4 (финальная): размер рыбы — узловая таблица по степеням двойки, интерполяция по log2(веса). fishSizeFromW(w) + FISH_SIZE_KNOTS=[[0,16],[1,20],[2,25],[3,35],[4,48],[5,64],[6,80],[7,100],[8,120],[9,170],[log2(1000),256]] ([log2(w/0.1), длина px]) — явная таблица пользователя (веса степени двойки, «погрешность 10%»): степенная шкала ревизии 3 не покрыла таблицу в середине (на 25.6 кг было бы +24% к цифрам; локальный показатель кривой 0.26..0.61) — заменена узлами. Длина силуэта = 2.45·fs (тело 2·fs + хвост), интерполяция линейна по log2(w) — узлы бьются ТОЧНО (0% отклонения, проверено: 16/20/25/35/48/64/80/100/120/170/256 px), кривая монотонна (1000 точек); веса вне 0.1–100 кг клампятся в края (нижний кламп — только золотая рыбка 0.05–0.1 кг). Распределение: 0.1 кг → 16 px (0.25× лодки), 0.2 → 20, 0.4 → 25, 0.8 → 35, 1.6 → 48, 3.2 → 64 px (= лодка), 6.4 → 80, 12.8 → 100, 25.6 → 120, 51.2 → 170 px, 100 кг (кит max) → 256 px (4× лодки); 1 кг → 39.2 px, 10 кг → 92.9 px; босс 20–50 кг → 113–168 px (1.77–2.6×). Диапазон 16..256 px = ×16. Тесты: пинов на размер силуэта нет — 193/193 PASS, exit 0; check.mjs OK; скриншоты пересняты (кадр reel: 12.5 кг ≈ 99 px ≈ 1.55× лодки); узлы 100/3.2/0.1 кг проверены живыми кадрами headless-Chromium (численный контроль 16.0/64.0/256.0 px). Доки: DEVLOG (Этап 41 — таблица, интерполяция, пометки ревизий 3/4).
andrey pushed to main at andrey/fishing-game 2026-09-20 19:32:56 +03:00
31d60a6333 Этап 41 ревизия 3: 100 кг → 256 px (4× лодки), 1 кг → 20 px — степенная шкала. fishSizeFromW(w)=(3.95+16.05*max(0.1,w)^0.5981)/2.45 — по ДЛИНЕ силуэта (длина = 2.45·fs): якоря 0.1 кг → 8 px (не тронут), 1 кг → 20 px, 100 кг → 256 px = 4× лодки 64 px (было 128 = 2×). Буквально квадратичная шкала 3 якоря не держит монотонно (парабола по w: пик ~420 px на 61 кг, затем схождение к 256 px на 100 кг — кит меньше «средней» рыбы; квадратичная по ln w: провал до ~4 px у 0.2 кг) — степенная A+B·w^k точна по всем трём якорям и монотонна (k≈0.598, A≈3.95, B≈16.05). Распределение: 5 кг → 46 px (0.72× лодки), 10 кг → 67.6 px (1.05×; размер лодки достигают ~9.1 кг), 20 кг (босс min) → 100 px (1.57×), 50 кг (босс max) → 170.6 px (2.67×), 100 кг (кит max) → 256 px (4×). Диапазон 8..256 px = ×32 (было ×16; в исходной формуле ×2.7). На мобильном 360 px кит ≈ 71% ширины экрана. Тесты: пинов на размер силуэта нет — 193/193 PASS, exit 0; check.mjs OK; скриншоты пересняты (кадр reel: 12.5 кг ≈ 77 px ≈ 1.2× лодки); якоря 100/1 кг проверены живыми кадрами headless-Chromium. Доки: DEVLOG (Этап 41 — формула, таблица размеров, пометка ревизии и обоснование выбора шкалы).
andrey pushed to main at andrey/fishing-game 2026-09-20 19:09:53 +03:00
203694a30c Этап 41 ревизия 2: минимум 0.1 кг → 8 px длины силуэта (fs 8→3.27). fishSizeFromW(w)=(8+120*(max(0.1,w)-0.1)/99.9)/2.45 — шкала теперь линейна по ДЛИНЕ силуэта (длина = 2.45·fs), якоря: 0.1 кг → 8 px (было 19.6 px — «ещё меньше»), 100 кг → 128 px = 2× лодки 64 px (не тронут). Новое распределение: 1 кг → 9.1 px (0.14× лодки), 5 кг → 13.9 px (0.22×), 10 кг → 19.9 px (0.31×), 20 кг (босс min) → 31.8 px (0.50×), 50 кг (босс max) → 67.9 px (1.06×), 100 кг → 128 px (2×); размер лодки (64 px) достигают ~47 кг. Диапазон 8..128 px = ×16 (было ~20..54 px = ×2.7): мелочь — точечная, разброс дали тяжёлые 20–100 кг. Баланс/тесты: не затронуто — 193/193 PASS, exit 0; check.mjs OK; скриншоты пересняты (кадр reel: 12.5 кг ≈ 23 px ≈ 0.36× лодки). Доки: DEVLOG (Этап 41 — формула/таблица обновлены, пометка ревизии).
andrey pushed to main at andrey/fishing-game 2026-09-20 19:00:58 +03:00
2734998854 Этап 41 ревизия: лог-шкала размера рыбы → линейная. fishSizeFromW(w)=8+44.2*(max(0.1,w)-0.1)/99.9 вместо 8+44.2*log10(max(0.1,w)/0.1)/3 — лог поднимал средние рыбы до «почти лодка» (1 кг → 0.9×, 10 кг → 1.4×): «все рыбы сильно большие». Якоря не изменились: 0.1 кг → 8 (минимум), 100 кг → 52.2 (128 px = 2× лодки 64 px). Линейное распределение: 1 кг → 8.4 (0.3×), 10 кг → 12.4 (0.5×), 20 кг (босс min) → 16.8 (0.6×), 50 кг (босс max) → 30.1 (1.2×), 100 кг → 52.2 (2×) — размер лодки (64 px) достигают ~41 кг. Мелочь осталась мелкой (как в старой формуле 8+(w/wMax)*10+rarity), разброс дали тяжёлые 20–100 кг. Баланс/тесты: не затронуто — 193/193 PASS, exit 0 (прогон поверх Этапа 42); check.mjs OK; скриншоты пересняты (кадр reel: 12.5 кг ≈ 33 px ≈ 0.5× лодки). Доки: DEVLOG (Этап 41 — формула и таблица размеров обновлены на линейную, помечена ревизия).
2329dd9a21 Центрирование SVG-портрета на карточке улова: #card .bigemoji svg — margin:0 auto. Портрет (блок фиксированной ширины 120px) прижимался к левому краю: text-align:center у .panel центрирует только текст, на блочный SVG не действует (.bigemoji — display:block на всю ширину). Адаптивные размеры (94px/81px в media-запросах) наследуют правило. Игровая логика не тронута (визуальный фикс). Тесты: 193/193 PASS, exit 0; check.mjs OK.
Compare 2 commits »
andrey pushed to main at andrey/fishing-game 2026-09-20 18:24:10 +03:00
cb502e4a17 SVG-портреты рыб в дневнике и карточке улова + убраны эмодзи рыб (Этап 42): 32 flat-SVG портрета в assets/fish/fish-<id>.svg (viewBox 0 0 160 100, flat-заливки, цвета var(--f1..f4,hsl-fallback) с инлайн-fallback в каждом элементе, переменные НЕ объявляются на <svg>/<g> — иначе перекраска сквозь <use> не сработает). Встраивание — node tools/embed-fish.mjs (идемпотентно, блок между маркерами FISH-SVG:BEGIN/END сразу после <body>, 32 <symbol id="fish-<id>" viewBox="0 0 160 100">, валидация + самопроверка + check.mjs внутри; повторный запуск — md5-стабильно). Приёмка — tools/fish-preview.html (file://: сетка 32 + демо перекраски вариантов). Дневник (пойманные) и карточка улова — <use href="#fish-<id>"> вместо дублирующихся эмодзи (🐟 был у 11 видов); showCard ставит href у #cardFishUse; перекраска вариантов — CSS-переменные --f1/--f3 в #card.<variant>-card .bigemoji (copper/gold/quartz/emerald/diamond; silver/rainbow — существующие filter, boss — filter). Эмодзи рыб УБРАНЫ полностью: поле emoji удалено из всех 32 записей SPECIES (пин lc1 fieldsOk обновлён в том же коммите), тосты обрыва/срыва без эмодзи, иконка квеста catch_species — mini-SVG .qfish (<use>, скоуп .jrow .je из-за специфичности правила портрета), рыбка-маркер дистанции на канвасе — drawFishMark (path), иконки ачивок/воблера — глифы уже бывшие в субсете (🏅/💪/🗺️/⚓/🌊/🎣). Emoji-шрифт перегенерирован (tools/emoji-font.py): субсет 64→52 глифа, woff2 89→65 КБ. Тесты: пины lc1 (32 symbol + spriteIdsOk по всем id) и M6-карточка (href #fish-carass у всех 8 вариантов); 193/193 PASS, exit 0; check.mjs OK; emoji-font --check OK (52); grep 12 рыбных эмодзи — 0 вхождений. Игровая логика/баланс/пины роллов не тронуты (визуальный этап). Доки: AGENTS.md (строка «Портреты рыб (SVG-спрайт)» в «Где крутить»), DEVLOG (Этап 42, обе части).
andrey pushed to main at andrey/fishing-game 2026-09-20 12:23:04 +03:00
c250068e8a Размер рыбы при вываживании — от абсолютного веса (Этап 41): 0.1 кг → минимум как раньше, 100 кг → 2× лодки. drawHookedFish(): fs=fishSizeFromW(reel.w) вместо 8+(w/wMax)*10+rarity — размер больше не от диапазона вида и не от редкости (крупнее вес → крупнее рыба); босс-×1.5 убран (20–50 кг и так 1.7–1.8× лодки, с ×1.5 рак 30 кг выглядел бы крупнее кита 100 кг), аура босса сохранена. fishSizeFromW(w)=8+44.2*log10(max(0.1,w)/0.1)/3 — лог-шкала (линейная упёрла бы все уловы 0.1–10 кг в 8..12 px), якоря 0.1 кг→8 / 100 кг→52.2 (длина 2.45·52≈128 px = 2× лодки 64 px); диапазон ×6.5 (было ×2.4). Не тронуто: подплывающая рыба до подсечки (вес не зароллен), фоновые рыбы, 🐟-маркер, карточка; wMin/wMax остались в rollWeight/hook/st0 — баланс не задет (balance.mjs: пины 65.1/125.9 · 194.1/249.0 · 297.3/476.7 · 329.1/552.7 без изменений). Тесты: пинов на размер силуэта нет — 193/193 PASS, exit 0; check.mjs OK; скриншоты пересняты (30 кадров, кадр reel: 12.5 кг ≈ 95 px ≈ 1.5× лодки). Доки: DEVLOG (Этап 41), AGENTS.md правок не требует (формулу не пинит).
andrey pushed to main at andrey/fishing-game 2026-09-20 11:02:25 +03:00
1f0f78decf Ночные *_WEIGHTS «ночь доходнее» + меньше сельди/скумбрии в Море (Этап 40): без подгонки под ×3/×4/×5 — просто факт. LAKE_NIGHT: +навaga 5→10, сиг 13→18, судак 28→32, линь 22→24; −вьюн 8→4, хариус/плотва 4→3, густера/краснопёрка 3→2.5. SEA_DAY: сельдь/скумбрия 34/34→32/32 (доля 82.3→79.5% — дневное Море ограничено инвариантом «< Океан 329.1»), камбала 11→12, тунец 2.6→3, меч 1.2→1.5. SEA_NIGHT: сельдь 24→18, скумбрия 30→20 (доля 78.5→64.2%), камбала 11→15, тунец 2.6→4, меч 1.2→2.2. OCEAN_NIGHT: +кит 2.5→4, манта 3.5→5, акула/кальмар 3→4.5, осьминог 6→8; −мурена 32→26, горбуна 28→22. Цены/веса видов/река не тронуты. tools/balance.mjs: Озёра 194.1/249.0 (×2.98/×1.98 Реки, ночь/день 1.11→1.28), Море 297.3/476.7 (×4.57/×3.79, 1.16→1.60), Океан 329.1/552.7 (×5.06/×4.39, 1.21→1.68), Река 65.1/125.9. Инвариант «новая вода доходнее в ОБЕ фазы»: Море/Озёра ×1.53/×1.91, Океан/Море ×1.11/×1.16 — дневной запас тонкий (Море упирается в Океан), зафиксировано в AGENTS.md. Средний вес: Море день ≈7.0 (было 6.5), ночь ≈9.4; Озёра ночь ≈13.9 — разрыв «Море легче Озёр» сократился, не закрыт (инвариант). Здоровье роллов: худшее Море день swordfish 55.9 попаданий — ок. Тесты: lc2/lc4/lc4b/lc4c/§9j/M4/M6/§10 без изменений — 193/193 PASS, exit 0; check.mjs OK. Доки: AGENTS.md (пины + пометка тонкого запаса), комментарии ДАННЫЕ index.html, DEVLOG (Этап 40).
48dd6ae22a Цены Озёр/Моря/Океана под цели ×3/×4/×5 Реки (Этап 39): после лестницы весов Этапа 38 доходность новых вод была ×5–15 — урезаны цены 24 видов (Озёра k≈0.201: zander 8, chuch 6, crayfish 40, bleak 4, roundel 5, eelpout 11, tench 16, navaga 50, rudd 5, cisco 18; Море k≈0.253: herring 8, mackerel 18, flounder 33, tuna 46, swordfish 81; Океан k≈0.192: moray 5, grouper 5, turtle 9, angler 21, octopus 23, manta 29, shark 31, squid 37, whale 67), цены Реки не тронуты. tools/balance.mjs: новая опция --price id:цена (what-if 🪙/кг, паттерн --set: парсинг/валидация id/calcTable/WHAT-IF строка/help) — набор цен собран и сверен через скрипт ДО и ПОСЛЕ правки index.html (цифры совпали). Итог (нейтральная снасть): Озёра 194.1/214.5 (×2.98/×1.70 Реки), Море 262.7/304.2 (×4.04/×2.42), Океан 329.1/398.9 (×5.06/×3.17), Река 65.1/125.9 — цель по ДНЮ (×3/×4/×5): единый множитель масштабирует обе фазы, а ночь/день у новых вод ×1.11–1.21 против ×1.93 у Реки — «обе фазы» ценами недостижимо (нужна правка *_WEIGHTS); зафиксировано в AGENTS.md. Инвариант «новая вода доходнее в ОБЕ фазы» держится с запасом: Море/Озёра ×1.35/×1.42, Океан/Море ×1.25/×1.31 (тонкий запас этапа 38 ×1.06 снят). Тесты: пины lc1 (10f) — 24 строки (колонка price) + текст ассерта; тесты наград M4/§9k2/M6/shiny читают w×price динамически — без изменений (босс-рак 200→40). 193/193 PASS, exit 0; check.mjs OK. Доки: AGENTS.md (финальные пины + --price), README (4–1500 🪙/кг), KODA.md (0.05–100 кг, 4–1500 🪙/кг), шапка balance.mjs (пины), DEVLOG (Этап 39).
ebb468accb Лестница веса по локациям (Этап 38): дороже вода = тяжелее рыба = сложнее бой — SPECIES.wMin/wMax 24 видов (Озёра ×8: судак 8–48, линь 2.4–32, сиг 4–28; Море ×6, рыба-меч ×4 по явному заданию: скумбрия 1.8–15, камбала 3–30, тунец 12–72, меч 20–80; Океан ×4, кит ×2 чтобы остался вываживаемым: мурена 6–24, горбуна 8–40, черепаха 20–56, осьминог 16–48, манта 24–60, акула 20–56, кальмар 16–48, кит 40–100). Река 0..7 не тронута (пины §9j/M4/M6); ролл-веса/цены/редкости — не тронуты; код боя не менялся (rollWeight/hook/updateReel читают wMin/wMax напрямую, st0 и силуэт инвариантны к w/wMax). Мотивация: лестница была сломана — E[вес] Река≈1.3≈Озёра≈1.3>Море≈1.1, макс Реки 40 (осётр) > макс Озёр 12 (судак). Теперь максимы монотонны: 40<48<80<100; E[вес] 1.3→10.7→6.5→21 кг. tools/balance.mjs: Озёра 970.0/1072.4 · Море 1028.9/1192.4 · Океан 1691.4/2053.9 (было 121.2/134.1 · 190.8/222.0 · 539.5/671.3), Река 65.1/125.9 без изменений; инвариант «новая вода доходнее в ОБЕ фазы» держится: Море/Озёра день ×1.06 (тонкий запас — зафиксировано в AGENTS/DEVLOG), ночь ×1.11, Океан/Море ×1.64/×1.72; здоровье роллов без изменений. Осознанные странности (не чинили): средний вес Моря (≈6.5) легче Озёр (≈10.7) — ролл Моря 82% сельдь/скумбрия; кит 40–100 кг на Титане (maxW 40) при w>40 рвёт леску в режиме «держи», вываживается контролем натяжения (паттерн кит-босса Этапа 37). Доходность выросла ×5–15 — Этап 39 (отдельный коммит) урезает цены к целям Озёра≈×3 Реки, Море≈×4, Океан≈×5. Тесты: пины lc1 (10f) переписаны (24 строки — только веса) + текст ассерта (кит 40–100 кг); lc2/lc4/lc4b/lc4c/§9j/M4/M6/§10 без изменений — 193/193 PASS, exit 0; check.mjs OK. Доки AGENTS.md (Локации/Баланс Озёр/Баланс-скрипт) и DEVLOG (Этап 38) синхронизированы.
Compare 3 commits »