146 lines
11 KiB
Markdown
146 lines
11 KiB
Markdown
# План: локация «Волшебное болото» (id 4, 90 000 🪙)
|
||
|
||
Статус: **реализован (Этап 45)** — см. запись «Этап 45» в `docs/DEVLOG.md`; тело плана ниже оставлено как историческая фиксация.
|
||
Ориентир по коду: `index.html` ~3861 строка; ссылки на строки даны на момент составления плана
|
||
(перед реализацией сверять — номера могли сдвинуться).
|
||
|
||
## 1. Задача
|
||
|
||
Добавить пятую локацию — **«Волшебное болото»** за **90 000 🪙**:
|
||
|
||
- светящиеся рыбы, которые **ночью** светятся в темноте **разными цветами**;
|
||
- **прыгающие лягушки**;
|
||
- **кувшинки** и **лилии** (жёлтые, белые, розовые).
|
||
|
||
## 2. Зафиксированные решения (ответы пользователя)
|
||
|
||
| Развилка | Решение |
|
||
|---|---|
|
||
| Когда светятся рыбы | **Только ночью** — включать при `nightMix() > 0.35` (тот же порог, что у фонаря на лодке, `index.html:2584`). Днём болото — обычная мрачная вода. |
|
||
| Сколько новых видов | **5 видов** по одному на редкость r0–r4, у каждого своё поле `glow:'#hex'` (разные цвета). |
|
||
| Босс | **Да** — светящийся босс + персональная ачивка (паттерн остальных 4 локаций). |
|
||
| Доходность | «Не принципиально» → берём **между Озёрами и Морем** (уважает связку «дороже вода = дороже улов» при цене 90 000). Ориентир день ~240 / ночь ~330 🪙; точные цифры подбираются `balance.mjs --set` и фиксируются. |
|
||
| Свечение в карточке/дневнике | **Да** — CSS `drop-shadow` по полю `glow` вида. |
|
||
|
||
## 3. Предлагаемые виды (имена/цвета можно менять)
|
||
|
||
| id | RU | EN | r | weight | wMin–wMax | glow | цена |
|
||
|---|---|---|---|---|---|---|---|
|
||
| `glowfin` | Светлячок | Glowfin | 0 | 38 | 0.3–3 | `#5ff2ff` циан | 8 |
|
||
| `moonfish` | Лунная рыбка | Moonfish | 1 | 24 | 0.8–8 | `#b9c8ff` бледно-голубой | 13 |
|
||
| `emberfin` | Изумрудный светляк | Emerald Glowfish | 2 | 14 | 1.5–16 | `#57ffa8` зелёный | 20 |
|
||
| `violetlure` | Фиалковый огонёк | Violet Lure | 3 | 5 | 2–24 | `#d17bff` фиолетовый | 38 |
|
||
| `spiritfin` | Дух болота | Swamp Spirit | 4 | 2.5 | 0.5–6 | `#ffe07a` золотой | 70 |
|
||
|
||
- **Босс** — `spiritfin` (легендарный дух; вес по общему правилу 20–50 кг, награда ×5).
|
||
- Веса и цены — стартовая заготовка, финал через `node tools/balance.mjs --set ...`.
|
||
- «Здоровье» теста «каждый вид ≥1»: минимальный вес вида ≥ ~2.2 (иначе lc4 за 3000 роллов
|
||
заплывёт). `moonfish`/`emberfin` в норме; при желании боссу можно добавить вес.
|
||
- **Дополнительные ачивки**: `swamp_first` (локация, `coinPct:0.02`, как `lake_first`) и
|
||
`swamp_boss` (без `coinPct`, как `lake_boss`). Это поднимет `ACHIEVEMENTS.length` 34→36
|
||
и пин `achBonus().coinPct` 0.16→0.18 — тесты и доки обновить явно.
|
||
|
||
## 4. Карта изменений по коду
|
||
|
||
### 4.1 Данные (`index.html`, секция «ДАННЫЕ»)
|
||
|
||
| Что | Где | Правка |
|
||
|---|---|---|
|
||
| Локация | `1143-1156` (`LOCATIONS`) | Запись `{id:4, name:'Волшебное болото', ... cost:90000}`; `water` — тёмно-моховой 6-hex (день/ночь); `waves` — слабая рябь (`amp~0.8`). Миграция сейва (`1382-1387`) уже завязана на `LOCATIONS.length`. |
|
||
| Новые виды | `1072-1118` (`SPECIES`) | Только **в КОНЕЦ** (после `whale`) — `SPECIES[0..7]` запинены тестами/квестами (§9j/M4/M6). Каждому поле `glow`. |
|
||
| Ночные веса | `1127` (`NIGHT_WEIGHTS`) | Ключ каждому новому id (иначе `weight=undefined`). |
|
||
| Таблицы болота | `1176-1196` | `SWAMP_IDS`, `SWAMP_DAY_WEIGHTS`, `SWAMP_NIGHT_WEIGHTS`, `SWAMP_SPECIES(_NIGHT)` — копия паттерна LAKE/SEA/OCEAN, без пересечений. |
|
||
| Босс | `1201` (`BOSS_BY_LOCATION`) | `4:'spiritfin'`. |
|
||
| Фоновые рыбы | `1809-1814` (`AMBIENT_FISH`) | 5-я запись + `palette` (циан/зелёный/фиолет/золото) для «разных цветов». |
|
||
|
||
### 4.2 Логика
|
||
|
||
- `pickSpecies()` (`1907-1925`): заменить вложенный тернарник на табличный доступ по
|
||
`save.location` + guard на диапазон. Поведение локаций 0..3 идентично; болото больше
|
||
не «проваливается» в реку.
|
||
- `startBite()` (`1950`): босс подхватится из `BOSS_BY_LOCATION[4]` автоматически;
|
||
`save.bosses` уже миграционно готов (`1371-1372`).
|
||
|
||
### 4.3 Свечение (только ночь)
|
||
|
||
- `drawFishShape`/`drawAmbientFish` (`2517-2540`): аура радиальным градиентом +
|
||
`globalCompositeOperation='lighter'`, цвет из `palette`/`glow`, только при
|
||
`nightMix()>0.35` и `save.location===4`.
|
||
- `draw()` (`2934-2943`) и `drawHookedFish()` (`2731-2745`): аура для вида с `glow` ночью
|
||
(паттерн боссовой ауры `2739-2743`). Обязательно `save/restore` либо сброс `shadowBlur`.
|
||
- Карточка (`showCard` `3645`, CSS `175-190`): класс `glow-card` для вида с `glow` **при
|
||
normal-варианте** (чтобы не конфликтовать с фильтрами вариантов) → `drop-shadow` цвета `glow`.
|
||
- Дневник (`renderShop` journal `3501-3521`): маркер-класс на SVG для светящихся видов.
|
||
|
||
### 4.4 Декорации (лягушки, кувшинки, лилии)
|
||
|
||
- `initScenery()` (`1836-1853`): ветка `i===4` — фон (камыш/кривые деревья) + отдельные
|
||
массивы `pads[]`/`frogs[]` (очищаются вместе с `scenery`).
|
||
- `updateDecor(dt)` (`2240-2266`): параболический прыжок лягушек; покачивание кувшинок.
|
||
- Новая `drawSwampDecor()`: кувшинки (эллипс с вырезом), лилии жёлтые/белые/розовые
|
||
(лепестки), лягушки. Вызов в `draw()` (`2924`) **после** `drawWater`/`drawAmbientFish`
|
||
и до `drawBoat` — лилии поверх воды.
|
||
- Вызовы `initScenery()` не трогаем (уже есть в `resize` и обеих ветках `shopClick`).
|
||
|
||
### 4.5 Магазин / i18n / ачивки
|
||
|
||
- `shopClick` тост (`3586`): ветка `id===4` → `welcome_swamp`.
|
||
- `T` ru/en (`3060+` / `3157+`): название и описание локации, `welcome_swamp`,
|
||
`nameEn`/`descEn`/описания видов.
|
||
- `ACHIEVEMENTS` (`1618-1655`): `swamp_first` (+0.02), `swamp_boss` (без `coinPct`).
|
||
|
||
### 4.6 Портреты (основной объём)
|
||
|
||
- 5 файлов `assets/fish/fish-<id>.svg` (viewBox `0 0 160 100`, цвета через `var(--f1/--f3)`).
|
||
- Добавить id в `tools/embed-fish.mjs:24-29`, прогнать `node tools/embed-fish.mjs`.
|
||
|
||
### 4.7 Тесты (`tests/test.js`) — в том же коммите
|
||
|
||
- `lc1` (`1956-2010`): `SPECIES.length` 32→37, `LOCATIONS` 4→5, `costs` +`,90000`,
|
||
`names`, `sprites` 32→37, `swampOrder`, поля новых видов.
|
||
- `lc2` (`2013-2045`): `SWAMP_*` длины/порядок/пересечения.
|
||
- Новый тест роллов болота (аналог `lc4c` `2112-2132`).
|
||
- `lc5` (`2135-2171`): кейс `location:4`.
|
||
- Покупка болота — аналог `lc8c` (`2247-2259`).
|
||
- `lc9` (`2261-2266`): дневник 32→37.
|
||
- `lc10` (`2268-2290`): дополнить `mid24` swamp-видами.
|
||
- `a22d` (`2309-2326`): `ACHIEVEMENTS.length` 34→36.
|
||
- Пин `0.16` (`1648-1666`): 0.16→0.18.
|
||
- Новый data-тест: у swamp-видов есть `glow`, цвета различны, `*_WEIGHTS` покрывают все id.
|
||
|
||
### 4.8 Инструменты / доки / визуал
|
||
|
||
- `tools/balance.mjs`: таблицы болота в `TABLES`, пины в шапке; сортировать сводку
|
||
отношений по цене (т.к. 90000 < Моря/Океана, а порядок массива иной).
|
||
- `tests/gen-screenshots.js`: кадр `swamp` (день) и/или `swamp-night` со свечением.
|
||
- `AGENTS.md`, `README.md`, `docs/DEVLOG.md` («Этап 45»).
|
||
- Emoji-шрифт не трогаем (лягушки/лилии — фигуры canvas), пока не появятся новые emoji.
|
||
|
||
## 5. Порядок работ (фазы)
|
||
|
||
1. Данные: `LOCATIONS` + `SPECIES` + веса + `BOSS_BY_LOCATION` + табличный `pickSpecies`.
|
||
→ `node tools/check.mjs`.
|
||
2. Баланс: `node tools/balance.mjs` (+`--set`), зафиксировать числа.
|
||
3. Портреты: 5 SVG + `embed-fish.mjs`.
|
||
4. Свечение рыб (ambient/bite/reel, карточка/дневник).
|
||
5. Декорации: лягушки/кувшинки/лилии + фон болота.
|
||
6. Магазин/тосты/i18n/ачивки.
|
||
7. Тесты (все пины выше) → `cd tests && npm test`.
|
||
8. Доки + скриншоты + при желании `orca-playtest.js`.
|
||
|
||
## 6. Проверка (порядок команд)
|
||
|
||
1. `node tools/check.mjs`
|
||
2. `node tools/embed-fish.mjs` (сам прогонит check)
|
||
3. `node tools/balance.mjs` — пины Река/Озёра/Море/Океан не изменились, болото в цели
|
||
4. `cd tests && npm test` — все PASS, exit 0
|
||
5. Опционально: `node tests/orca-playtest.js`, `node tests/gen-screenshots.js`
|
||
|
||
## 7. Риски
|
||
|
||
1. `SPECIES` — только в конец (иначе river-пины/квесты ломаются молча).
|
||
2. `pickSpecies` табличный рефакторинг — нужен guard, чтобы не изменить роллы локаций 0..3.
|
||
3. Порядок отрисовки лилий/лягушек — строго после воды.
|
||
4. Порог свечения и производительность (`shadowBlur`/градиенты на мобиле).
|
||
5. Числовые пины тестов и `achBonus().coinPct` — обновить всё в одном коммите.
|