| 2026-09-07 |
UX-пачка: подсказки, клик-зоны, моты, коллизия домов, сундук, тихая вода
...
- Тосты держатся по длине текста (до 6 с) + подсказка сбора колокольчиков
при первом входе в пруды (флаг hint_bells).
- Клик по «телу» объекта: RouterDeps.pixelTile как фолбэк на голом клике —
bbox тел NPC/интерактивов (без подписей) + ремап на высокий тайл (дома).
- Моты: заметная насыпь с пульсирующей искрой, HUD-счётчик, вьюха
растворяется с искрами при поднятии (InteractSink.onConsumed).
- Движок: TallSpec.shadow — тайл (tx-1,ty-1) за домом блокируется
(shadowTilesOf в collision.ts + isWalkable карты, тесты).
- Интерьеры: бронзовый контур проёма + подпись «выход».
- Спрайт сундука (tiles/chest.png) вместо ящика-плейсхолдера.
- Вода прудов: radius 2.5, volume 0.22 — только вплотную и тихо.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
19 hours ago
|
Фикс десинка вью героя (SpriteMotion не двигает blink-view) + звук: ветер, шорохи, тише вода
...
- Движок: SpriteMotion перезаписывает позицию/поворот только при bob/sway —
view с чистым blink/pulse можно двигать извне (герой прибивало к точке
спавна, ходьба выглядела камерным скроллом, по прибытии спрайт
«возвращался»); detach симметричен; тесты SpriteMotion
- PlayerController: syncView на точном прибытии в waypoint (кадр не отстаёт)
- Звук: ambience/wind — глобальный слой (AmbienceLayerDef.radius опционален,
нет at/tiles — константная громкость) на лугах и прудах; вода прудов
тише (0.6→0.35, радиус 6→5); sfx/rustle — редкие дальние шорохи пепла
из тика сцены (rng сцены, случайные pan/rate). Птиц в мире нет по лору
- Доки: anim.md (правило позиционирования), practices.md (глобальные
слои, шорохи, «птицы молчат»)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
20 hours ago
|
Аудио: стерео-музыка, динамические темы (бой/настороженность), room tone интерьеров
...
- Движок: renderMusicStereo (interleaved L,R, equal-power pan треков,
нормализация по общему пику каналов), createBuffer(channels 1|2);
моно renderMusic бит-в-бит прежним сэмплам
- Игра: темы боя и tension-стем в data/music.ts; threat-тик
LocationScene.updateMusic — chase → тема боя, wary → тихий стем
(setVolume с флагом stemPending против шторма перезапусков)
- Room tone интерьеров: ROOM_TONES (hum-спеки, шина ambience),
запуск в enter, стоп в exit, validate-тест ключей
- checks/music.mjs: инвариант «тема лугов не перезапускается»
(динамические темы/стем — легитимная реакция на врага)
- Доки: assets-audio-save.md (стерео), practices.md (динамическая
музыка, pending-флаг), plan.md (Работа G — сделано)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
20 hours ago
|
| 2026-09-06 |
audio: палитра спеков (tone/wobble/sweep/layers) — все sfx на спек-синтезе (E4)
...
- SoundSpec: kind 'tone' (чистый тон + свип freqTo), параметры w/attack/
fadeTo/wobbleHz|Depth|Base|Phase, доп. голоса layers (SpecVoice с delay);
без модификаторов бит-в-бит прежним формулам
- data/sfxSpecs.ts: 16 спеков — все бывшие файловые sfx, включая шаги
(StepVariants: варианты renderSpec с сидами base+i·10, fallback — базовый
спек); ui_click во всех сценах через playSfx
- gen.mjs остался только амбиенту; assets/audio/sfx/ удалён; формулы
бывших sfx экспортированы для парити-теста (bit-в-бит / eps 1e-5)
- мост: scene:synthesize принимает kind tone; доки: agent.md,
assets-audio-save.md, practices.md, plan.md (E4 ✅)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
20 hours ago
|
audio: миграция bell_hit/whoosh на спек-синтез (E3), мёртвый door.wav удалён
...
- SoundSpec: флаг swell (огибающая «0 → 1 → 0» у hit/scrape), у chime 4-й
партиал и константная амплитуда клика — формулы совпали с gen.mjs дословно
- data/sfxSpecs.ts: реестр SPEC_SFX + playSfx — единая точка проигрывания
sfx (AudioSystem, useTransition, collectFlower); ключи в AUDIO_KEYS
- gen.mjs: CLI-гвард (WAV при импорте не пишутся), формулы bellHit/whoosh
экспортированы для парити-теста sfxSpecs.test.ts (бит-в-бит равенство)
- доки: plan.md (E1–E3 ✅, F/G ✅), practices.md, assets-audio-save.md
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
20 hours ago
|
Движок: секвенсор renderMusic + playLoopBuffer; игра — тема лугов (работа G)
...
Партитура MusicSpec (bpm, beats, партии-стемы: pluck/bell/pad) чисто
компилируется в луп; playLoopBuffer играет буфер памяти на любой шине.
Тема лугов — правило-базовый генератор в data/music.ts (сид, ля-минорная
пентатоника), компиляция в рантайме — WAV для музыки не нужен; у области
поле theme, у Game — playTheme с guard-ом и кроссфейдом. Проба
checks/music.mjs в agent:check. Секвенция тем (бой) — до боевой темы.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
21 hours ago
|
Мост: scene:synthesize — звук по спеку из агентных проверок (работа E2)
...
Агент без слуха описывает звук параметрами (SoundSpec), движок
компилирует его в буфер (playSpec), факт запуска наблюдаем в
__gameAudioLog. Проба checks/synth.mjs в agent:check: удар/звон/
скрип/гул по спекам, громкость доезжает до голоса, повторный синтез
играет, негодные спеки возвращают null, гул не глушит амбиент.
Формы спеков — в docs/engine/agent.md.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
21 hours ago
|
Игра: DEV-лог аудио, агентная проба audio, практики «Добавляю звук»
...
- DEV-шпион window.__gameAudioLog (кольцо 24): sfx через onPlayed, амбиент через playAmbience
- checks/audio.mjs: амбиент запущен один раз, шаги без боя, bell_hit, guard амбиента, кольцо;
зарегистрирована в agent.mjs (8 проб)
- Доки: practices.md — ситуация «добавляю звук»; assets-audio-save.md — шпион и проба
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
22 hours ago
|
Игра: шаги по поверхностям, звуки предметов, локальные амбиент-слои
...
- Шаги: sfx/step_grass|ash|water|floor по тайлу под ногами (stepKey), старый sfx/step удалён
- Предметы: моты → mote_pickup, сундук → chest_open, знаки/записка → note, whoosh на переходах
- Фауна: событие fauna:startle (FaunaSystem слышит combat:attack) → sfx/deer_startle
- AudioSystem.setLayers: несколько амбиент-слоёв сразу, синхронный дедуп, тик-фейд громкости
- AreaDef.ambienceLayers: вода прудов, гул башни (точка), скрипы домов (тайлы)
- validate-тест покрывает новые ключи через AUDIO_KEYS
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
22 hours ago
|
Игра: амбиент на шину ambience вместо music, слайдер «Амбиент»
...
- gen.mjs: ключи ambience/meadows|ponds|zvenets -> assets/audio/ambience/ (music/ удалён)
- AUDIO_KEYS вынесен в data/audio.ts (валидатор в node-тестах без ?url-импортов Game)
- Game.playAmbience(key, 0.7) c guard ключа; '' — stopAmbience; шина ambience в settings
- AreaDef: визуальное ambience -> atmosphere, аудио ambience?: string (интерьеры — тишина)
- SettingsScene: Общая / Амбиент / Звуки (ползунок music не показываем — треков нет)
- validate-тест: area.ambience и Interactables.responses[].sound ∈ AUDIO_KEYS
- хвосты music/ в доках вычищены; agent:check зелёный
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
22 hours ago
|
Батч 7: декор-слой (микро-кусты, камни, проплешины)
...
- engine: DecorData + TileMapData.decor; decorLayer между землёй и объектами;
addDecor (возвращает спрайт, один на тайл, повторный заменяет) / clearDecor;
setTile декор не трогает
- engine: MapFileV1.decor + validateDecor (границы, целые, dx/dy — числа)
- game: DECOR-реестр (tuft/stone/bald, id 15-17), buildDecor на createRng(seed+7919)
(~10% наземных тайлов, только GRASS/ASH, смещение не по сетке);
mulberry32 заменён на движковый createRng
- art: decor_tuft/stone/bald 16×16 (рисунок в ромб 16×8, палитра G/P)
- фикс fresh-теста: Math.round -> -0 теряется в JSON, нормализация +0
- тесты: порядок слоёв, addDecor/clearDecor, границы, round-trip + валидация decor
- доки: maps.md (раздел «Декор»), art-style.md, practices.md (ситуация
«меняю генераторы арта или карт», грабля -0)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
23 hours ago
|
Батч 6: варианты текстур тайлов (микс по хэшу координат)
...
- engine: hashTile(x,y,seed) — чистый хэш координат (math/rng.ts)
- engine: TileMapData.variants + setTileVariants + публичный variantOf;
анимация сильнее вариантов (setTileAnimation снимает их)
- engine: MapFileV1.variants (строковые ключи) + validateVariants в parseMap
- game: GRASS_V1/V2, ASH_V1, PATH_V1 (id 11-14), GROUND_VARIANTS в трёх
генераторах карт, новые текстуры в ASSET_KEYS и tileTextures()
- art: grass_2/grass_3/path_2/ash_2 (32×16, та же палитра, другой seed)
- тесты: hashTile (детерминизм/разброс), выбор варианта стабилен при setTile,
анимация vs варианты, round-trip + валидация variants
- доки: maps.md (раздел «Варианты текстур»), art-style.md, art-pipeline.md
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
23 hours ago
|

Тела не проходят друг сквозь друга + карта коллизий агенту
...
Расталкивание через реестр сцены: герой выталкивает себя из NPC
(PlayerController), враг — из героя, NPC и своих (EnemySystem); каждый
актор двигает только себя (separateCircles). attackStop (0.85) больше
суммы радиусов — авто-атака не дрожит.
A* не ведёт героя сквозь тело: SceneObjects.walkGrid() считает тайлы
NPC занятыми (герой застревал «на носу» у Ирвина — звон в верёвку
не поднимал флаг). Проводка: клик по миру, авто-подход к цели,
scene:route моста.
Карта коллизий агенту: слой s.collision {width, height, blocked (0/1
с footprint пропов), props} + команды scene:walkable {x, y} и
scene:raycast {from, to} (прямая видимость, вода прозрачна). Новый
сценарий checks/collision.mjs: слой валиден, walkable/raycast на
конкретных тайлах, клик в дерево — герой в проходимом, телепорт в
тело спящего ползуна — враг выталкивает себя.
Доки: agent.md (слой + 2 команды), practices.md (ситуация «проверяю
коллизии/движение» + грабли телепорта на тайл перехода).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
23 hours ago
|
Реестр размеров спрайтов: sizes.mjs + AssetLoader.frameSize
...
Единый источник номиналов для тулз (gen.mjs, lint-art.mjs), рантайм
читает размер кадра из атласного JSON. Захардкоженные 16×24/16×16
заменены ссылками на реестр; VIRTUAL-дубли 480/270 в сценах — на
Game.VIRTUAL_W/H; маркер NPC считается от реальной высоты кадра.
- tools/pixelart/sizes.mjs: SIZES (tile/tall/prop/char/fauna/clump/decor)
+ SLOTS для линтера; тест sizes.test.ts
- gen.mjs, lint-art.mjs: импорт из реестра вместо локальных констант
- AssetLoader.frameSize(key, frameName?) — sourceSize из атласного JSON
- IsoLayout как параметр игры — отложено (docs/plan.md)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|

feat(tools): батч 3 — тулзы кадров + animations в атласах
...
- engine/tools/frames.mjs: производные кадры из опорных — shiftFrame,
bobFrame (парение), squashFrame (приседание), swingFrame (nearest-
поворот вокруг опоры), mirrorFrame, deriveCycle (дескрипторы)
- buildAtlas(..., animations) — Record<имя, number[]> → JSON.animations
(формат Pixi); assets.animation() оживает
- gen.mjs: вода двумя кадрами (tiles/water_1/2, блики сдвинуты на 1px),
атласы героя/фауны/сгустков собираются через buildAtlas с animations,
новый chars/npcs_sheet (idle-кадры NPC через bobFrame); сгустки в
ячейке 20×20 теперь по центру (было прижато влево — спрайты врагов
центрируются точнее)
- aiart/atlas.mjs: инлайн-бобинг → squashFrame (вывод идентичен),
animations из frameSets
- игра: ключи воды water_1/water_2 (старый tiles/water удалён)
- ассеты перегенерированы вместе с генераторами (npm run art, art:lint ok)
- доки: art-pipeline.md (frames.mjs, animations), assets-audio-save.md
- тесты: frames (8), buildAtlas animations (2) — итого 369
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
aiart: примерка tryon + бобинг walk-кадров; фикс startDevServer (cwd)
...
- tryon.mjs: примерка AI-сборки в игре до promote — подмена целевого
атласа, rename кадров <id>_ → hero_ (контракт LocationScene),
скриншот героя в локации, восстановление файлов в finally.
- Бобинг: при bob:true 2-й кадр = 1-й, сдвинутый вниз на 1px —
различимая ходьба из одинаковых поз стоя; манифест bob:true.
- agent-lib startDevServer: опция cwd (приложение передаёт каталог с
index.html — vite от корня репо отдавал 404), spawn detached +
kill группы (зомби-дети npx держали порт), детект выхода при занятом
порте; игровой lib.mjs по умолчанию cwd apps/game; docs/engine/agent.md.
- meta.image в buildAtlas — basename (Pixi резолвит относительно URL
JSON; путь с каталогом давал /chars/chars/… и 404).
- docs/plan.md: статус проекта — техно-демка движка.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
feat(aiart): палитровый ремапер + линтер арта
...
recolor.mjs — перекраска квантованного спрайта по ключам палитры/hex (CLI +
поле remap в манифесте атласов: плащ звонаря приведён к каноническим C0/C1).
lint-art.mjs (npm run art:lint) — авто-чеклист арт-библии: палитра, слоты,
детект «мыла»; все 31 кодовых ассета и AI-атлас проходят, негативы проверены.
Тест ремапера (3). Доки plan.md, art-pipeline.md, CLAUDE.md.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
fix(aiart): кроп фигур h245→h230 — грунтовая полоса листа размывала ноги кадров
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
feat(aiart): пайплайн атласов персонажей gen/build/promote + полный прогон звонаря
...
Манифест-драйвенно (atlas-manifest.json): промпт, seed, ракурсы→направления,
палитра (game | palettes/*.json), crop-оверрайды. sd_sheet.py — генератор
листов в репо (интерпретатор — env RPG_SD_PYTHON). Прогон: 6 кадров звонаря
(3 направления × 2) + обзорный лист build/bellringer/_review.png на апрув,
статус draft — promote в assets закрыт. Сырые листы — в .gitignore (seed
детерминирован). Скрипт npm run aiart; доки plan.md и art-style.md.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
docs(plan): B3-доп — ускорители (iGPU/q8) отвергнуты, fp32-CPU остаётся
...
iGPU HD 620 (Vulkan/ggml) не бенчмарка: 24 EU и общая память ~30 ГБ/с —
на порядок слабее CPU в матмулах, OpenCL для Gen9.5 мёртв. Рабочий рычаг —
меньше шагов (25→15 = 11→6.6 мин). В доку и кадр демо пост-обработки.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
B3-проба: SD_PixelArt_SpriteSheet_Generator на CPU — путь рабочий, квантование отвергнуто
...
- fp32/diffusers, 15 шагов = 6.6 мин/вид (25 шагов — 11 мин): 4 фигуры
читаются, но это позы стоя, не walk-цикл; кадры ~120 px.
- q8_0 через stable-diffusion.cpp: 34 мин (int8-ядра ggml без VNNI на
i5-7300U медленнее fp32-oneDNN) и VAE в q8 даёт шум — квантование на
этой машине не берём.
- Вердикт в docs/plan.md: разовые атласы ≈ 30 мин/персонажа (4 вида),
доработка кадров руками; пробы в tools/aiart/probe-b3/.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|

Крупные объекты: props с footprint в движке, слоты арта, проба дома кодом
...
Работа C из docs/plan.md — подготовка к зданиям акта 2.
Движок:
- TileMapData.props: крупный объект с footprint w×h от СЗ-угла — коллизия
по всему прямоугольнику, земля под ним (ground), спрайт якорем низ-центр
footprint'а; без текстуры — колонна-плейсхолдер (общий с tall хелпер).
- IsoDepthLayer.addRect: глубина по диагонали юго-восточного угла
footprint'а — герой у южной стены перекрывается домом, перед южным
углом рисуется поверх.
- mapFormat: props в файловом формате + валидация (целые w/h ≥ 1,
footprint внутри карты, высота в юнитах).
- LocationScene вставляет map.propViews в общий depth-слой.
- Доки движка: maps.md (секция props), render.md (addRect).
Арт (проба C2):
- Арт-библия: слоты крупных спрайтов (дом 2×2 — 64×80, 3×3 — 96×96,
4×4 — 128×112); плотность пикселя как у тайлов.
- gen.mjs: tiles/house_big.png (64×80) — композит: модули щитов + крыша
из шпал + козырёк + окна. Сравнение с AI-апскейлом 24→48 —
tools/aiart/probe-c2.png: код-композит заметно чище, апскейл — мыло с
чужой плотностью пикселя. Вывод: крупные объекты — код-композит;
апскейл только как болванка (см. docs/plan.md, работа C).
Тесты: 318 (+9: footprint, depth-rect, валидация пропов).
Co-Authored-By: Claude Code <noreply@anthropic.com>
|

B1: доменный PoC на PixelGPT-24×24 — 44% годных, отказов нет, лицензии нет
...
Вторая GPT-пиксель-модель (68M, CPU ~22 с/спрайт) с обусловливанием палитрой
игры (5 цветов на запрос). 18 доменных спрайтов (колодец, столб, рычаг,
колокол, камин, прилавок, дверь, моты + сундук как контроль).
Итог: критерий 30% выполнен (44% good); главное отличие от PXG-Tiny —
модель не отказывается от доменных объектов (колокол, дверь, камин, столб,
моты — good). Ограничения: даунскейл 24→16 губит деталь (колодец good на
24×24), фон часто залит, ровно 5 цветов, лицензии на код/веса нет — в игру
нельзя. Вывод в docs/plan.md: критичные интерактивы — RD API или ручной
арт; дообучение под игру не делаем.
- tools/aiart/prompts-b1.txt, review-b1/ (18), processed-b1/ (19),
manifest-b1.json (вердикты).
- post.mjs: опциональный каталог вывода (партии не затирают листы друг
друга).
- Раннер генерации и модель — вне репо (~/.cache/rpg-ai), в git только
промпты/манифест/PNG.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Чистка тулз: пробы-сироты и дублирующие смоуки удалены, доки по новой раскладке
...
- Удалены одноразовые пробы, никем не запускаемые: cam-probe, far-test,
skin-info, skin-probe, walk-probe, font-probe.
- Удалены смоуки, дублирующие checks/: smoke-zvenets и smoke-ponds
(покрываются checks/transitions.mjs), smoke-quest (checks/interact.mjs).
Полный прогон акта 1 — smoke-act1.mjs, базовый — smoke.mjs.
- Доки: CLAUDE.md (правило «общее — в движок, сценарий — в игра»,
packages/engine/tools), docs/engine/{practices,art-pipeline,agent}.md,
docs/demo.md, docs/llms.txt, README.md.
- npm run audio — скрипт для и без того существующего генератора WAV.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|

Разграничение: жанронезависимые тулзы переехали в packages/engine/tools
...
Правило: тулза, знающая контент игры (палитру, тайлы, локации, сценарии
акта), живёт в apps/game/tools как «сценарий применения»; машинерия без
знаний об игре переезжает к движку.
- packages/engine/tools/: png.mjs (encode+decode), canvas.mjs (палитра —
параметр), imaging.mjs (кроп/квантизация/обзорный лист), wav.mjs
(WAV-энкодер и примитивы синтеза), agent-lib.mjs (маяк — параметр
openGame), boundary.mjs (правила гварда, корни/публичное API — опции)
+ юнит-тесты boundary.
- exports движка: "./tools/*" — игровые сценарии импортируют
@rpg/engine/tools/* вместо относительных путей; maps/gen.test.ts
больше не лезет в src движка (encodeMap/parseMap из @rpg/engine).
- Игра остаётся сценарным слоем: palette.mjs, gen.mjs (арт/звуки),
aiart (промпты/манифест/тонкий post.mjs), checks/, smoke*, agent.mjs,
новый lib.mjs (маяк загрузки игры поверх движкового каркаса).
- Артефакты генераторов (арт, карты, WAV, processed) бит-в-бит прежние.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
B0 PoC: AI-генерация спрайтов PXG-Tiny + пайплайн пост-обработки
...
tools/aiart/ — пробный контур AI-арта:
- post.mjs: декодер PNG без зависимостей, кроп по альфе, nearest-вписывание
в 16×16, квантизация в палитру palette.mjs, обзорный лист для апрува;
- manifest.json: вердикты прогона (40% годных, стиль совпал на 100%);
- prompts-b0.txt + review/ + processed/ — сырьё и результат.
Модель PXG-Tiny (MIT/CC0) локально на CPU (~6 с/спрайт, iGPU-машина).
Ограничение зафиксировано в docs/plan.md: домен 38 классов не покрывает
критичные ассеты игры — для них дообучение / RD API / ручной арт.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Архитектура: гвард границы движок/игра + перенос тулз в apps/game/tools
...
- Гвард границы (apps/game/tools/guards/boundary.mjs, npm run guard):
движок не импортирует игру и не выходит из пакета, игра импортирует
движок только через @rpg/engine и @rpg/engine/assets/*. Чистое ядро
покрыто тестами (8 кейсов); проба guard:boundary в agent check.
- tools/ -> apps/game/tools/ (git mv, история сохранена): правка
корне-относительных путей в генераторах и CLI, ROOT-константы
'../../..', npm-скрипты обновлены.
- Доки: CLAUDE.md, llms.txt, docs/engine/*, README — новые пути,
практика «меняю границу движок/игра» и грабля про ROOT тулз.
Co-Authored-By: Claude Code <noreply@anthropic.com>
|