| 2026-09-12 |

game: мышь-ввод камеры, секция «КАМЕРА» в дев-панели, мост
...
camera.ts: CameraInput — поворот зажатой ЛКМ (setPointerCapture), колесо —
дистанция орбиты (только third person); enabled гасится в tick() в меню/
сумке/катсцене/фейде. Слушатели только на канвасе — конфликтов с клавишами
на window нет.
main.ts: движение screenMoveToWorld по yaw активной камеры (в изо —
ISO_YAW как раньше); видимость героя — одна точка на тик (в first лицо
герой скрыт, в катсцене виден); мост setCameraMode (для first — глаза
героя 10 над ногами и почти горизонтальный взгляд по умолчанию)/setOrbit;
windowInfo переписан на renderer.cameraInfo() (временный каст ортокамеры
убран).
devview/index.html: секция «КАМЕРА» (Изо/От 3-го/От 1-го + Сброс орбиты,
метка режима) по паттерну погоды. shot.mjs: флаг --cam iso|third|first.
check:fast 407 тестов; скриншоты shot.mjs --cam third/first — визуально
корректные перспектива и скрытие героя.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
8 hours ago
|

engine: спрайты и свет под перспективу (затухание по глубине, фрустумы)
...
particles.ts: общий блок makeParticlePerspUniforms() (uPxScale/uPersp/
uRefDist — все слои шарят IUniform'ы, рост ёмкости не отрывается);
createSpriteLayer теперь принимает блок вместо per-layer pxScale.
POINT_VERT: gl_PointSize = aSize·uPxScale·mix(1, uRefDist/max(w,1e-4),
uPersp) — в изо uPersp=0 и w=1: прежнее поведение бит-в-бит; калибровка
uPxScale·uRefDist = (H/2)/tan(fov/2) — точка на дистанции viewSize
рисуется в изо-масштабе, переход режимов бесшовный. QUAD_VERT не тронут.
cameraMath.ts: perspVisibleRadius(D, tanHalf, aspect, viewSize) — сечение
пирамиды для теневых фрустумов, кламп снизу ¼ изо-полуширины.
voxelRenderer.ts: applySpriteUniforms() флипает блок в конструкторе и
setCameraMode; visibleRadius() — изо легаси viewSize·max(aspect,1),
перспектива — сечение на глубине видимой земли (farG fogBandLayout под
капом дальностей). setSun/setLightning зовут его. Резкая линия включения
теней у горизонта в перспективе — известный предел (каскады вне скоупа).
index.ts: экспорт makeParticlePerspUniforms. Тесты: perspVisibleRadius,
общий persp-блок переживает рост ёмкости. check:fast 407 тестов, гейт
погоды зелёный (26 чеков).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
8 hours ago
|

engine: туман в перспективе — реконструкция глубины и след земли
...
fog.ts: fogBandLayout(mode, viewSize, pitch, eyeH, fov) — iso даёт легаси
viewSize·FOG_BAND_START/STEP точно (регрессионный замок изо-кадра),
перспектива — стопка на наземном следе фрустума: nearG = eyeH/tan(pitch+
fov/2), farG = eyeH/tan(max(pitch−fov/2, 0.05)) с капом 6·viewSize
(PERSP_FOG_FAR_K — у горизонта в 1st person стопка ушла бы в бесконечность).
FOG_FRAG: #ifdef PERSP — along из нелинейной глубины буфера
(near·far/(far−(far−near)·depth)), halfH = tanHalf·along, halfW = halfH·
aspect, разметка юниформами uBandStart/uBandStep; изо-ветка шейдера —
прежний код дословно. Дефайн PERSP переключается в render() рядом с
SRGB_OUT (needsUpdate при смене режима).
voxelRenderer.updateFogUniforms: базис активной камеры (union-ветка) +
юниформы разметки; eyeH = высота камеры над target с полом 0.5.
Тесты: изо-равенство легаси, стопка внутри [nearG, farG], кап при взгляде
в небо. check:fast 404 теста, гейт погоды зелёный.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
8 hours ago
|
engine: окно частиц пирамидой (перспективные режимы камеры)
...
polyWindow.ts: particleWindowPersp — боковые грани пирамиды через камеру
(n·δ ≤ n·d), near/far плоскости с честными смещениями, тот же polyAABB.
Контракт: окно всегда конечное — пустой фрустум (взгляд в небо, far cap
D·3 → 0) даёт вырожденный бокс в точке цели вместо ±Infinity, иначе
wrapV у осадков делит на размер окна и размножает NaN.
voxelRenderer.visibleWindow: ветка iso/persp по режиму, сигнатура без
изменений; persp: tanHalf = tan(PERSP_FOV/2), far = min(camera.far,
D·PERSP_WINDOW_FAR_K). cameraMath: экспорт PERSP_WINDOW_FAR_K = 3.
Тесты polyWindowPersp: земля перед камерой внутри, позади/под камерой
снаружи, вырожденные углы и пустой фрустум — конечное окно, far cap
режет окно. Потребители (weatherWindow, ash, ambientParticles, airFx)
не тронуты. check:fast 401 тестов, гейт погоды 26/26 (изо не сломан).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
8 hours ago
|
Режим камеры: изо / третье лицо / первое лицо в движке (шаг 1)
...
- CameraMode + чистая математика камеры (render/cameraMath.ts):
camForward, orbitPosition (переехал из modelViewer, реэкспорт),
PERSP_FOV 50°, клампы pitch/dist (грабля «из-под земли»).
- VoxelRenderer: isoCamera + perspCamera (создаётся всегда), публичное
camera — getter активной (union); setCameraMode/setOrbit/orbitState/
setEyeHeight/cameraInfo. repositionCamera ветвится по режиму:
семантика setTarget «точка интереса» сохранена — игры, зовущие его
каждый тик слежения, не ломаются, ориентация живёт в орбит-состоянии.
- Guard: окно частиц и юниформы тумана в перспективе пока по изо-камере
(до треков окон пирамиды/тумана — NaN не бывает).
- Тесты camForward/orbitPosition; окно моста — временный каст.
- Доки CLAUDE.md: API камеры.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
8 hours ago
|
Рассинхрон доков по итогам ревью: сумма снега, узлы канала, цвет вспышки
...
- сумма плотностей SNOW_BANDS 0.0415 (комментарий и CLAUDE.md говорили
0.0405 — арифметическая ошибка при удвоении слоёв).
- «58 узлов канала» → 59 (Math.round(176/3)).
- цвет вспышки — из LIGHTNING_COLOR (литерал 0xdfe8ff дублировал
константу и мог разойтись при смене).
- комментарий setArea теперь честен: камера ставится на центр тайла
входа, герой — на safeEntry (возможен сдвиг спиралью), подхват на
первом тике, а не «продолжит без микро-скачка».
- index.ts: экспортированы LIGHTNING_COLOR, weatherWindow,
RAIN_LAYERS/SNOW_LAYERS (нужны агентам/тестам наружу).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
11 hours ago
|
dispose рендера + ModelViewer, честный тест ветвей, гейт теней вспышки
...
- VoxelRenderer.dispose(): контекст GL, пост-проход, туман, свет с
shadow map; ModelViewer.dispose зовёт его — раньше каждое открытие
вьювера оставляло рендерер с тремя теневыми источниками в GL.
- тест ветвей болта больше не тавтологичен: считал «alpha < 1», что
выполнял ореол канала (0.22); теперь 2×5 бледных сегментов, спуск.
- гейт weather.mjs (+1 чек, 26 всего): тени вспышки реально рисуются —
тёмные пиксели земной трети кадра гаснут при setLightningShadows(false)
(1258 → 1028). Направление света вспышки от точки удара не зависит,
так что чек — сравнение с тенями/без, а не «переброс стороны».
- мост + VoxelRenderer.setLightningShadows(on) — диагностика гейтов.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
11 hours ago
|
Фиксы ревью демки: гарды «E», пересборка атласа, setAsh гасит молнию
...
- interact() не действует под меню: nearPick протух (тик заморожен),
случайное «E» у двери стартовало переход под панелью.
- атлас тайлей пересобирается при росте реестра (ленивая регистрация
тайлей новой области): живые меши переклеиваются на новый атлас до
dispose старой текстуры; комментарий теперь честен про кэш.
- setAsh(false) гасит активную вспышку молнии (новый LightningSystem.
cancel — огибающей некогда догорать в замершем мире) и обновляет
слайдеры панели после сброса ручной погоды.
- комментарий тика фауны приведён к коду: олени живут в фейде/катсцене
намеренно (гейты с кадр-равенством глушат fauna сами).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
11 hours ago
|
Фиксы ревью движка: параллакс тумана, dispose молнии, tint при росте слоя
...
- fog: дрейф слоёв теперь убывает с глубиной (0.42−0.05·k) — код
противоречил доку «глубокие слои медленнее» (параллакс объёма).
- lightning: dispose посреди вспышки гасит свет рендера и слой —
раньше DirectionalLight и env-подсветка дождя замирали навсегда.
- particles: обёртка слоя помнит tint и переапплаит его свежему impl
при росте ёмкости (иначе новый меш получал дефолтный белый).
- тесты: dispose молнии гасит свет; tint переживает рост (спрайты/квады).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
11 hours ago
|
Молния подсвечивает дождь/снег и туман
...
Lit-слои получали env-свет только от ambient+солнца — направленный свет
вспышки на них не действовал (ночью дождь оставался невидимым в разряд).
lightningEnvLight(k, nightK) добавляет долю вспышки (0.2) в uEnv и
uFogColor при пересчёте света в setSun: ночью дождь проявляется во
вспышку вместе с миром, туман вспыхивает тем же цветом.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
12 hours ago
|
Молния: разряд + вспышка с тенями, дебаг-кнопка «⚡ Молния»
...
Движок (render/lightning.ts): LightningSystem — strike(at?) (без точки —
случайная точка окна видимости, детерминирована номером удара), update(t)
гонит огибающую мерцания (пик + два рестрайка, 0.55 с), info(). Разряд —
излучающий слой частиц: непрерывный зигзаг (сумма двух синусов) 58 узлов
на высоту 176 (за верх кадра) + ореол и две ветви. Вспышка — отдельный
направленный свет рендера setLightning(at, k) с shadow map: свет из точки
разряда вниз с наклоном, ночью усилен (×(1+nightK)); setSun не трогает.
Игра: мост makeLightning(at?)/lightningInfo(), тик системы, кнопка в
секции погоды дев-панели. Гейт weather.mjs: +6 чеков (25 всего).
Тесты чистой части (огибающая, геометрия, жизненный цикл) — 387 ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
12 hours ago
|
Снег на 50% быстрее: 1.7 → 2.55 юнит/с
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
Капли дождя втрое быстрее: 31 → 93 юнит/с
...
Цикл падения слоя (40 юнитов) сжался до ~0.43 с — тест «колонка
неизменна внутри падения» ужат до окна 0.15 с внутри цикла.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
Дождь и снег: слоёв 3 → 6, суммарная плотность ~×1.75
...
6 перекрывающихся полос глубины (дальний 0..0.3 частый и мелкий,
ближний 0.75..1.0 редкий и крупный): ливень 6147 → 10757 капель,
снег 3074 → 5798 хлопьев. Потолки RAIN_MAX/SNOW_MAX не тронуты —
они по-слойные, макс. плотность отдельного слоя не менялась.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
Дождь и снег многослойные и втрое гуще (как туман)
...
Фидбек: «дождь сильно гуще, тоже многослойным — с туманом круто
сработало, снег аналогично». RAIN_LAYERS/SNOW_LAYERS = 3 слоя частиц,
каждый в своей полосе глубины: ближний редкий и крупный, дальний
частый и мелкий (стена дождя в глубине), полосы перекрываются —
слоистость не читается линиями. Суммарная плотность ×~3 (ливень
~6100 капель, снег ~3100 хлопьев у игры). Слои остаются lit-частицами
— свет источников и ночное гашение работают как раньше. Тесты под
новую плотность (+1 на полосы слоёв), 378 ✓; гейт погоды зелёный.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
Туман без высотного затухания: кроны и герой под туманом
...
Фидбек скрином (screens/fog.png): затухание выше y≈8 выводило из
тумана кроны деревьев (17–38) и героя (~14) — туман «строго у земли»,
деревья торчали чистыми посреди дымки. На плоском рельефе демки
«собирание тумана в низинах» ничего не добавляет — затухание убрано,
объём читается стопкой слоёв по глубине. Гейт погоды зелёный.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|

Многослойный туман по дальности от камеры + слайдер дев-панели
...
Композитный проход: сцена → RT с DepthTexture, полноэкранный квад
реконструирует мировую точку (в орто глубина линейна) и красит кадр
стопкой из 6 слоёв по дистанции вдоль взгляда ОТ КАМЕРЫ. Клубы — fbm
по мировым XZ с дрейфом ветра (глубокие слои медленнее — параллакс),
высотное затухание собирает туман в низинах; цвет — env-свет сцены
(день светло-серый, ночь тёмный). Полоты ⟂ оси взгляда забракованы
пробой-изолятом: при взгляде ~63° плоскости уходят под рельеф.
Главная грабля: d в шейдере обязан быть dot(wp − uCamPos, uCamF) —
глубиной от КАМЕРЫ; вариант от цели давал для видимых пикселей
d ∈ [−1.12·V, +1.12·V] при слоях на 2.5..5·V — все smoothstep'ы
нули, туман полностью прозрачен (изолят маскировал: камера ближе).
Попутно чинит pow-граблю из 55876f8: степень PARTICLE_LIT_GAMMA из TS
в GLSL-шаблоне печаталась «2» (int) — pow(int) не компилировался в
GLSL ES, lit-слои частиц (дождь/снег/пепел/листья/пыль) молча не
рисовали; в GLSL-шаблоны числа из TS — через .toFixed(1).
WeatherSpec.fog (0..1), база прудов 0.3; 6-й слайдер «туман» в дев-
панели. Гейт weather: 19 проверок (+6 туман: рисуется, глубинный
градиент, дрейф, ночь тёмная, слайдер панели). check:fast — 377 ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|

Освещаемые частицы в темноте ещё темнее: квадрат видимости + гашение цвета
...
Фидбек: «освещаемые партиклы в темноте сделаем ещё темнее». Две правки
ветки #if LIT шейдера частиц:
1) vis гасит и цвет, и альфу: vColor*(uTint*vis + received) — раньше
гасилась только альфа, цвет оставался полным, и полупрозрачные СЕРЫЕ
точки читались на тёмном фоне;
2) кривая видимости нелинейная: vis = clamp((max-канал(received)*1.6)^2) —
степень давит слабый свет (ночь received ~0.05-0.1: линейная кривая
оставляла vis ~0.1), а день/лампа по-прежнему насыщают vis в 1.
Чистая функция litVisibility(maxChannel) зеркалит шейдерную кривую —
тесты без WebGL (371). Замер пробы (пара кадров ночью «дождь вкл/выкл»,
пиксели ярче фона): 815 -> 641 (гашение цвета) -> 10 (квадрат); день
не изменился (дождь 101 -> 100), мотыльки (излучающие) светятся как
раньше (961 тёплых px).
Гейт weather «облачность темнит кадр» ослаблен до x0.93: зенитный свет
пасмурного дня (fd7a331) намеренно добавляет освещённости — падал и до
этой правки (воспроизведено на старом шейдере, цифры те же).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
14 hours ago
|

Два вида частиц: излучающие и освещаемые сценой (lit)
...
Живучий баг «частицы светятся одинаково при любом освещении»: теперь
режим — свойство слоя. renderer.addParticles({lit: true}) — освещаемый
слой: полученный свет (env-свет сцены + точечные источники) правит и
цветом, и видимостью (альфа = clamp(max-канал·PARTICLE_LIT_VIS)) — ночью
в темноте частица исчезает, у лампы/фонарика проявляется, днём вид как
раньше. Излучающий режим (по умолчанию) — прежняя формула.
- particleEnv(amb, sun) — чистая функция env-света (ambient + доля
солнца PARTICLE_ENV_SUN 0.3: у билборда нет нормали); рендер
пересчитывает uEnv в конце setSun — туда сходятся все изменения света;
- игра: lit — дождь/снег (WeatherSystem.setTint удалён), пепел,
листья/пыль; tint остался самосветящимся: мотыльки, дымка, блики.
Ручной ночной tint был подменой реакции на свет — больше не нужен.
Замер в игре: дождь день 101 / ночь 14 яркости, в луче фонарика капли
проявляются; мотыльки ночью светятся как раньше. Тесты 368 ✓ (+particleEnv),
гейты atmosphere/weather/panels ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
14 hours ago
|
Пасмурная «тенька сверху»: зенитный свет с контактной тенью
...
В облачный день свет рассеян и переотражается так, словно есть доп свет
прямо сверху. Второй DirectionalLight в зените (кастер тень вбок не
смещает — фрустум только на видимую область) даёт минимальную тень ПОД
объектом, куда косые лучи солнца не достают, и чуть подсвечивает
горизонтальные грани (пасмурный «молочный» свет).
- zenithIntensity(cloudK, nightK, daySunScale) — чистая функция,
OVERCAST_TOP_LIGHT = 0.55; ночь и тёмный интерьер гасят вместе с небом;
- мягкость общая с солнцем (shadowSoftK), пересчёт в setSun;
- в игре: у деревьев/валунов/героя в пасмурный день мягкий ореол у
основания, направленные солнечные тени исчезают.
Тесты 368 ✓, гейты atmosphere/weather/panels ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
14 hours ago
|
Контраст теней: setShadowStrength + облачность светлит тени
...
Рассеяный свет освещает затенённые места со всех сторон — в пасмурный
день тени не только мягче (3ba9b1d), но и светлее. Ручка —
sun.shadow.intensity (three 0.186: mix(1.0, shadow, intensity) в шейдере):
- shadowIntensity(strength, cloudK) — чистая функция: сила тени гасится
облачностью множителем 1 − k·SHADOW_CLOUD_FADE (0.45);
- setShadowStrength(k) — ручное управление (0 — тени исчезают);
- setCloud по умолчанию тянет контраст вниз (не перезаписывает силу,
в отличие от мягкости); пересчёт в setSun — переживает тики света.
Замер на изоляте (земля + куб): контраст свет/тень 3.6 в ясный →
1.5 в пасмурный. Тесты 361 ✓, гейты atmosphere/weather ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 hours ago
|
Мягкость теней: setShadowSoftness + облачность рассеивает тени
...
Движку нужна ручка резкости теней: облачность гасила солнце, но тени
оставались резкими, хотя рассеяный свет даёт мягкую полутень.
Механика: PCF three (0.186) масштабирует диск сэмплов Вогеля
shadow.radius'ом — мягкость без смены типа shadow map. Радиус в текселях
считает чистая функция shadowBlurTexels(k, frustumHalf, mapSize) из
мирового размытия (0..SHADOW_BLUR_MAX = 3 юнита) — зум и высота солнца
меняют фрустум, мировое размытие постоянно (setSun пересчитывает тексели).
API: VoxelRenderer.setShadowSoftness(k) (0 — резкие, ручное поверх);
setCloud(k) тянет мягкость своим k — пасмурная погода даёт диффузные тени
без правок игрового кода. Замер пробы: резких краёв на кадре 14101 → 6614
при облачности 1. Тесты функции — 4, check:fast 357 ✓, гейты
atmosphere/weather ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 hours ago
|
Дев-панель не ставит игру на паузу: мир и время живут при открытой панели
...
Раньше тик при dev.open выходил рано — стояло всё, кроме погоды. Теперь
панель — просто оверлей: часы/свет/фейд/катсцена/фауна идут, правки
слайдеров видно в живой игре. Метка часов панели обновляется каждый тик
(новый refreshClockLabel — только текст, слайдер не трогается, чтобы не
мешать тянущему его; полная синхронизация осталась на открытии и
перемотках). Пауза осталась только у меню и сумки. Гейты panels/weather ✓,
check:fast — 353 теста.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 hours ago
|
Свет частиц читается: a² вместо a³ + конус фонарика 2.2× для объёма
...
Диагноз: реакции частиц на свет были перцептивно нулевыми при исправной
проводке. Точечные источники: кубический фоллофф концентрировал вклад в
внутреннем ~10% радиуса (среднее a³ по сфере ≈ 1/60) — изолят с игровыми
условиями давал +1.4% яркости. Фонарик: тонкий горизонтальный луч едва
пересекает видимый ортокамерой слой — ~20 капель (76 px diff), глаз не
ловил; подтверждено хирургическим A/B в живой игре (flip uSpotOn при
замороженном времени).
Фикс: квадратичный фоллофф точечных источников в LIGHT_FRAG (капли в
пятне лампы тёплые и яркие), конус спота для частиц в 2.2× шире
поверхностного с клампом полуугла (луч читается светящейся цепочкой
капель). Гейт atmosphere/weather ✓, check:fast — 353 теста.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
17 hours ago
|
Осадки: ускорение ×1.4 и глубина (план даль/близь)
...
Фидбек: дождь и снег медленные, выглядят плоско. Скорости ×1.4
(дождь 31 юнит/с, снег 1.7). Глубина: камера ортографическая, параллакса
нет — глубина симулируется расхождением параметров частицы от стабильной
глубины d∈[0..1] (sin-хэш, уклон в дальний план): дальнее меньше/
медленнее/бледнее (аэроперспектива), ближнее крупнее/быстрее; у дождя
дальние штрихи короче, у снега ближние качаются шире. Снежинка несёт
свой размер в позах (раньше размер слоя был фиксированным). Тесты
респавна переведены на фазовый скан (скорость теперь пер-частица),
добавлен тест разброса планов. 352 теста, гейт weather ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
17 hours ago
|
Фикс #218: рост ёмкости слоя частиц не плодит замороженные меши
...
Редирект layer.update = fresh.update при росте ёмкости ломался, когда
держатель слоя (WeatherSystem) снял методы заранее: ссылка навсегда
указывала в замыкание старой реализации, каждый тик сверх ёмкости
создавал новый слой с однократной записью — замороженные снимки дождя
копились в сцене (пелена на весь экран, ~46 слоёв).
Теперь createSpriteLayer/createQuadLayer держат стабильный фасад:
публичный объект один на всю жизнь слоя, при росте подменяется только
внутренняя реализация, первый кадр после роста рисуется сразу.
Регрессия particleLayers.test.ts (метод снят заранее — меш один).
Живой прогон: veil% 3.6→13.5 (накопление) → стабильные 0.07-0.09.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
18 hours ago
|
Дождь/снег: респавн — полный реролл колонки, трек не остаётся на экране
...
Сдвиг колонки при респавне в узкой окрестности якоря (±20 юнитов) оставлял
каплю падать в одной и той же полосе: трек «горел» на экране вечно, а поле
колонн было квази-статично в мире — кадры, разнесённые на полный цикл
падения, совпадали. Теперь sin-хэш от номера цикла растягивается на большой
период (RAIN_SPAN 731 / SNOW_SPAN 613) — капля перебрасывается по всему
периоду. Колонка внутри падения неизменна (капля падает по прямой).
Тесты: переброс ≥80% капель за цикл, стабильность колонки внутри падения.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
19 hours ago
|
Тесты света частиц (packParticleLights/фонарик) — упущены прошлым коммитом
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
19 hours ago
|
Лок fps: селект 30/60 вместо чекбокса — потолок 60 при rAF 60 Гц неотличим
...
Фидбек «unlocked 60 = locked 60»: лимитер применялся верно (замер живой
страницы: лок 30 даёт ровно 30 fps), но потолок, равный герцовке rAF,
пропускает каждый кадр (порог 16.7−1 мс) и по построению совпадает с
«без лока». Осмысленный демо-лимит обязан быть ниже герцовки — секция
«ЦИКЛ» стала селектом (без лока / 30 / 60), мост devSetFpsLock принимает
лимит, fpsInfo.lock — число. Тесты цикла: поправлено неверное ожидание
«первый кадр после setMaxFps проходит» (до 33.3 мс — пропуск) + сценарий
120 Гц rAF: лок 60 рендерит вдвое реже. Гейт panels синхронен.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
19 hours ago
|
FPS-счётчик в правом верхнем углу + лок 60 fps в дев-режиме
...
- движок: GameLoop.setMaxFps(fps) на живом цикле (0 — без лимита;
lastFrame сбрасывается, чтобы без лока не ждать интервала) — тест
на живом цикле с инъекцией времени
- игра: #fps в правом верхнем углу (сводка раз в 0.5 с, z-index выше
дев-панели); в панели секция «ЦИКЛ» — чекбокс «лок 60 fps»
- мост: fpsInfo() (fps + lock), devSetFpsLock(on) — применить и
синхронизировать чекбокс
- гейт panels: счётчик показывает кадры, угол виден, лок и чекбокс
синхронны (грабля: headless троттлит rAF — мерить «fps > 0»)
Тесты 345 ✓, гейт panels ✓, гейт weather 14 ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
19 hours ago
|