15 KiB
id, title, summary, priority, area, owner, created, updated, execution_time, depends_on, canonical_docs, related_files
| id | title | summary | priority | area | owner | created | updated | execution_time | depends_on | canonical_docs | related_files | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| TASK-0028 | Перевести runtime NavMesh на interest-cluster-based coverage | Заменить основной runtime pathing mode с множества region-based NavMeshData на небольшой набор крупных cluster-based coverage windows, чтобы убрать seam-разрывы и сделать покрытие совместимым с multiplayer interest set. | Highest | ai | unassigned | 2026-04-08 | 2026-04-08 | 2d |
|
|
|
TASK-0028 - Перевести runtime NavMesh на interest-cluster-based coverage
Status
Статус задачи ведется в docs/tasks/Index.md и является каноническим там.
Why
Текущая region-based runtime NavMesh схема подтверждает локальную работоспособность build pipeline, но уже показала архитектурно важную проблему: pathfinding между соседними зонами покрытия дает PathPartial, даже когда destination сам лежит на NavMesh.
Это означает, что текущий основной runtime pathing mode опирается на набор разрозненных nav islands и не гарантирует непрерывный navigation graph между активными зонами симуляции.
Для multiplayer host-authoritative pathing этого недостаточно. Хосту нужен не просто локально построенный NavMesh, а непрерывное coverage в активной области симуляции без систематических seam-разрывов на границах мелких регионов.
Expected Outcome
- Основной runtime pathing mode больше не строится как множество мелких независимых
NavMeshDataпо nav regions. - Вместо этого используется небольшой набор крупных
coverage windows, каждый из которых покрываетinterest cluster. - Внутри активной области симуляции pathfinding не ломается на границах бывших nav regions.
- Coverage учитывает не только одного игрока, а multiplayer interest set:
spawn anchors + players + active NPC. - Модуль остается sidecar-решением поверх
VoxelWorld, без hardwiring внутрьVoxelWorldGenerator.
Current Context
Сейчас runtime NavMesh уже вынесен в sidecar-модуль и строится локально на каждом peer:
VoxelWorldGeneratorотдает nav sources через contracts;VoxelWorldNavMeshServiceсобирает sources из chunk snapshots;- build идет локально и не реплицируется по сети;
- authority gameplay сохраняется у хоста.
Однако unit of build и unit of scheduling пока выбраны неудачно как основной pathing mode:
- много мелких
NavMeshDataпо region-based сетке; - pathfinding между region surfaces может распадаться на отдельные islands;
- visual continuity overlay не гарантирует graph connectivity для
NavMesh.CalculatePath/NavMeshAgent.
Source Of Truth
docs/architecture/mvp-world-authority-navmesh.mddocs/plans/TASK-0023-runtime-navmesh-implementation-plan.md- фактическая реализация
VoxelWorldNavMeshService - подтвержденные smoke-test результаты с
PathPartialна границах region coverage
Read First
Assets/Features/VoxelWorldNavMesh/Runtime/VoxelWorldNavMeshService.csAssets/Features/VoxelWorldNavMesh/Runtime/VoxelWorldNavMeshConfig.csAssets/Features/VoxelWorld/Contracts/NavMeshWorldContracts.csAssets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.csdocs/architecture/mvp-world-authority-navmesh.md
Fixed Decisions
1. NavMesh remains local-build sidecar state
NavMesh по-прежнему:
- строится локально на каждом peer;
- не реплицируется как data blob;
- остается derived cache от world state;
- не является authoritative network state.
2. Chunk stays source/invalidation unit, not build unit
Chunk остается:
- источником nav build sources;
- unit of invalidation для world lifecycle;
- источником dirty notifications.
Chunk не должен оставаться каноническим unit of nav coverage build.
3. Coverage window is built from interest clusters, not from one player and not from camera
Нельзя строить канонический runtime pathing вокруг:
Camera.main;- только одного tracked player;
- presentation-level сущности.
Coverage должен строиться вокруг interest clusters, формируемых из:
- spawn anchors;
- players;
- active NPC.
4. One player does not imply one dedicated volume
Нельзя закреплять правило один игрок = один volume.
Правильная модель:
- один spatially coherent interest cluster = один coverage window;
- близкие игроки и NPC должны merge'иться в один cluster;
- число active windows должно быть bounded.
5. Scene scan through NavMeshSurface sample is not the canonical integration model
Подход из sample NavMeshSurfaceVolumeUpdater полезен как диагностическая подсказка, но не должен становиться буквальной production integration model.
Канонический путь для проекта:
- bounds уровня sliding coverage window;
- build sources из
IChunkNavSourceReader/ world contracts; - DI + typed MessagePipe + reader contracts.
6. Spawn readiness must become first-class
Покрытие должно учитывать spawn anchors до player movement activation. Нельзя полагаться на то, что NavMesh magically появится только после того, как actor уже стал единственной точкой интереса.
Scope In
- замена основного runtime pathing mode с region-based surfaces на cluster-based coverage windows;
- новый scheduler по coverage windows;
- cluster builder для
players + active NPC + spawn anchors; - build source collection по bounds окна, а не по одному nav region;
- read-model для current nav coverage state;
- explicit coverage readiness для spawn / first path command / AI activation;
- bounded merge policy для близких interest points;
- debug visibility coverage windows.
Scope Out
- изменение authority model NPC/AI;
- репликация NavMesh;
- полноценная crowd avoidance система;
- multi-agent taxonomy beyond current single-agent MVP;
- player host-authoritative navigation system как отдельная feature-задача;
- большой рефактор world feature вне необходимого nav contracts surface.
Required Architecture
New canonical unit: interest cluster
Нужна новая внутренняя модель coverage:
WorldInterestPointостается atomic input;NavInterestClusterстановится unit of grouping;NavCoverageWindowстановится unit of build and readiness.
Минимальная ответственность cluster builder:
- собрать текущий interest set;
- spatially merge близкие точки интереса;
- стабилизировать cluster ids между обновлениями;
- строить quantized window bounds с margin.
Coverage window replaces region as primary build unit
Coverage window должен хранить:
- cluster id;
- current bounds;
NavMeshData/NavMeshDataInstance;- dirty/building/ready state;
- список covered chunks или equivalent cached source membership.
Source collection remains contract-driven
Build sources должны собираться:
- не через scene scan;
- не через direct references на private world internals;
- а через
IChunkNavSourceReaderи chunk nav source snapshots.
Chunk используется как source/invalidation unit, но не как primary coverage unit.
Coverage state must be queryable
Нужен reader contract уровня:
INavCoverageReader
Минимальная ответственность:
IsPositionCovered(Vector3 worldPosition);- возможность получить current active coverage windows;
- возможность проверить readiness для spawn/path activation.
Scheduler must be bounded and quantized
Нельзя rebuild'ить coverage window на каждый микрошаг игрока.
Нужны:
- quantized movement threshold;
- bounded number of active windows;
- bounded builds per frame;
- rebuild только при существенном смещении cluster bounds, изменении cluster composition или chunk invalidation внутри covered bounds.
Suggested Runtime Structure
New or refactored runtime types
NavInterestClusterBuilderNavCoverageWindowRuntimeNavCoverageWindowSnapshotNavBuildSourceCollectorINavCoverageReaderVoxelWorldClusteredNavMeshServiceили equivalent refactor текущегоVoxelWorldNavMeshService
Config changes
Текущий config должен сместиться от region-centric параметров к cluster/window-centric:
clusterMergeDistanceclusterBoundsPaddingclusterRebuildQuantizationmaxActiveCoverageWindowschunkCollectionMarginInChunksmaxBuildsPerFrame
Если старые region-centric поля остаются временно ради миграции, они не должны продолжать определять основной runtime pathing mode.
Main Highlights Of Changes
- Смена unit of build
- было:
nav region - станет:
interest cluster coverage window
- Смена unit of scheduling
- было: очередь dirty regions
- станет: очередь dirty coverage windows
- Смена unit of readiness
- было: неявная region-local готовность
- станет: явная coverage readiness по world position
- Смена логики multiplayer coverage
- было: первая practical привязка к локальному player interest
- станет:
spawn anchors + players + active NPC
- Уход от seam-first topology
- было: pathing через сеть мелких surfaces с риском disconnected islands
- станет: меньшее число более цельных coverage windows
Acceptance Criteria
- Основной runtime pathing mode больше не опирается на множество мелких region-based
NavMeshDataкак на primary navigation graph. - Destination на NavMesh в соседней активной области больше не приводит систематически к
PathPartialтолько из-за seam между бывшими nav regions. - Coverage формируется по interest clusters, а не по одному tracked player и не по
Camera.main. - Spawn anchors участвуют в initial nav coverage.
- Нужное coverage state можно query'ить через reader contract.
- Sidecar-модуль остается отключаемым без переписывания
VoxelWorldcore. - Build pipeline остается bounded и пригодным для WebGL-host бюджета.
Verification
- ручной тест: pathfinding между соседними активными областями больше не обрывается на границе бывших region surfaces;
- ручной тест: при удалении игроков друг от друга coverage windows корректно split/merge'ятся по кластерам;
- ручной тест: spawn area получает nav coverage до first path command;
- ручной тест: pathfinding внутри cluster window и между близкими covered areas дает
PathComplete, где раньше получалсяPathPartialиз-за seam; - debug visualization coverage windows подтверждает ожидаемую cluster topology.
Risks / Open Questions
- Один большой coverage window может снять seam-problem, но оказаться слишком тяжелым для host CPU budget; поэтому bounded cluster windows важнее, чем просто "один volume на весь мир".
- Слишком агрессивное merge policy может раздуть rebuild cost; слишком слабое merge policy вернет seam-problem в другой форме.
- Нужна аккуратная стратегия стабильных cluster ids, иначе scheduler и debug tooling будут шумными.
- Возможно понадобится временный dual-mode rollout: region mode как fallback, clustered mode как новый primary pathing mode до подтверждения стабильности.
Human Decisions Needed
- none currently
Decision Log
2026-04-08- подзадача выделена после smoke-test'а runtime NavMesh, который подтвердил локальную работоспособность build pipeline, но выявилPathPartialна границах region-based coverage.
Handoff Notes
Эта задача не отменяет базовые решения TASK-0023, а уточняет основной runtime pathing mode. Не возвращать интеграцию к Camera.main или scene-scan-driven sample как к канонической архитектуре. Sample NavMeshSurfaceVolumeUpdater использовать только как источник идеи sliding coverage, но не как буквальную production integration model.