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 »
andrey pushed to main at andrey/fishing-game 2026-09-19 21:31:55 +03:00
36f54109a7 Рыба-босс в каждой локации (Этап 37): BOSS_BY_LOCATION={0:'sturge',1:'crayfish',2:'swordfish',3:'whale'} — босс = существующий вид текущей локации (Осётр/Гигантский рак/Рыба-меч/Синий кит, новых видов в SPECIES нет), условие в startBite() по save.location, тот же паттерн M4 (клон с boss:true, 30% или forceBoss). Единое правило веса: любой босс 20–50 кг (hook(): w=sp.boss?20+rand*30:rollWeight(sp), до d0/ov/st0, тот же w в reel.w/catchFish) — карманного рака нет, но босс до 50 кг > maxW Титана 40: при w>40 в режиме «держи кнопку» возможен настоящий обрыв (вываживается контролем натяжения) — зафиксировано в DEVLOG как материал баланс-этапа. Награда ×5/фазы/карточка «-БОСС» — без изменений, все вид-независимы; старые M4-пины (§9k/§9l(3)/M6(4)) прошли байт-в-байт без правок (награда читает фактический w, фазы нормированы на d0). Ачивки: boss_first — нейтральный текст «Победи рыбу-босса», +3 новые lake_boss 🦞 / sea_boss 🦈 / ocean_boss 🐳 (check по save.bosses[id], БЕЗ coinPct — пин §10c(8) achBonus 0.16 жив; bonus:{} — bonusText/achBonus корректны) — 31→34. save.bosses={} — дефолт save/freshSave + миграция loadSave + запись в boss-ветке catchFish. Тесты: новый блок §9k2 (3 локации × старт/вес 20–50 по фактическому reel.w/улов ×5/save.bosses/ачивка/карточка) + миграция сейва, a22d 31→34 — 193/193 PASS (2 прогона); check.mjs OK; emoji-font --check OK (🦞/🦈/🐳 уже в субсете); balance.mjs — без сдвига (босс вне ролла). Доки: README/AGENTS/KODA/DEVLOG (Этап 37), BROWSER-TESTING и orca-playtest — цифры босса 5–40→20–50 кг.
andrey pushed to main at andrey/fishing-game 2026-09-19 15:43:42 +03:00
ae5e2c1094 Локация «Океан» (Этап 36): SPECIES 23→32 — 9 глубоководных видов (мурена/горбуна/черепаха/удильщик/осьминог/скат-манта/большая белая акула/гигантский кальмар/синий кит), эксклюзив Океана; OCEAN_IDS/OCEAN_DAY/NIGHT_WEIGHTS (ночь — смещение к крупным), LOCATIONS[3] Океан 196608 🪙 (= ×1.5 Моря), своя вода; pickSpecies() — развилка на 4 локации (0/1/2/3); тост welcome_ocean RU/EN; ачивки sea_first «Широкая вода» ⚓ / ocean_first «Глубина» 🌊 (locations-based, 29→31, пин §10c(8)=0.16 не тронут). Попутный баг: граница loadSave() save.location>1 (с этапа 5, не обновлялась в этапе 35) → >=LOCATIONS.length — купленное Море сбрасывалось на Реку при каждом reload; регресс-кейсы lc5 (d)/(e). tools/balance.mjs — скрипт расчёта доходности таблиц ролла (--set/--dist/--lure), расширен на 4 локации (8 таблиц); пины: Река 65.1/125.9 · Озёра 121.2/134.1 · Море 190.8/222.0 · Океан 539.5/671.3 (×2.8–3.0 Моря — точная подгонка отдельным этапом). Кит wMax 50 > maxW Титана 40: ≥40 кг при технике «держи кнопку» — гарантированный обрыв, вываживается только управлением натяжением (28–38 с боя) — зафиксировано в DEVLOG как материал баланс-этапа. Emoji-шрифт: +6 глифов 🐢🐙🦑🐳🌊⚓ (58→64), --check OK. Тесты: пины 10f переписаны (32 вида/4 локации/costs), +роллы Океана lc4c (3000×2), +покупка lc8c, +lc5 (d)/(e), +sea_first/ocean_first — 183/183 PASS, exit 0; check.mjs OK. Доки README/AGENTS/KODA/DEVLOG синхронизированы (включая устаревшие числа: 162→183 проверки, 15→10 кадров, пример --set на латинских id).
andrey pushed to webasm at SHS/pip 2026-09-19 11:02:57 +03:00
94084fb351 Merge branch 'master' into webasm
031c3b9999 more 17 standard
04a588eb45 version 6.0.0
b745d5d867 add 418 code (1 april joke)
8e41461c08 version 6.0.0_beta
Compare 88 commits »
andrey pushed to main at andrey/fishing-game 2026-09-18 23:24:45 +03:00
6d5e76d96e Локация «Море» + эксклюзивные рыбы у каждой локации (Этап 35): SPECIES 16→23 — Озёра теряют речную рыбу и получают краснопёрку/сига (10 своих), Море — сельдь/скумбрию/камбалу/тунца/рыбу-меч (5 своих); таблицы по *_IDS без пересечений, LAKE_* перебалансированы (день ≈121, ночь ≈134 🪙 — снова доходнее Реки), SEA_*_WEIGHTS (день ≈190/ночь ≈222 — топ); цены локаций: Озёра 65536, Море 131072 (×2); миграция location по LOCATIONS.length, тосты welcome_sea RU/EN, босс-осётр остался только в Реке. Тесты: пины 10f переписаны (23 вида/3 локации/10 озёрных), +пересечения lc2, +роллы и покупка Моря (lc4b/lc8b) — 180/180 PASS; orca 76/76, pack+smoke 6/6, emoji-font --check OK; скриншоты RU/EN пересняты; доки README/AGENTS/KODA/DEVLOG синхронизированы.
andrey pushed to main at andrey/fishing-game 2026-09-18 20:11:14 +03:00
812c65bd90 Доходность Озёр 100+ 🪙 (Этап 34): LAKE_*_WEIGHTS — сдвиг долей в пользу дорогой рыбы, день 84.7→110.4 (×1.70 реки), ночь 122.2→145.5 (×1.16 реки).
aace2b130a Ещё пять озёрных видов (Этап 33): SPECIES 11→16 — плотва/густера/вьюн/линь/навага, чтобы «побольше разных рыб» не трогало Реку.
Compare 2 commits »
andrey pushed to main at andrey/fishing-game 2026-09-15 21:35:36 +03:00
975ed32d97 Дождь ×3 (Этап 32): WEATHER.rain.variantMult 2.5→3 — особые варианты в дождь ещё чаще; эффект в variantChance() применяется к шансу с бустом снасти (суммарно у топ-снасти в дождь P(особой)≈90%, насыщения нет — все шансы <1). Заодно упущение Этапа 30: тост погоды берётся из T (t('wx_rain'), i18n), а WEATHER.rain.toast — мёртвое поле; в T.wx_rain оставался старый текст «шанс серебряной/золотой/радужной ×2,5» — RU «Дождь: шанс особых рыб ×3», EN «Rain: special fish chance ×3» (+WEATHER.rain.toast для консистентности). Тесты: M8(1) пин variantMult===3; M8(2) шансы ×3 (copper 0.36 / silver 0.24 / quartz 0.21 / gold 0.18 / emerald 0.03 / diamond 0.021 / rainbow 0.015, tol 1e-9) + пин текста тоста («особых», «×3»); orca-шаг 8 ratio ×3. 178/178 PASS, exit 0; check.mjs OK. Доки: README (×3), AGENTS (M8 ×3 + пометка про t('wx_*)/мёртвый toast), DEVLOG Этап 32, BROWSER-TESTING (шаг 8).
andrey pushed to main at andrey/fishing-game 2026-09-15 21:21:55 +03:00
297e6f3ff7 Снасть усиливает шанс особых вариантов (Этап 31): variantBoost() = lure().rare×0.15 + (уровень наживки−1)×0.05, множитель шанса варианта ×(1+B·r), r — номер в лестнице VARIANTS (медь 1 … радуга 7) — чем реже вариант, тем сильнее прибавка; внутри variantChance() (единственная точка вероятностей), дождь ×2.5 применяется к усиленному шансу. Источник B — существующий rare-стат effLure (крючок 0 / червь 0.2 / воблер 0.8 / блёстка 2.0, +1.0 на 3–4 ур.) — тип и уровень наживки работают через один статики + слагаемое за каждый уровень апгрейда (+0.05/ур., буст с 1-го уровня, не только с 3-го). Диапазон: простая 1 ур. — B=0 (P(особой)≈31%, базовые пины не менялись), червь 0.03, воблер 0.12, блёстка 1 ур. 0.3 (rainbow ×3.1), блёстка 4 ур. 0.6 (rainbow ×5.2, gold ×3.4, P(особой)≈60%); насыщения нет (топ+дождь — все шансы <1). Тесты: +1 §10c(9) «буст снасти» — B=0 у простой, червь/блёстка/4 ур. значения copper/gold/rainbow (tol 1e-9), отношение множителей «радуга/медь» растёт с B (редким больше), ролл r=0.12 с червя → copper (граница под бустом); §10c(1) +пин boost0=0; пины шансов §10c(1)/(5), M8(2) — на нейтральной снасти (снапшот/рестор save.lure/lureLv в eval — снасть mid-сьюта после M5-тестов непредсказуема). 178/178 PASS, exit 0; check.mjs OK. Доки: AGENTS.md (M6: формула/диапазон/паттерн пинов), README (снасть усиливает шанс), DEVLOG Этап 31.