document modular navmesh and agent prompts
Update the runtime NavMesh architecture to a DI and MessagePipe sidecar model, and add reusable agent prompt templates that capture the project's current multiplayer, WebGL, and modularity constraints.
This commit is contained in:
@@ -2,16 +2,17 @@
|
||||
|
||||
## Status
|
||||
|
||||
Этот документ считается каноническим для решений по детерминированному миру, authority model и runtime NavMesh, пока его явно не заменят более новым архитектурным решением.
|
||||
Этот документ считается каноническим для решений по детерминированному миру, authority model, модульным границам и runtime NavMesh, пока его явно не заменят более новым архитектурным решением.
|
||||
|
||||
## Purpose
|
||||
|
||||
Зафиксировать долгосрочные решения для MVP, чтобы downstream-задачи по FishNet, worldgen, AI и persistence не уехали в разные стороны.
|
||||
Зафиксировать долгосрочные решения для MVP, чтобы downstream-задачи по FishNet, worldgen, DI, AI и persistence не уехали в разные стороны.
|
||||
|
||||
## Scope
|
||||
|
||||
- deterministic voxel world generation
|
||||
- authority model для session gameplay
|
||||
- модульные границы feature-подсистем
|
||||
- runtime NavMesh в procedural world
|
||||
- риски WebGL-host режима
|
||||
|
||||
@@ -79,7 +80,7 @@
|
||||
Последствия:
|
||||
- изменения чанка в будущем пойдут не через owner migration, а через authoritative world deltas от хоста
|
||||
|
||||
### 4. Runtime NavMesh строится локально на каждом peer по фактической локальной геометрии чанка
|
||||
### 4. Runtime NavMesh строится локально на каждом peer по фактической локальной геометрии мира
|
||||
|
||||
Решение:
|
||||
- NavMesh не реплицируется по сети как data blob
|
||||
@@ -175,23 +176,52 @@
|
||||
Последствия:
|
||||
- при появлении разных классов существ нужно отдельно пересмотреть agent taxonomy
|
||||
|
||||
### 9. В этой фазе решение остается scene-local и не привязывается к VContainer или Addressables
|
||||
### 9. Runtime NavMesh реализуется как sidecar-модуль, а не как hardwired часть world generator
|
||||
|
||||
Решение:
|
||||
- runtime NavMesh реализуется как часть текущего scene-local world runtime
|
||||
- VContainer и Addressables в этой задаче не вводятся
|
||||
- `VoxelWorld` остается владельцем world state и chunk lifecycle
|
||||
- NavMesh реализуется отдельным подключаемым модулем в собственной assembly
|
||||
- модуль подключается через DI и может быть отключен без переписывания world feature
|
||||
|
||||
Почему выбрано:
|
||||
- в проекте пока нет production-ready composition root поверх gameplay world
|
||||
- принудительное добавление DI boundary сейчас даст больше шума, чем пользы
|
||||
- Addressables не подключены и не требуются для гипотезы NavMesh generation
|
||||
- это соответствует целевой модели feature-подсистем как подключаемых модулей
|
||||
- позволяет держать `VoxelWorld` core меньше и стабильнее
|
||||
- упрощает отключение NavMesh в сценах или режимах, где он не нужен
|
||||
|
||||
Почему не выбран ранний DI/bootstrap refactor:
|
||||
- это отвлекает от основной гипотезы по производительности и корректности NavMesh
|
||||
- возникает преждевременная архитектурная сложность при еще нестабильных правилах мира
|
||||
Почему не выбран partial-вариант внутри `VoxelWorldGenerator`:
|
||||
- он быстрее в реализации, но цементирует NavMesh внутрь world feature
|
||||
- делает отключение модуля искусственным
|
||||
- увеличивает связанность и мешает дальнейшему DI-разделению
|
||||
|
||||
Последствия:
|
||||
- код должен оставаться достаточно изолированным, чтобы позже его можно было вынести в runtime service
|
||||
- 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
|
||||
|
||||
Последствия:
|
||||
- нужны contracts для `IChunkNavGeometryReader` и `IWorldInterestReader`
|
||||
- нужны message types для `ChunkNavGeometryReady`, `ChunkNavGeometryRemoved` и `WorldInterestChanged`
|
||||
- `GlobalMessagePipe` не считается канонической точкой интеграции для feature-кода
|
||||
|
||||
## Long-Term Risks
|
||||
|
||||
@@ -205,15 +235,17 @@
|
||||
- Цель в `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.
|
||||
- `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 и без camera-driven assumptions.
|
||||
- `TASK-0023`: runtime NavMesh обязан быть local-build, throttled, sidecar-модулем и не должен иметь camera-driven assumptions.
|
||||
|
||||
Reference in New Issue
Block a user