[Fix] Update Tasks to Voxel Engine

This commit is contained in:
2026-03-31 09:32:34 +07:00
parent 122d7e55c2
commit 097a86f40b
12 changed files with 338 additions and 46 deletions
+5 -2
View File
@@ -42,7 +42,7 @@
| --- | --- | --- | --- | --- | --- | --- | --- |
| TASK-0001 | ToDo | Highest | architecture | unassigned | 1d | docs/tasks/items/TASK-0001.md | Зафиксировать MVP-архитектуру диаблоида на FishNet: разделение player/world, authority, детерминизм и контракты между подсистемами. |
| TASK-0002 | ToDo | Highest | networking | unassigned | 1d | docs/tasks/items/TASK-0002.md | Реализовать сетевой bootstrap FishNet, лобби, выбор мира и подготовку игрока к входу в сессию. |
| TASK-0003 | ToDo | Highest | worldgen | unassigned | 1d6h | docs/tasks/items/TASK-0003.md | Построить детерминированную генерацию мира по seed с поддержкой биомов и стабильной структуры чанков. |
| TASK-0003 | ToDo | Highest | worldgen | unassigned | 1d6h | docs/tasks/items/TASK-0003.md | Построить детерминированную voxel-генерацию мира по seed с биомами и стабильной структурой чанков. |
| TASK-0004 | ToDo | High | persistence | unassigned | 1d | docs/tasks/items/TASK-0004.md | Спроектировать раздельные сохранения мира и персонажей по модели Terraria-style. |
| TASK-0005 | ToDo | Highest | spawning | unassigned | 1d | docs/tasks/items/TASK-0005.md | Реализовать детерминированный спавн врагов по seed, биому и координатам чанка. |
| TASK-0006 | ToDo | Highest | persistence | unassigned | 1d | docs/tasks/items/TASK-0006.md | Реализовать побитовую систему состояния врагов в чанке и сохранить ее в world save. |
@@ -58,5 +58,8 @@
| TASK-0016 | ToDo | High | classes | unassigned | 1d | docs/tasks/items/TASK-0016.md | Реализовать MVP-скилл Лучника: выстрел через общую систему оружия и навыков. |
| TASK-0017 | BackLog | Medium | networking | unassigned | 1d | docs/tasks/items/TASK-0017.md | Добавить reconnect/resume после дисконнекта с восстановлением позиции и session state. |
| TASK-0018 | BackLog | Medium | persistence | unassigned | 1d | docs/tasks/items/TASK-0018.md | Добавить миграции формата сохранений между версиями для world save и player save. |
| TASK-0019 | BackLog | High | worldgen | unassigned | 1d6h | docs/tasks/items/TASK-0019.md | Добавить детерминированное размещение dungeon prefab в grid мира с вырезанием мировых тайлов под ним. |
| TASK-0019 | BackLog | High | worldgen | unassigned | 1d6h | docs/tasks/items/TASK-0019.md | Добавить детерминированное размещение dungeon prefab в voxel-мире через stamp/carve в данных чанков. |
| TASK-0020 | BackLog | High | security | unassigned | 1d | docs/tasks/items/TASK-0020.md | Добавить серверные ограничения и валидации против читов и некорректных клиентских команд. |
| TASK-0021 | ToDo | High | architecture | unassigned | 2d | docs/tasks/items/TASK-0021.md | Привести проект в порядок: разнести код по asmdef, навести структуру Editor/Runtime и добавить базовые автотесты. |
| TASK-0022 | ToDo | Highest | worldgen | unassigned | 1d | docs/tasks/items/TASK-0022.md | Интегрировать спавн врагов в VoxelWorldGenerator: спавнить по загрузке чанка и учитывать kill-state. |
| TASK-0023 | ToDo | Highest | ai | unassigned | 2d | docs/tasks/items/TASK-0023.md | Реализовать runtime NavMesh bake для voxel-чанка и интегрировать обновление навигации при загрузке/изменении чанков. |
+7 -7
View File
@@ -13,8 +13,8 @@ canonical_docs:
- docs/tasks/Index.md
- docs/tasks/_template.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/WorldGen/WorldAutotileProfile.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldAtlas.cs
- Assets/Scripts/Player/SimplePlayerInputMover.cs
---
@@ -42,19 +42,19 @@ related_files:
## Current Context
В проекте уже есть рабочий слой генерации мира в `Assets/Scripts/WorldGen/*`, но нет зафиксированной архитектуры под сетевую игру, классы персонажей, боевую систему и сохранения.
В проекте есть воксельный генератор мира в `Assets/Scripts/VoxelWorld/*` и легаси код в `Assets/Scripts/WorldGen/*`. Фокус проекта смещен на воксельный генератор, поэтому архитектурные решения должны опираться на него.
## Source Of Truth
- `docs/tasks/Index.md`
- код в `Assets/Scripts/WorldGen/*`
- код в `Assets/Scripts/VoxelWorld/*`
- явные решения человека по MVP после создания этой задачи
## Read First
- `docs/tasks/Index.md`
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/WorldGen/WorldAutotileProfile.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldAtlas.cs`
- `Assets/Scripts/Player/SimplePlayerInputMover.cs`
## Scope In
@@ -71,7 +71,7 @@ related_files:
## Constraints
- сохраняйте существующий worldgen как стартовую точку, если человек явно не меняет направление
- сохраняйте воксельный worldgen как стартовую точку, если человек явно не меняет направление
- предпочитайте минимальную архитектуру, достаточную для MVP
- все последующие задачи должны опираться на решения из этой задачи
+11 -13
View File
@@ -1,7 +1,7 @@
---
id: TASK-0003
title: Построить детерминированную генерацию мира с биомами
summary: Развить существующий worldgen до детерминированной генерации мира по seed с поддержкой биомов и стабильной структуры чанков.
title: Построить детерминированную voxel-генерацию мира с биомами
summary: Развить воксельный worldgen до детерминированной генерации мира по seed с поддержкой биомов и стабильной структуры чанков.
priority: Highest
area: worldgen
owner: unassigned
@@ -13,12 +13,11 @@ depends_on:
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/WorldGen/ChunkTemplate.cs
- Assets/Scripts/WorldGen/WorldAutotileProfile.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldAtlas.cs
---
# TASK-0003 - Построить детерминированную генерацию мира с биомами
# TASK-0003 - Построить детерминированную voxel-генерацию мира с биомами
## Status
@@ -38,24 +37,23 @@ related_files:
## Expected Outcome
Один и тот же seed всегда строит одинаковый набор чанков, тайлов и биомных зон. У мира есть понятный API для запроса biome data и chunk data.
Один и тот же seed всегда строит одинаковый набор воксельных чанков и биомных зон. У мира есть понятный API для запроса biome data и chunk data.
## Current Context
В проекте уже есть `InfiniteWorldGenerator`, `ChunkTemplate` и `WorldAutotileProfile`, что дает стартовую основу под генерацию 2D-мира.
В проекте уже есть `VoxelWorldGenerator`, который строит чанки и управляет их lifecycle. Легаси `Assets/Scripts/WorldGen/*` не является фокусом проекта.
## Source Of Truth
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/WorldGen/ChunkTemplate.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldAtlas.cs`
- решения из `TASK-0001`
## Read First
- `docs/tasks/items/TASK-0001.md`
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/WorldGen/ChunkTemplate.cs`
- `Assets/Scripts/WorldGen/WorldAutotileProfile.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldAtlas.cs`
## Scope In
+2 -2
View File
@@ -14,7 +14,7 @@ canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scenes/SampleScene.unity
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
---
# TASK-0004 - Спроектировать раздельные сохранения мира и персонажей
@@ -53,7 +53,7 @@ related_files:
- `docs/tasks/items/TASK-0001.md`
- `docs/tasks/items/TASK-0002.md`
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
## Scope In
+2 -2
View File
@@ -13,7 +13,7 @@ depends_on:
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
---
# TASK-0005 - Реализовать детерминированный спавн врагов по чанкам
@@ -50,7 +50,7 @@ related_files:
## Read First
- `docs/tasks/items/TASK-0003.md`
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
## Scope In
+2 -2
View File
@@ -14,7 +14,7 @@ depends_on:
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
---
# TASK-0006 - Реализовать побитовую систему состояния врагов в чанке
@@ -53,7 +53,7 @@ Enemy slot model должна прийти из `TASK-0005`, а общая сх
- `docs/tasks/items/TASK-0004.md`
- `docs/tasks/items/TASK-0005.md`
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
## Scope In
+3 -2
View File
@@ -12,10 +12,11 @@ depends_on:
- TASK-0005
- TASK-0007
- TASK-0010
- TASK-0023
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
- Assets/Scenes/SampleScene.unity
---
@@ -98,7 +99,7 @@ related_files:
## Risks / Open Questions
- на tile/grid мире нужно заранее проверить, как лучше готовить NavMesh для процедурных чанков
- на voxel-мире нужно заранее определить, как обновлять NavMesh в рантайме при загрузке/изменении чанков (см. `TASK-0023`)
## Human Decisions Needed
+1 -1
View File
@@ -14,7 +14,7 @@ depends_on:
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
---
# TASK-0018 - Добавить миграции формата сохранений между версиями
+16 -15
View File
@@ -1,7 +1,7 @@
---
id: TASK-0019
title: Добавить генерацию данжей-предфабов поверх биомов мира
summary: Реализовать BackLog-задачу на детерминированное размещение готовых dungeon prefab в мире так, чтобы они одинаково вставлялись по seed, вписывались в grid и вырезали мировой слой под собой.
summary: Реализовать BackLog-задачу на детерминированное размещение dungeon prefab в voxel-мире: одинаковая позиция по seed, встраивание через stamp/carve и сохранение результата.
priority: High
area: worldgen
owner: unassigned
@@ -13,7 +13,7 @@ depends_on:
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
- Assets/ChunkTemplate.asset
---
@@ -33,15 +33,15 @@ related_files:
## Why
Пользователь явно описал сценарий с готовым prefab-данжем, который должен одинаково размещаться у всех игроков и не рисоваться поверх карты, а встраиваться в grid мира с вырезанием тайлов под собой.
Dungeon prefab должны одинаково размещаться по seed и быть частью мира, а не отдельной "декорацией". Для voxel-мира это означает stamp/carve в данных чанков (и, при необходимости, пересборку визуального меша/коллайдеров).
## Expected Outcome
Система worldgen умеет по seed и biome rules выбрать место для dungeon prefab, встроить его в мир, удалить конфликтующий мировой слой под ним и воспроизвести тот же результат у всех клиентов.
Система worldgen умеет по seed и biome rules выбрать место для dungeon prefab, встроить его в voxel-мир (stamp/carve в воксельных данных чанков), удалить конфликтующие воксели и воспроизвести тот же результат у всех клиентов.
## Current Context
В проекте уже есть grid/tile-based worldgen. Dungeon placement должен строиться поверх deterministic world coordinates и biome sampling.
В проекте есть `VoxelWorldGenerator` с chunked runtime loop. Dungeon placement должен строиться поверх deterministic world coordinates и biome sampling, но применять изменения на уровне voxel chunk data.
## Source Of Truth
@@ -52,14 +52,14 @@ related_files:
## Read First
- `docs/tasks/items/TASK-0003.md`
- `Assets/Scripts/WorldGen/InfiniteWorldGenerator.cs`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
- `Assets/ChunkTemplate.asset`
## Scope In
- deterministic placement dungeon prefab по seed и biome rules
- привязка prefab к grid/tiles мира
- вырезание или замещение мировых тайлов под данжем
- выбор world-space/voxel-space якоря (anchor) и bounded volume для stamp/carve
- stamp/carve в voxel chunk data и пересборка меша/коллайдера
- одинаковое размещение у всех игроков
## Scope Out
@@ -69,7 +69,7 @@ related_files:
## Constraints
- данж не должен просто отрисовываться сверху без интеграции в мир
- данж не должен существовать только как отдельный GameObject без интеграции в voxel данные мира
- размещение должно быть детерминированным и совместимым с chunked worldgen
## If You Find Drift
@@ -79,23 +79,24 @@ related_files:
## Suggested Approach
1. Определить правила выбора позиции данжа по biome/world rules.
2. Описать grid-aligned placement и carve/replace world tiles под prefab.
3. Подготовить интеграцию с chunk loading и world save.
2. Определить формат dungeon stamp (например: набор voxel изменений, высотная маска, volume SDF или готовый "voxel brush").
3. Реализовать применение stamp/carve в voxel chunk data и пересборку визуала.
4. Подготовить интеграцию с chunk loading и world save.
## Acceptance Criteria
- один и тот же seed размещает один и тот же dungeon prefab в одном и том же месте
- данж встраивается в grid мира и заменяет конфликтующие тайлы под собой
- данж встраивается в voxel-мир через stamp/carve и изменяет voxel chunk data
- результат одинаков у всех игроков и повторяем после загрузки мира
## Verification
- повторная генерация одинакового мира и сверка положения данжа
- ручная проверка отсутствия наложения поверх неснятых мировых тайлов
- ручная проверка отсутствия "парящих" коллайдеров/дыр после stamp/carve
## Risks / Open Questions
- нужно решить, как хранить пересечение данжа с несколькими чанками и как кэшировать carve results
- нужно решить, как хранить пересечение данжа с несколькими чанками и как кэшировать/сохранять stamp results
## Human Decisions Needed
@@ -103,7 +104,7 @@ related_files:
## Decision Log
- `2026-03-30` - задача добавлена в `BackLog` по явному запросу пользователя и уточнена требованием grid-carving.
- `2026-03-31` - задача переписана под voxel worldgen: stamp/carve вместо grid/tile carving.
## Handoff Notes
+107
View File
@@ -0,0 +1,107 @@
---
id: TASK-0021
title: Привести проект в порядок (asmdef и базовые тесты)
summary: Разнести код по asmdef (Runtime/Editor/Tests), навести структуру каталогов и добавить минимальный набор автотестов, чтобы развитие воксельного мира и сетевого слоя не превращалось в хаос.
priority: High
area: architecture
owner: unassigned
created: 2026-03-31
updated: 2026-03-31
execution_time: 2d
depends_on:
- TASK-0001
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
- Assets/Editor/Tasks/TaskBoardWindow.cs
---
# TASK-0021 - Привести проект в порядок (asmdef и базовые тесты)
## Status
Статус задачи ведется в `docs/tasks/Index.md` и является каноническим там.
Допустимые значения статуса:
- `BackLog`
- `ToDo`
- `InProgress`
- `Review`
- `Done`
## Why
Сейчас проект развивается сразу в нескольких направлениях (воксельный worldgen, FishNet, AI/NavMesh, спавн/сейвы). Без нормальной структуры сборки и минимальных тестов любые изменения начинают ломать соседние подсистемы, а время на интеграцию растет.
## Expected Outcome
- Код разделен на asmdef по доменам и по границе Runtime/Editor.
- Editor-утилиты не тянут Runtime зависимости и наоборот.
- Есть базовые автотесты, которые фиксируют ключевые контракты (например, детерминизм вычислений и формат времени/парсинг задач можно оставить на потом).
## Current Context
В репозитории уже появились editor-инструменты (`Task Board`) и есть воксельный генератор (`VoxelWorldGenerator`). На текущем этапе важнее обеспечить предсказуемую сборку и быстрый фидбек, чем расширять функционал без контроля.
## Source Of Truth
- текущие канонические задачи в `docs/tasks/Index.md`
- существующие asmdef (если появятся) и фактические зависимости в проекте
## Read First
- `docs/tasks/Index.md`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
## Scope In
- добавить asmdef для ключевых Runtime доменов: voxel worldgen, networking, gameplay-core, ai
- добавить asmdef для Editor tooling
- добавить test assemblies (EditMode) и минимальные smoke tests
- привести нейминг и папки к стабильной структуре (Runtime/Editor/Tests)
## Scope Out
- полный рефактор всех namespaces
- покрытие тестами всей игры
## Constraints
- не менять поведение runtime систем без отдельного решения и проверки
- не ломать существующий пайплайн Unity compilation
## Suggested Approach
1. Снять карту зависимостей: какие папки и системы действительно связаны.
2. Ввести asmdef минимальным числом сборок, но с четкими границами Runtime/Editor.
3. Добавить 3-5 тестов: сборка, создание генератора, базовый deterministic шаг (если есть чистые функции).
4. Зафиксировать правила добавления новых скриптов в нужные assembly.
## Acceptance Criteria
- проект компилируется без циклических ссылок между asmdef
- Editor скрипты не попадают в Runtime сборки
- тесты запускаются (EditMode) и дают полезный сигнал
## Verification
- Unity compilation без ошибок
- запуск `EditMode` тестов
## Risks / Open Questions
- возможны скрытые зависимости через `Resources`/`AssetDatabase` и прямые ссылки на UnityEditor
## Human Decisions Needed
- none currently
## Decision Log
- `2026-03-31` - задача создана как техническая стабилизация перед расширением worldgen/AI.
## Handoff Notes
Если при разнесении asmdef всплывет, что legacy `Assets/Scripts/WorldGen/*` больше не нужен, лучше выделить его в отдельный assembly или пометить как deprecated, а не смешивать с `VoxelWorld`.
+95
View File
@@ -0,0 +1,95 @@
---
id: TASK-0022
title: Интегрировать спавн врагов в VoxelWorldGenerator
summary: Добавить в воксельный генератор мира интеграцию спавна врагов при загрузке чанков, используя детерминированные правила и kill-state.
priority: Highest
area: worldgen
owner: unassigned
created: 2026-03-31
updated: 2026-03-31
execution_time: 1d
depends_on:
- TASK-0003
- TASK-0005
- TASK-0006
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
---
# TASK-0022 - Интегрировать спавн врагов в VoxelWorldGenerator
## Status
Статус задачи ведется в `docs/tasks/Index.md` и является каноническим там.
## Why
Спавн врагов должен быть частью runtime world loop: при появлении/активации чанка сервер должен спавнить deterministic roster, а при повторной загрузке учитывать kill-state, чтобы мир ощущался стабильным и сохраняемым.
## Expected Outcome
- При загрузке чанка сервер вычисляет deterministic spawn roster для этого чанка.
- Сервер спавнит врагов в пределах чанка (или в заданных spawn zones), не создавая дублей.
- При наличии kill-state для чанка повторный спавн не создает уже убитых врагов.
## Current Context
В проекте уже есть `VoxelWorldGenerator`, который управляет жизненным циклом чанков. Задачи `TASK-0005` и `TASK-0006` описывают deterministic roster и kill-state, но без интеграции в мир спавн не работает end-to-end.
## Source Of Truth
- `docs/tasks/items/TASK-0005.md`
- `docs/tasks/items/TASK-0006.md`
- `Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs`
## Scope In
- точка интеграции: событие/хук на появление чанка в runtime
- вычисление spawn roster для `(seed, chunkCoord)`
- привязка `enemySlotIndex` к конкретному spawned enemy
- применение kill-state при (ре)загрузке чанка
## Scope Out
- AI поведение врагов (это `TASK-0012`)
- сложные spawn director механики
## Constraints
- сервер является источником истины для спавна
- результат должен быть детерминированным
## Suggested Approach
1. Выделить интерфейс/сервис `IChunkSpawnService` (или аналог) и вызывать его из `VoxelWorldGenerator` при загрузке чанка.
2. Реализовать вычисление roster, используя уже согласованный контракт из `TASK-0005`.
3. Перед фактическим спавном проверить kill-state из `TASK-0006`.
4. Зафиксировать правила despawn при выгрузке чанка.
## Acceptance Criteria
- при повторной загрузке одного и того же чанка сервер спавнит одинаковый roster
- убитые слоты не спавнятся повторно после загрузки world save
## Verification
- ручной тест: зайти/выйти из зоны чанка и убедиться, что roster стабилен
- тест: убить врага, сохранить/перезагрузить мир, проверить отсутствие этого слота
## Risks / Open Questions
- нужно решить, где хранить runtime mapping `enemySlotIndex -> NetworkObject` и когда его очищать
## Human Decisions Needed
- none currently
## Decision Log
- `2026-03-31` - задача выделена отдельно как интеграция deterministic spawn в runtime voxel-chunk loop.
## Handoff Notes
Если окажется, что генератор чанков работает и на клиенте, убедиться, что спавн вызывается только на сервере.
+87
View File
@@ -0,0 +1,87 @@
---
id: TASK-0023
title: Runtime NavMesh bake для voxel-чанка
summary: Реализовать генерацию/обновление NavMesh в рантайме для каждого voxel-чанка, чтобы враги могли корректно ходить по процедурному миру.
priority: Highest
area: ai
owner: unassigned
created: 2026-03-31
updated: 2026-03-31
execution_time: 2d
depends_on:
- TASK-0003
canonical_docs:
- docs/tasks/Index.md
related_files:
- Assets/Scripts/VoxelWorld/Runtime/VoxelWorldGenerator.cs
---
# TASK-0023 - Runtime NavMesh bake для voxel-чанка
## Status
Статус задачи ведется в `docs/tasks/Index.md` и является каноническим там.
## Why
AI врагов (`TASK-0012`) опирается на NavMesh. Воксельный мир генерируется чанками в рантайме, значит навигация должна обновляться динамически, иначе враги не смогут корректно находить путь.
## Expected Outcome
- Для активных чанков есть актуальный NavMesh, соответствующий walkable поверхности.
- При загрузке/обновлении чанка навигация перестраивается предсказуемо и без зависаний.
- Есть понятные границы: когда перестраиваем NavMesh, когда откладываем, как ограничиваем стоимость.
## Current Context
`VoxelWorldGenerator` строит mesh/collider для чанка. Это хорошая опора для NavMeshSource сборки, но нужно аккуратно сделать runtime bake на уровне чанка или группы чанков.
## Scope In
- определить модель bake: per-chunk NavMeshData, либо один NavMeshData на область вокруг игрока
- собрать NavMesh build sources из чанка (MeshCollider/BoxCollider/Renderer)
- обновлять NavMesh при загрузке/выгрузке чанков
- ограничения производительности: throttle, бюджет на кадр, батчирование
## Scope Out
- полноценный crowd simulation
- оптимизация под большие карты без ограничений
## Constraints
- runtime bake не должен фризить игру
- результат должен быть одинаков в рамках одного мира при одинаковых чанках
## Suggested Approach
1. Выбрать подход: `NavMeshSurface` (если используется пакет) или ручной `NavMeshBuilder.UpdateNavMeshDataAsync`.
2. Определить build bounds по чанку и собрать build sources по его коллайдерам.
3. Встроить вызов bake в lifecycle чанка: после генерации mesh/коллайдера.
4. Добавить throttling и очереди обновлений.
## Acceptance Criteria
- после генерации чанка враг способен построить путь по поверхности чанка
- при выгрузке чанка навигация не содержит "висячих" областей
## Verification
- ручной тест: враг преследует игрока при перемещении между чанками
- стресс тест: быстро двигаться по миру и убедиться, что обновления не фризят
## Risks / Open Questions
- нужно определить, как синхронизировать bake с сетевой моделью (сервер/клиент) и где AI реально работает
## Human Decisions Needed
- none currently
## Decision Log
- `2026-03-31` - runtime bake вынесен в отдельную задачу как prerequisite для enemy NavMesh AI.
## Handoff Notes
Если в проекте нет пакета NavMeshComponents, возможно придется добавить его или реализовать минимальный runtime builder.