| 2026-09-12 |

Многослойный туман по дальности от камеры + слайдер дев-панели
...
Композитный проход: сцена → 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
16 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
21 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
22 hours ago
|

Погода в движке: дождь, снег, ветер, облачность
...
Движок (packages/engine):
- WeatherSpec (windDir/windStrength/cloud/rain/snow), clampWeather,
windVector; weather.ts — WeatherSystem на слоях частиц (addParticles):
окно осадков = след кадра + маржа, wrap, альфа у края; дождь —
тяжёлая капля (дрейф ветра ×0.6), снег — покачивание + полный дрейф
- VoxelRenderer.setCloud: гашение солнца (×1−0.6k), облачный тинт
ambient/фона через cloudDim (обесцвечивание + затемнение), встроен
в setNight (lastNightTint пересчитывается)
- agent-lib: startDevServer показывает stderr vite при падении
Игра: погода по областям (AREA_WEATHER) + ручной режим дев-панели,
переживает смену области; setAsh(false) глушит погоду (гейт-режим);
в тике погода анимирует даже при открытой панели. Мост: weatherInfo,
setWeather (merge/сброс), devSetWeather. Дев-панель: слайдеры
облачность/дождь/снег/ветер/направление, счётчики капель и снежинок.
Гейт tools/checks/weather.mjs — 14 проверок (базы областей, ливень/
снег падают, облачность темнит, панель, глушение). 343 теста ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
22 hours ago
|
| 2026-09-11 |

Трек 32: крепления предметов к костям риги — рюкзак и факел на герое
...
- Движок: attach.ts — Attachment {bone, model, pos?, rot?}: предмет
(обычная VoxelModel со своей палитрой) размещается в связочном
пространстве базы и едет с костью (boneWorlds); attachVoxels мержит
воксели предметов в позу, attachTiles — общий реестр тайлей со сдвигом
id за базу. Неизвестная кость — throw. Тесты: предмет едет ровно как
воксель кисти (равенство сдвигов 1e-9), тайли, детерминизм.
- Генераторы: backpackModel (84 вокс, пряжка — перекраска, не добавление),
torchModel (6 вокс), палитра GearPalette.
- Character: CharacterOptions.attachments + setAttachments; visual()
мержит attachVoxels до yaw-маппинга — предмет поворачивается с моделью.
- Игра: герой с рюкзаком (root, за спиной) и факелом (armR, машет с
рукой); мост heroGear(ids|null) + heroInfo.gear/gearVoxels. Гейт
gear.mjs (6 проверок): счёт 90/84/0, снятие меняет кадр, ходьба цела.
- Багфиксы, найденные пробой: пост-проход затемнял день ~втрое (RT
хранит linear, квад рисовал без linearToOutputTexel — конверсия сразу
после сэмпла, до эффектов; тест на порядок) и дев-панель была видна
с самого старта страницы (#dev[hidden]{display:none}).
326 тестов, гейты gear/atmosphere/panels/render зелёные.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
Дев-панель: управление временем суток (слайдер + пресеты)
...
Секция «Время суток» сверху панели F3: метка часов, слайдер 0..1439,
пресеты 8:00/12:00/18:54 (пик золотого часа)/22:00. Перемотка дёргает
clock.set + lighting.update — свет пересчитывается сразу. Панель — мир
на паузе (как в диалоге), время течёт после закрытия; при открытии
слайдер синхронизируется с часами. Мост: devSetClock, devInfo.clock.
Грабля: список объектов выталкивал секцию за край — панель flex-колонка,
объекты скроллятся. Гейт panels +3 (24 проверки), 317 тестов.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
Трек 28: лоад-скрин, слоты сейвов, панель сумки, фикс застревания в доме, ModelViewer + дев-панель
...
- баг: дома шире тайла — safeEntry ищет свободную позицию спиралью (collides)
- лоад-скрин #loading до первого кадра
- меню: слоты auto + s1..s3 (сохранить/загрузить/удалить), мост menuInfo.slots/saveTo/loadFrom/saveDelete
- панель сумки по I (#bag), мир стоит; мост bagInfo/toggleBag
- движок: ModelViewer (орбитальная камера, клипы, turntable, статы modelStats; юнит-тесты орбиты/статов)
- игра: дев-панель F3 (каталог 14 объектов, скины, вьювер), мир стоит
- гейт panels.mjs (21 проверка), пробы probe-house/probe-load/probe-dev
- доки: CLAUDE.md (структура + трек 28), plan.md, 303 теста, 18 гейтов зелёные
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-09-10 |
Полировка игры: меню/автосейв, виньетка наката, мотыльки/дымка, шиммер воды
...
- Меню (Esc) + автосейв/«Продолжить» (движковый SaveManager): GameSave —
полный снапшот сюжета (область/тайл, флаги+вары, сумка, часы, правки
цветков до setArea); страница стартует в меню — гейтам startGame(false)
- Виньетка опасности + пелена наката (screenFx, DOM-слои)
- Атмосферные частицы v1 Atmosphere: мотыльки лугов, дымка прудов
(клочья на якорях клеток воды); шиммер — редкие блики на прудах
- Мост: ambientInfo, menuInfo, startGame(load); shot.mjs — startGame
- Грабли: castShadow после пересоздания облака, z-fighting копланарных
кубов над world-мешем (EPS 0.03), зомби-vite по PID, encodePng Buffer
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
3 days ago
|
| 2026-09-09 |
Фидбек: канвас под окно, плавная камера, поворот оленей, пропорции мира
...
- Канвас тянется под окно (CSS 16:9), бэкинг-стор 960×540 (pixelated).
- Камера следует за героем по float-цели без округления — дёрганье ушло;
глайд катсцен тоже без квантования.
- Олень поворачивается мордой по ходу движения (rotXZ, 4 четверти).
- Пропорции: деревья/дома/башня/Машина выше юнитов (герой 10 вокселей);
высота чанка мира 16 → 20 (дерево до 15 + GROUND_Y).
- Мост setFauna(false) для кадр-равенств (олени бродят в реальном
времени до setManual — флейк детерминизма areas); гейту areas нужен
stepTicks(1) после setFollow(false) — ручной режим не перерисовывает.
- Меню зафиксировано в треке 21 плана (замечание пользователя).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
3 days ago
|
Игра: разрешение 960×540 и отдаление камеры (viewSize 24)
...
Бэкинг-стор канваса теперь совпадает с CSS-размером (масштаб ×1,
пиксели резкие), viewSize 17 → 24 — камера видит больше поля.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
3 days ago
|

Трек 16: NPC и квестовый каркас — диалоги/квесты v1 в игре на v2
...
Контент «Пепельных луга» 1:1 из v1: реестры FLAGS/VARS, 7 предметов,
NPC (Ирвин/Мила в Звенце, Клинт в роще по флагу act2_hook), 9 диалоговых
графов (JSON + validateDialogue при старте), квесты как стадии с
doneFlag/ready/progressKey, GameState (DialogueState движка).
Сцена: NPC-манекены с точками взаимодействия (E — Поговорить), выбор
графа — квест-стадия → repeat → dialogueFirst; в диалоге мир замер;
эффекты графов исполняет игра (сумка, тосты); HUD — трекер квеста,
сумка, тосты. Мост: npcInfo/talkTo/dialogueInfo/dialoguePick/
dialogueAdvance/dialogueAbort/setState/stateInfo.
Движок: экспортирован evalConditions (ready-условия стадий — те же
предикаты, что в графах диалогов).
Гейт tools/checks/npc.mjs — 27 проверок (раскладка NPC v1, появление
Клинта по флагу, выбор графа по стадиям включая сдачи, выбор ответа,
сумка, флаги, трекер, motes_note, мир замер, панель диалога).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
3 days ago
|

Трек 15: карты и области — игра «Пепельные луга» на v2 (apps/game)
...
Новое приложение v2/apps/game (демка не тронута — её 11 гейтов завязаны
на сценку): воспроизведение демо-среза v1 по референсу.
- tools/convertMaps.mjs — конвертация карт v1 (RLE) → src/data/maps.json;
раскладка тайлов v1 переносится данными (позиции NPC/переходов сходятся)
- src/areas.ts — генератор мира области: 1 тайл v1 = 3×3 вокселя,
земля y0-1, вода слоем y=2 (непроходима, как v1 blocked), штампы
объектов — компактные генераторы строго в тайл 3×3 (mapTree/mapBush/
mapBoulder — крона не вылезает на соседей) + дома/колодец/башня/
машина/рельсы/стены/декор; всё детерминировано
- src/data/areas.ts — 8 областей с переходами v1 1:1: step (вход на
тайл-триггер), click («E» у двери/колодца), 'return' — стек возврата
- src/main.ts — мир области пересоздаётся на переходе, герой-манекен,
фейд out→swap→in (#fade), подсказка «E — …» (#hint), камера follow
- мост: setManual/stepTicks/heroInfo/heroTeleport/setInput/setFollow/
setSun/areaInfo/gotoArea/solidAt/interact/interactInfo
- гейт tools/checks/areas.mjs — 16 проверок: детерминизм пересборки,
blocked (3×3 под-колонки), зажим у грани воды, step-переходы
луга⇄Звенец/луга⇄пруды, люк→зал→return по стеку, click «E», интерьер
- доки: v2/CLAUDE.md (game-блок, грабли: экранная ось (1,0) — диагональ
мира и срез триггера; штампы шире тайла), plan.md (трек 15 закрыт)
check:fast: 261 тест, typecheck engine+demo+game.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
3 days ago
|