diff --git a/docs/tasks/Index.md b/docs/tasks/Index.md index c9f8a58b..3c683778 100644 --- a/docs/tasks/Index.md +++ b/docs/tasks/Index.md @@ -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-чанка и интегрировать обновление навигации при загрузке/изменении чанков. | diff --git a/docs/tasks/items/TASK-0001.md b/docs/tasks/items/TASK-0001.md index 30423e2c..e7f8f1e7 100644 --- a/docs/tasks/items/TASK-0001.md +++ b/docs/tasks/items/TASK-0001.md @@ -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 - все последующие задачи должны опираться на решения из этой задачи diff --git a/docs/tasks/items/TASK-0003.md b/docs/tasks/items/TASK-0003.md index 9f1be0e6..0d4ab9b4 100644 --- a/docs/tasks/items/TASK-0003.md +++ b/docs/tasks/items/TASK-0003.md @@ -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 diff --git a/docs/tasks/items/TASK-0004.md b/docs/tasks/items/TASK-0004.md index 46be06f0..495594dd 100644 --- a/docs/tasks/items/TASK-0004.md +++ b/docs/tasks/items/TASK-0004.md @@ -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 diff --git a/docs/tasks/items/TASK-0005.md b/docs/tasks/items/TASK-0005.md index 2069fd91..482cf16e 100644 --- a/docs/tasks/items/TASK-0005.md +++ b/docs/tasks/items/TASK-0005.md @@ -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 diff --git a/docs/tasks/items/TASK-0006.md b/docs/tasks/items/TASK-0006.md index 12fe13a5..aadaae7c 100644 --- a/docs/tasks/items/TASK-0006.md +++ b/docs/tasks/items/TASK-0006.md @@ -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 diff --git a/docs/tasks/items/TASK-0012.md b/docs/tasks/items/TASK-0012.md index 737589dc..1e968920 100644 --- a/docs/tasks/items/TASK-0012.md +++ b/docs/tasks/items/TASK-0012.md @@ -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 diff --git a/docs/tasks/items/TASK-0018.md b/docs/tasks/items/TASK-0018.md index 9e82565f..4e9c89bb 100644 --- a/docs/tasks/items/TASK-0018.md +++ b/docs/tasks/items/TASK-0018.md @@ -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 - Добавить миграции формата сохранений между версиями diff --git a/docs/tasks/items/TASK-0019.md b/docs/tasks/items/TASK-0019.md index c1c581c2..8767afcb 100644 --- a/docs/tasks/items/TASK-0019.md +++ b/docs/tasks/items/TASK-0019.md @@ -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 diff --git a/docs/tasks/items/TASK-0021.md b/docs/tasks/items/TASK-0021.md new file mode 100644 index 00000000..5c934ea4 --- /dev/null +++ b/docs/tasks/items/TASK-0021.md @@ -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`. diff --git a/docs/tasks/items/TASK-0022.md b/docs/tasks/items/TASK-0022.md new file mode 100644 index 00000000..0a0eeb16 --- /dev/null +++ b/docs/tasks/items/TASK-0022.md @@ -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 + +Если окажется, что генератор чанков работает и на клиенте, убедиться, что спавн вызывается только на сервере. diff --git a/docs/tasks/items/TASK-0023.md b/docs/tasks/items/TASK-0023.md new file mode 100644 index 00000000..0ede8382 --- /dev/null +++ b/docs/tasks/items/TASK-0023.md @@ -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.