Files
fishing-game/screenshots-wiki
andrey 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.
2026-09-22 23:02:00 +03:00
..
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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.
2026-09-22 23:02:00 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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.
2026-09-22 23:02:00 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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.
2026-09-22 23:02:00 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00
Этап 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 — все блокирующие находки закрыты.
2026-09-22 21:34:10 +03:00