| 2026-09-12 |
Режим камеры: изо / третье лицо / первое лицо в движке (шаг 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
14 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
16 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
16 hours ago
|
Фиксы ревью демки: гарды «E», пересборка атласа, setAsh гасит молнию
...
- interact() не действует под меню: nearPick протух (тик заморожен),
случайное «E» у двери стартовало переход под панелью.
- атлас тайлей пересобирается при росте реестра (ленивая регистрация
тайлей новой области): живые меши переклеиваются на новый атлас до
dispose старой текстуры; комментарий теперь честен про кэш.
- setAsh(false) гасит активную вспышку молнии (новый LightningSystem.
cancel — огибающей некогда догорать в замершем мире) и обновляет
слайдеры панели после сброса ручной погоды.
- комментарий тика фауны приведён к коду: олени живут в фейде/катсцене
намеренно (гейты с кадр-равенством глушат fauna сами).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
16 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
17 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
19 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
20 hours ago
|
Дев-панель не ставит игру на паузу: мир и время живут при открытой панели
...
Раньше тик при dev.open выходил рано — стояло всё, кроме погоды. Теперь
панель — просто оверлей: часы/свет/фейд/катсцена/фауна идут, правки
слайдеров видно в живой игре. Метка часов панели обновляется каждый тик
(новый refreshClockLabel — только текст, слайдер не трогается, чтобы не
мешать тянущему его; полная синхронизация осталась на открытии и
перемотках). Пауза осталась только у меню и сумки. Гейты panels/weather ✓,
check:fast — 353 теста.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
20 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
1 day 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
1 day ago
|
Погода: плотность осадков на площадь окна, дождь — штрихами
...
Ливень при rain=1 выглядел как редкая субпиксельная пыль: окно слоя
[0,40] (след кадра до дальней плоскости) при камере игры (viewSize 80,
far 800) — 342×342 юнита, а 260 капель с фиксированным счётчиком
размазывались по нему (капля 0.5 юнита при 3.3 px/юнит — 1.7 px).
- счётчик капель/снежинок — плотность на кв. юнит окна (RAIN_DENSITY
0.016 / SNOW_DENSITY 0.007, потолки RAIN_MAX/SNOW_MAX): зум камеры
не меняет видимую плотность; info() отдаёт фактические счётчики
- капля рисуется штрихом — цепочкой из 3 точек над головой (хвост
бледнее и тоньше), размер поднят до 0.55/0.7 юнита
- мост: windowInfo(y0, y1) — окно видимости частиц + параметры камеры
(диагностика плотности агентом)
Тесты 344 ✓ (число точек = плотность × площадь окна; счётчики после
update), гейт weather.mjs 14 ✓ (ливень — стена капель >1000).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day 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
1 day ago
|
Свет частиц: точечные источники и фонарик подсвечивают слои частиц
...
- Движок: общий блок юниформ света на рендере (packParticleLights,
setParticleLights), шарится ссылками между слоями; шейдерный вклад
ламп/конуса умножается на цвет частицы, ×2 на согласование с GAIN-пулами.
- Игра: GameLighting отдаёт снапшот источников + конус фонарика каждый тик;
снапшот моста — lightingInfo.particleLights.
- Гейт atmosphere +2 (день 0 / ночь = источникам), 332 теста.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
Озёра утоплены, деревья крупнее, манекен 8×12×4, теневой фрустум по кадру, частицы в системе освещения
...
- Вода: яма y=1 пуст / вода y=0; непроходимость — physicsWorld
(невидимый коллайдер над ямами); декор на воде не штампуется.
- Деревья: стволы 25-38, кроны 17-24, чанк 64.
- Манекен 8×12×4 (134 вокс, 19 тайлей — детализация на текстурах),
снаряжение пропорционально меньше (рюкзак 40 / факел 4 / фонарик 16).
- Тени: динамический фрустум в setSun (visible·aspect + высота кастера),
mapSize 2048 — граница включения теней больше не видна.
- Частицы: uTint в ParticleLayer, ночной тинт PARTICLE_NIGHT,
размеры уменьшены (пепел/листья/пыль/дымка/мотыльки).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
Тьма за краем карты, деревья крупнее, солнце едет по часам, фонарик героя
...
- Бездна: неосвещаемая плоскость под миром — за границей области тьма
в любое время суток.
- mapTreeModel: сетка 12×12, стволы 22–36, крона до r≈5; высота чанка
мира 52→64 (дерево до 53 не влезало).
- Солнце: движок умел setSun(k), но игра не вызывала — тени стояли на
полудне. GameLighting зовёт setSun((часы−6)/12) каждый тик; снапшот
моста — sunK. Гейт детерминизма областей пинит часы перед кадрами
(солнце едет каждую игровую минуту — кадры в разные минуты различны).
- Фонарик: движок addSpotLight (SpotLightHandle setTarget) +
flashlightModel (2×2×5); игра — крепление в левой руке (armL,
зеркально факелу), конус по hero.yaw ночью/в темноте, снапшот
flashlight.on/intensity; gear по умолчанию 110 вокс.
- Доки v2/CLAUDE.md: трек 34 + генераторы/прожектор.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-09-11 |
Фидбек: вьювер крутит вокруг центра модели, точечный свет ярче, реестр объектов
...
- modelCenter (движок): ось орбиты ModelViewer — центр bbox занятых
вокселей, а не угол сетки; экспорт из index.ts, тест на углы.
- Точечные источники: three r155+ считает PointLight в физических
единицах — POINT_LIGHT_GAIN=8 в addPointLight И setIntensity
(мерцание каждый кадр затирало усиление — свет оставался тусклым).
- Реестр объектов игры (apps/game/src/registry.ts): каталог дев-вьювера
собирается сам из мест создания (areas/main/fauna), без ручного
списка; devview только рисует DOM. 20 записей, id стабильны —
гейт panels без изменений.
- Доки v2/CLAUDE.md: трек 33 + структура modelViewer/addPointLight.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|

Трек 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
|
Трек 31: пост-обработка движка (RT + полноэкранный квад) и воздух области
...
- Движок: VoxelRenderer.setPostPass (сцена в RT NearestFilter 1:1, затем
квад на экран; PostPassHandle {uniforms, dispose}) + сборщик postPass
({vignette?, grain?, wobble?}); uTime заводится рендерером всегда.
Детерминизм гейтов: зерно статично (хэш по координатам), анимируется
только дисторсия через uTime.
- Игра: PostFx (виньетка 0.32→0.5 к ночи, зерно 0.02, дисторсия жары
0.004 в зале Машины — проход пересобирается в setArea, active=ashEnabled);
AirFx (листопад рощи 26 шт с покачиванием, пыль разъезда 40 шт —
взвесь с edgeAlpha в марже окна видимости); карта AIRFX в данных;
ambientInfo.air.
- Гейт atmosphere +5 проверок (виньетка по зонам кадра, листья, пыль);
гейт panels: статы манекена синхронизированы с треком 29 (19 тайлей).
317 тестов, 7+11 гейтов зелёные.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|

Слой частиц движка: спрайты/плоские квады + окно видимости камеры
...
Частицы больше не воксели: отдельный 2D-слой поверх мира (THREE.Points
билборды и InstancedBufferGeometry квады в XZ), без освещения и теней.
Окно видимости частиц — точный AABB сляба ортокамеры на слое [y0,y1]
(polyWindow, перебор вершин полиэдра). Пепел/мотыльки/дымка/блики воды
переведены на слой: частицы живут в мировых координатах, окно камеры
заворачивает их с маржой за экран, в марже альфа гаснет — без появления
из воздуха. Окно покрывает весь кадр с перекрытием.
Движок: particles.ts (ParticlePoint/ParticleLayer, createSpriteLayer/
createQuadLayer, addParticles/addFlatParticles), polyWindow.ts,
visibleWindow(y0,y1), 4 теста (симметрия следа, покрытие окна,
сдвиг от высоты, вырожденность). Игра: particlesWindow.ts (маржа,
wrap, edgeAlpha), миграция ash/ambientParticles/waterShimmer,
setAsh пересобирает частицы области.
Грабли: знаки полуплоскостей n·δ≤b; AABB в дельтах — прибавлять target;
окно без кэша (едет за камерой); квады на воде — над гранью y=3;
fresh.update после роста ёмкости; скорости по v1 (px/s ÷ 32).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
Трек 29: редизайн мира + текстурный слой на world-меше + скины
...
Движок: слой тайлей мира (Chunk.tex / VoxelWorld.getTex/setTex, мешер
texAt → per-vertex tiles/uvs, stampModel с opts.texRemap), рендер —
worldTileAtlas (общий атлас чанков, шейдерная инъция общая с облаком).
Манекен: скины деталей (подол/застёжка/подошвы, пряжка — слот metal).
309 тестов (+6), все 18 гейтов зелёные.
Игра: редизайн строений (дом — 3 стиля стен по сиду + tall, круглые
башня и колодец с воротом, клёпаная Машина), природа (валун-купол
с трещиной/мохом, высокий и малый кусты — варианты по сиду), олень.
Скины домов (houseTexture: кладка/доски/штукатурка/дранка/дверь) и
персонажей идут через реестр worldTex с дедупликацией тайлей по
контенту. Палитра мира дополнена слотами 18-23. Гейты areas/interact
поправлены под UNIT=10 (устаревшие константы), props — центр тайла.
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
2 days ago
|
| 2026-09-10 |
Текстурный слой моделей + манекен 10×16×4: деталь на текстурах, не геометрией
...
Формат: тайли пиксель-арта на грани вокселя (VoxelTile, тексель = слот
палитры — перекраска красит и текстуры) + tex (id тайля на воксель);
encodeModel(g, palette, texture?), texIdAt/texBytes/resolveTiles,
числовая валидация слоя. Рендер: addVoxelCloud(voxels, tiles) — атлас
(ячейка = 6 суб-граней тайля, 0 белая), aTileId + шейдерная инъция
(грань куба из нормали). Манекен: 14×24×8 (498 вокс) → 10×16×4 (164);
лицо — арт 8×8 текселей (бахрома/глаза/рот) на фасаде головы, волосы —
макушка и затылок. Игра: BODY_SIZE [5,16,5], stride 9.6, облака с
resolveTiles. Порог маха anim-гейта 1.0→0.8 (ноги вдвое короче).
6 гейтов игры + 11 демок зелёные, 300 тестов.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|

Дизайн персонажей v3: детализированный манекен 14×24×8 с лицом
...
Манекен движка 9×16×4 → 14×24×8 «путник» (~2.4 тайла, 498 вокс):
торс силуэтом (юбка плаща, пояс, грудь, плечи), рукава с кистями
кожи, сапоги с мысками, шея, голова с глазами, носом и волосами.
Палитра 8 слотов: MannequinPalette {skin?, hair?, torso?, legs?,
arms?, boots?, belt?, eyes?} — глаза отдельным тёмным слотом
(не от ремня). Череп ступенькой: фасад лица до y21, шапка волос
назад до z4 — иначе с игрового ракурса (~55° сверху) шапка прячет
глаза (луч к фасаду проходит через воксель уровнем выше).
Игра: палитры героя и NPC под новую модель (Ирвину тёплая кожа —
кожа в тон седине читалась как череп), BODY_SIZE [5,24,5],
stride 12.8 (каденция 1.64 цикла/с). Аним-лист под манекен 14
шириной (PITCH 18, подставки 14×14); combat-гейт — кучка для
визуального кадра спавнится в стороне от тела героя.
Все 6 гейтов игры + 11 демок зелёные, 297 тестов. Тулза
probe-hero.mjs — проба позиции героя через мост.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|
Дизайн персонажей и объектов, персонажи мельче (трек 24)
...
- Манекен движка 11×21×4 → 9×16×4; новое API mannequin(palette?):
MannequinPalette {torso/legs/head/arms} красит слоты, форма не зависит
- Палитры героя и NPC (NpcDef.colors); олень мельче (~10 вокс)
- Дом: двускатная крыша коньком вдоль X, деревянная дверь на видимом
фасаде, труба; дерево: крона с профилем (низ вздут, ель ярусами)
- Гейты anim.mjs под мелкий манекен (diff фаз 40, подъём стопы 0.7);
тулза crop-zoom.mjs — зум-кроп снимка для визуальной проверки
6 гейтов игры + 11 демок зелёные, 296 тестов.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|

Масштаб UNIT 5→10, детализация манекена 11×21×4, частицы из мира
...
Фидбек: «частицы летают вместе с персонажем, как приклеенные»;
«персонажи низкодетализированные, не читаются; объекты всё ещё
сильно меньше — масштаб поднимать кардинально».
- Частицы (пепел, мотыльки) отвязаны от камеры: мировой якорь +
дрейф, окно камеры заворачивает (wrap) — при движении героя
частицы стоят на месте в мире.
- 1 тайл v1 = 10×10 вокселей: генераторы областей и пропы подросли
(дерево ~30–38 со стволом 2×2, дом 24×30–40×18 — вдвое выше героя,
башня 47, Машина 24×34×18), высота мира 52, стены интерьера 13.
- Манекен движка 5×11×3 → 11×21×4 (голова-куб, торс, руки/ноги 2×2 —
силуэт читается; 220 вокселей; тест связности — BFS по
6-связности). Герой 2.1 юнита/с (stride 12.8 — темп v1), камера
viewSize 80 (охват 8 тайлов), радиусы интеракта 15, олень ~13 вокс.
- Гейты переведены на новую геометрию: все 6 игры + 11 демок
зелёные, 295 тестов.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|
Масштаб мира UNIT 3→5: герой ≈ 2 тайла, скорость 2.1 юнита/с
...
Фидбек «персонажи крупнее деревьев и соразмерны домам»: 1 тайл v1 =
5×5 вокселей. Генераторы областей и пропы подросли под тайл 5×5
(дерево 17–23 вокс ~2× героя, дом 12×14–18×9, башня 21, Машина
12×17×9, стены интерьера 8); олень ~9 вокс. Герой 2.1 юнита/с
(stride 6.4 — темп v1), олени 0.45/1.0 юнита/с. Камера viewSize 40 —
тот же охват 8 тайлов; тени/дистанция масштабируются от viewSize сами.
Гейты переведены на новую геометрию (центр тайла tile*5+2.5,
spotVoxel tile*5+2, подходы ±5); 6 гейтов игры + 295 тестов зелёные.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|
Трек 20: катсцены как данные — CutsceneRunner в движке
...
- Движок: core/cutscene.ts — жанронезависимый рантайм (стек шагов
{dur, fn?, cam?}, глайд камеры по инъекции CutsceneCamera, действие
шага может перезапустить сцену) + validateCutscenes; 8 юнит-тестов
- Игра: data/cutscenes.ts — метки точек камеры тайлами v1, именованные
действия, реестр 3 сцен; resolveCutscenes валидирует при старте;
main.ts — runner вместо inline-катсцен, мост playCutscene(id)
- Гейт cutscenes.mjs: dry-run каждой сцены до конца, камера к герою
- Все 6 гейтов игры зелёные, 295 тестов
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|
Полировка игры: меню/автосейв, виньетка наката, мотыльки/дымка, шиммер воды
...
- Меню (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 |

Ревью-раунд: багфиксы движка и игры
...
Системный поиск ошибок (ревью движка + сверка с v1 + стресс рантайма).
Игра: тема лугов не останавливалась и наслаивалась (GameAudio держит хендл
лупа и кроссфейдит); «E» сквозь катсцену/фейд по протухшим целям; порядок
диалогов NPC как в v1 (незнакомый — всегда first); «E» — ближайшая цель с
приоритетом при ничьей (v1 pickInteract); радиус NPC 4.5; скорость героя
5.25 вокс/с (v1 1.75 юнита/с); колокольчик в сумку при сборе; ночной свет
колокольчиков следует за полем (живой слой тайлов); пустой return-стек —
фолбэк на спавн (фейд не зацикливается); кэш декода RLE (isFlower 25/тик);
камера входа в область без округления (микро-скачок).
Движок: stepTick вне ручного режима = 0 (защита от двойных шагов);
addComponent на мёртвой сущности = undefined; dispose закрывает AudioContext
и гасит все лупы (Loops.stopAll — свободные слоты playLoopBuffer раньше не
останавливались никогда); validateDialogue — kind в do[] узла и циклы
узлов-действий; DialogueRunner — реентрантность abort/start в эффектах;
dayNightFactor без NaN на вырожденных границах; remapSlots с пустой
палитрой без TypeError. Тесты 281→287, все 5 гейтов зелёные.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
3 days ago
|