| 2026-09-07 |
feat(game): WASD-движение, кнопка действия E/A и подпись [E] Имя
...
Ходьба: WASD/стрелки/крестовина/аналоговый стик + тач-джойстик (приоритет)
через готовый PlayerController.moveFree; при нулевом векторе — обычный
update (moveFree со стопом рвал бы путь моста).
Кнопка действия: interact = KeyE / геймпад A — ближайшая цель в радиусе
1.5 юнита (NPC → click-переход/заперто → интерактив → цветок), резолв
через pickInteract (чистый, эпсилон-ничья 0.05 + приоритет kind).
Подпись «[E] Имя» над ближайшей целью заменяет per-object подписи;
NPC впервые получают подписи. Снапшот: interactHint (+ ключ анти-дрейфа).
Гвард wasBusy: клавиша, закрывшая диалог, не ударяет/не переоткрывает
разговор в тот же тик (Space/A мульти-биндинг advance+attack/interact).
Клик-движение пока живо (удаляется в следующем коммите).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
13 hours ago
|
feat(game): акт 2 — Клинт, размещения NPC по флагу
...
- механика NPC_PLACEMENTS/npcsForArea в npcs.ts: NPC появляется в области
при поднятом флаге (act2_hook от Милы), мёрж в LocationScene при загрузке;
- SceneObjects.addNpc: размещения попадают в клик-роутинг и кэш занятых
тайлов (иначе клик по Клинту резолвился как движение);
- диалоги clint_first/clint_repeat (крючок «пол-тона»), спрайт в атласе
npcs_sheet (6 кадров, clint_idle);
- validate: placements проверяются на bounds/walkable, def-ы — на ссылки
флагов и диалогов;
- interact.mjs: шаг «флаг -> Клинт в роще -> диалог -> met_clint».
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
14 hours ago
|

refactor(game): К3 — декомпозиция LocationScene, гигиена, валидация контента
...
Декомпозиция (1338 -> ~870 строк, сцена — оркестратор вьюх):
- systems/LocationAudio: слои/roomtone/шорохи/музыка угрозы (порядок тиков сохранён)
- systems/InteractableViews + data/assetSets: фабрики вьюх NPC/интерактивов,
enemyTextures из данных (префикс кадров из EnemyKindDef.frames)
- systems/Atmosphere: пепел/мотыли/дымка, накат, виньетка
- systems/quest/FlowerQuest: сбор/посадка/кат-сцена сдачи
- pixelTile -> чистый resolvePixelTile + pointerToWorld в ClickRouting (+ юнит-тесты)
Хардкоды сюжета -> data: QUEST_PLANT_TILES/QUEST_TOWER_TILE/QUEST_TOWER_GREEN,
harvestTile в AreaDef (правило «цветок только в ponds»)
Гигиена: HealthBar.setHp не перерисовывает при том же hp; eps-прибытие
вместо float-равенства (PlayerController, FaunaSystem) со снапом;
agentCommand — таблица Record вместо switch на 130 строк; удалён мёртвый код
(GameLighting.addLight/removeLight, Interactables.all, SceneObjects.byKind,
VolumeKey, questTaken/questDone/inventoryItems, реэкспорт MenuScene)
Валидация контента (тихие ошибки): патрули (границы+проходимость), хазарды,
источники света (дубли id, границы, пустые, whenFlag/notFlag), requiresItem
переходов/накатов, return-правило интерьеров, аудио-ключи (ambience/theme/
слои/sfx реакций и реплик/roomtone)
Проверено: check:fast (692 теста), agent:check 16/16, smoke-act1
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
18 hours ago
|
| 2026-09-06 |

Тела не проходят друг сквозь друга + карта коллизий агенту
...
Расталкивание через реестр сцены: герой выталкивает себя из 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>
|
Сцена на SceneRegistry: NPC/интерактивы/пропы/фауна/враги в одном реестре
...
- дефы получают юниты: NpcDef.pos + atlas?, InteractableDef.pos + view?
(tile вычисляется при загрузке модуля — сейвы/снапшот/валидатор без миграций)
- SceneObjects: фасад реестра области (npc/int/prop с footprint)
- клик-роутинг: npcAt/interactableAt/enemyAt через реестр; чистый
resolveClick и приоритеты не тронуты (пробы transitions/interact зелёные)
- шов врагов ECS: запись с pos по ссылке, move после шага, remove при смерти
- фауна регистрируется (kind 'fauna'), вьюхи NPC — def.atlas, интерактивов —
def.view.tex
- инвариант registry-consistent (реестр согласован с ECS)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|