# MVP World, Authority And Runtime NavMesh

## Status

Этот документ считается каноническим для решений по детерминированному миру, authority model, модульным границам и runtime NavMesh, пока его явно не заменят более новым архитектурным решением.

## Purpose

Зафиксировать долгосрочные решения для MVP, чтобы downstream-задачи по FishNet, worldgen, DI, AI и persistence не уехали в разные стороны.

## Scope

- deterministic voxel world generation
- authority model для session gameplay
- модульные границы feature-подсистем
- runtime NavMesh в procedural world
- риски WebGL-host режима

## Fixed Decisions

### 1. Базовый мир генерируется детерминированно и локально на каждом peer

Решение:
- базовая геометрия мира не стримится от хоста по сети
- каждый peer генерирует чанк локально из одинакового `seed`, одинакового `VoxelWorldConfig` и одинаковой версии world rules

Почему выбрано:
- для WebGL и peer-host модели это минимизирует сетевой трафик
- убирает постоянную сетевую репликацию геометрии чанков
- снимает с хоста роль единственной точки генерации базового мира
- хорошо сочетается с уже существующим `VoxelWorldGenerator`, который строит чанк из deterministic inputs

Почему не выбран host-generated world streaming:
- хост получал бы лишнюю CPU-нагрузку на генерацию и лишнюю сетевую нагрузку на раздачу чанков
- late join и догрузка дальних областей становились бы тяжелее по сети
- это хуже укладывается в бюджет WebGL-host

Последствия:
- `seed`, world config и их версия становятся частью session handshake
- любое расхождение по config/version между peers недопустимо и должно считаться protocol drift

### 2. Host остается authoritative для NPC, AI и другого gameplay state

Решение:
- NPC симулируются на хосте
- pathfinding NPC, агро, боевые решения и каноническое положение NPC принадлежат хосту
- клиенты получают состояние NPC по сети и могут делать только визуальное сглаживание

Почему выбрано:
- NPC влияют на бой, урон, столкновения и progression, значит их нельзя отдавать в authority случайному клиенту
- это радикально снижает риск читов и эксплуатационных багов
- упрощает late join, reconnect и дебаг сетевой симуляции

Почему не выбран client-owned NPC:
- ownership у первого встретившего игрока нестабилен при совместной игре
- миграция owner во время боя ломает воспроизводимость path state, aggro state и hit timing
- возрастает риск desync и эксплойтов
- резко усложняется отладка и сопровождение

Последствия:
- `client-authority` допустим только для ввода игрока и только при отдельной валидации на сервере
- для NPC authority migration в MVP не используется

### 3. У чанков нет owner и нет chunk ownership migration

Решение:
- чанк не закрепляется за конкретным игроком как за владельцем
- базовый чанк является общей детерминированной сущностью мира, а не network-owned объектом

Почему выбрано:
- при deterministic world generation ownership чанка не дает полезного выигрыша
- chunk ownership добавляет coordination cost, миграцию ответственности и новые классы сетевых гонок без пользы для MVP
- это плохо совместимо с late join и с будущими world deltas

Почему не выбран owner-per-chunk:
- первый увидевший чанк игрок не является надежным authority source
- потребуется сложная логика передачи владения при сближении игроков и при disconnect
- любые расхождения по владельцу чанка приводят к hidden state drift

Последствия:
- изменения чанка в будущем пойдут не через owner migration, а через authoritative world deltas от хоста

### 4. Runtime NavMesh строится локально на каждом peer по фактической локальной геометрии мира

Решение:
- NavMesh не реплицируется по сети как data blob
- каждый peer строит NavMesh у себя локально из актуальной локальной геометрии мира
- NavMesh всегда считается производным кэшем от world state, а не каноническим состоянием сессии

Почему выбрано:
- NavMesh data тяжелая и плохо подходит для сетевой репликации в peer-host модели
- при deterministic base world и одинаковых world deltas peers могут независимо прийти к одинаковой walkable topology
- это сохраняет сеть для gameplay state, а не для производных навигационных артефактов

Почему не выбран network-streamed NavMesh:
- лишний трафик и высокая сложность синхронизации
- плохая масштабируемость для догрузки чанков и late join
- NavMesh все равно пришлось бы пересобирать при локальных изменениях геометрии

Последствия:
- каноничность gameplay не должна зависеть от клиентского NavMesh
- client NavMesh используется для локальных потребностей, но authoritative decisions по NPC остаются у хоста
- при одинаковом world state peers должны приходить к функционально эквивалентной walkable topology, но NavMesh не считается protocol-grade bit-identical артефактом, от которого зависит correctness multiplayer state

### 5. Будущие изменения проходимости мира передаются как authoritative world deltas

Решение:
- базовый мир идет из deterministic generation
- любые будущие баррикады, спеллы, разрушаемость, carve и другие изменения мира передаются как authoritative deltas от хоста
- после применения delta каждый peer локально перестраивает затронутые nav regions

Почему выбрано:
- это отделяет immutable base generation от mutable session state
- обеспечивает late join: новому игроку можно отдать base seed/config и журнал world deltas
- не требует вводить ownership migration для чанков

Почему не выбран fully local mutable world:
- local-first изменения мира не могут быть каноническими в кооперативной сетевой игре
- конфликтуют с античитом, late join и persistence

Последствия:
- NavMesh pipeline обязан уметь маркировать локальные nav regions как dirty после world delta

### 6. NavMesh pipeline должен работать в single-thread budget; многопоточность в WebGL считается только опциональным ускорением

Решение:
- архитектура runtime NavMesh не должна зависеть от наличия потоков
- базовый режим должен укладываться в бюджет кадра на одном потоке
- если deployment позже подтвердит поддержку `SharedArrayBuffer` и `COOP/COEP`, можно добавить threaded optimization, но не делать ее обязательной

Почему выбрано:
- WebGL-host остается одной из целевых платформ
- WebGL multithreading требует специальных заголовков и эксплуатационной дисциплины на стороне хостинга
- завязка critical gameplay pipeline на эту инфраструктуру слишком рискованна для MVP

Почему не выбран threaded-only pipeline:
- он может работать в editor/desktop и развалиться в реальном WebGL deployment
- создаст ложное ощущение приемлемого бюджета, которого не будет на production-hosting

Последствия:
- rebuild должен быть incremental, throttled и bounded
- полносценовый bake вокруг камеры не подходит как каноническая модель

### 7. Первая итерация NavMesh может приоритизировать одного player actor, но внешний interest-контракт сразу задается как actor set

Решение:
- для первой проверки гипотезы scheduler может стартовать от одного player actor
- внешний reader/read-model контракт не должен жестко фиксировать single-point модель
- целевой контракт для multiplayer host: nav coverage должна учитывать игроков и активных NPC как actor-level interest set

Почему выбрано:
- это минимальный объем для MVP-проверки без ранней переплаты за сложную interest model
- при этом заранее фиксируется, что player-only coverage не является конечной архитектурой

Почему не выбран camera-driven center:
- камера не является каноническим gameplay actor
- в multiplayer и especially on host камера может не совпадать с зоной активной симуляции
- привязка к `Camera.main` ломает переносимость решения из test scene в сетевую сессию

Последствия:
- в коде нельзя оставлять `Camera.main` как канонический источник world/nav interest
- target должен представлять actor-level interest, а не presentation-level camera
- reader-контракт для интереса должен уметь вернуть один или несколько actor-level interest points; даже если первая scene wiring временно дает только один player actor, это не должно цементироваться во внешний API

### 8. Для MVP поддерживается один тип NavMesh agent

Решение:
- сейчас поддерживается только один `agentTypeID`

Почему выбрано:
- проект на стадии hypothesis/MVP
- это уменьшает стоимость runtime bake и настройки AI Navigation
- не раздувает матрицу тестирования до появления реальной необходимости

Почему не выбран multi-agent bake сразу:
- рост CPU и memory costs
- усложнение отладки при почти нулевой текущей пользе

Последствия:
- при появлении разных классов существ нужно отдельно пересмотреть agent taxonomy

### 9. Runtime NavMesh реализуется как sidecar-модуль, а не как hardwired часть world generator

Решение:
- `VoxelWorld` остается владельцем world state и chunk lifecycle
- NavMesh реализуется отдельным подключаемым модулем в собственной assembly
- модуль подключается через DI и может быть отключен без переписывания world feature

Почему выбрано:
- это соответствует целевой модели feature-подсистем как подключаемых модулей
- позволяет держать `VoxelWorld` core меньше и стабильнее
- упрощает отключение NavMesh в сценах или режимах, где он не нужен

Почему не выбран partial-вариант внутри `VoxelWorldGenerator`:
- он быстрее в реализации, но цементирует NavMesh внутрь world feature
- делает отключение модуля искусственным
- увеличивает связанность и мешает дальнейшему DI-разделению

Последствия:
- world feature обязан публиковать стабильные контракты для sidecar-потребителей
- NavMesh-модуль не должен зависеть от private nested runtime types `VoxelWorldGenerator`

### 10. Для модульной интеграции используется комбинация MessagePipe и reader-интерфейсов

Решение:
- `MessagePipe` используется для событий world lifecycle и invalidation
- отдельные reader-интерфейсы используются для получения актуального snapshot state
- NavMesh service получает `IPublisher<T>` и `ISubscriber<T>` через DI, а не через global lookup

Почему выбрано:
- сообщения хорошо решают слабую связность и optional-subscription
- одних сообщений недостаточно, потому что модуль может стартовать позже и пропустить часть lifecycle events
- reader-интерфейсы позволяют восстановить текущее состояние без зависимости от конкретной реализации мира

Почему не выбран message-only подход:
- missed events ломают начальную инициализацию и late subscription
- пришлось бы тащить тяжелые mutable runtime objects прямо в сообщения
- модуль становился бы хрупким при reorder startup sequence

Почему не выбран direct-reference подход:
- прямые ссылки на `VoxelWorldGenerator` убивают модульность
- `VoxelWorldGenerator` пока содержит private nested types и внутренние детали, которые нельзя делать частью внешнего API

Последствия:
- нужны query contracts для чтения актуальных nav build sources чанков и actor-level interest set, например `IChunkNavSourceReader` и `IWorldInterestReader`
- нужны message types для `ChunkNavGeometryReady`, `ChunkNavGeometryRemoved` и `WorldInterestChanged`
- `GlobalMessagePipe` не считается канонической точкой интеграции для feature-кода
- world-to-navmesh contracts не должны делать `Transform`, `MeshCollider` и `BoxCollider` каноническим внешним состоянием там, где достаточно узких source descriptors для build/invalidation

## Long-Term Risks

### Critical

- WebGL-host может не выдержать одновременно world streaming, runtime NavMesh rebuild и server-authoritative NPC AI.
- Любой drift по `seed`, `VoxelWorldConfig` или world rules между peers приведет к расхождению геометрии и локального NavMesh.

### High

- Цель в `50` активных NPC может упереться не в один subsystem, а в суммарный CPU budget хоста.
- Будущие изменения геометрии потребуют точной invalidation strategy по nav regions; без нее rebuild cost быстро выйдет из-под контроля.
- Если client movement в будущем начнет опираться на локальный NavMesh как на authority source, появятся расхождения с host simulation.
- Если contracts world feature окажутся слишком узкими или, наоборот, будут протекать внутренними типами генератора, sidecar-модуль быстро потеряет изоляцию.

### Medium

- Late join требует не только `seed/config`, но и корректного воспроизведения authoritative world deltas.
- Если region size выбрать слишком крупным, rebuild будет дорогим; если слишком мелким, возрастет число build operations и seam-risk на границах.
- Неаккуратное использование `GlobalMessagePipe` вместо DI-инъекции создаст скрытую runtime-зависимость и усложнит тестирование.

## Downstream Implications

- `TASK-0001`: этот документ закрывает часть канонических MVP-решений по world/authority/navmesh/module boundaries.
- `TASK-0002`: session handshake должен включать world seed, config/version и protocol compatibility checks.
- `TASK-0012`: enemy AI проектируется только как host-authoritative.
- `TASK-0023`: runtime NavMesh обязан быть local-build, throttled, sidecar-модулем и не должен иметь camera-driven assumptions.
