Files
MVP1/Docs/Modules/Intelligence.md
T
AlexanderandClaude Opus 5.5 9a6e5a2e7b Карта мира в 2.5D на примитивах
Карта на земле (X/Z): замок, города, лагеря, ресурсные точки, отряды и метки разведки -- примитивы,
подписи смотрят в камеру; наклонная перспективная камера с тем же поведением (перетаскивание, щипок, тап);
туман -- в текстуре земли; солнце и 3D-рендерер URP для камеры (Map3D). Логика и окна не менялись.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 14:55:41 +01:00

13 KiB
Raw Blame History

Разведка

Туман войны, источники обзора, чужие армии и последний контакт. Этап М1 по ТЗ разведки от 31.10.2026, решение №46: отдельный модуль.

  • Сборка: Bogatyri.Intelligence (без Unity: тот же код будет считать видимость на сервере).
  • Папка: Assets/Scripts/Modules/Intelligence.
  • Зависит от: только ядра. Карту и армии читает у Мира через контракт IWorldMap, отряды — их часть. Сам Мир о Разведке не знает: прямых ссылок между World и Intelligence нет.
  • Отвечает: Саша (решение №46).

Что умеет М1

Туман Три состояния клетки: не исследовано, исследовано (было в обзоре), видно сейчас. Клетка = клетка карты (1000 милли-единиц).
Источники обзора Своё поселение — 5 клеток, своя армия в походе — 1 клетка. Башни и герой-разведчик — позже (числа в правилах уже есть).
«Обзор» I/II/III +10 / +20 / +30% к радиусам. Уровни не складываются — действует текущий. Пока нет дерева технологий, уровень для теста задаётся в таблице.
Чужие армии Видны, только пока они в обзоре. Примерная численность ±20%, владелец — после опознания.
Событие наблюдения Армия вошла в обзор. На событие — один бросок численности и один бросок опознания (50%). Повторный расчёт, загрузка или нажатие не перебрасывают. Вышла и вошла снова — новое событие.
Последний контакт Армия вышла из обзора — остаётся бледная метка с последними данными. Данные больше не обновляются. Метка живёт 10 реальных минут.
Офлайн Наблюдение досчитывается шагами по 10 реальных секунд, не больше 48 часов. Армия, прошедшая через обзор, пока игра была закрыта, тоже будет замечена — события в порядке времени.

Примерная численность: окно шириной 40% от настоящей численности, сдвинутое случайно так, чтобы настоящая численность всегда была внутри. Пример: 50 воинов → «~42–62».

Контракт IIntelligence

Член Что делает
ObservationLevel Уровень «Обзора» 0..3.
GetVisibility(x, y) Unexplored / Explored / Observed для точки карты — по последнему расчёту.
Contacts Известные чужие армии (KnownContact): где, куда идёт, ~ApproxMin–ApproxMax, опознан ли и чей (OwnerId — только после опознания), видна ли сейчас, когда видели.
ObserveUntil(nowMs) Досчитать наблюдение до момента. Зовёт App/GameModules по WorldAdvancingEvent.

Что берёт у Мира: IWorldMap

Реализует MarchManager (модуль Мира).

Член Что это
HalfWidth, HalfHeight Границы карты от центра.
TryGetSettlement(ownerId, …) Где поселение игрока.
GetArmies(timeMs, …) Все армии на карте в момент timeMs (ArmyOnMap: id, владелец, где, куда, сколько воинов). Позиция считается по времени похода, поэтому можно спросить и о прошедших минутах.

События

Публикует (у всех — EventId = «армия#номер наблюдения» и TimeMs по часам игры):

  • ArmySpottedEvent — чужая армия вошла в обзор, с примерной численностью;
  • ArmyIdentifiedEvent — владелец опознан;
  • ArmyLostContactEvent — армия вышла из обзора.

Слушает: ничего напрямую. WorldAdvancingEvent (публикует Мир перед каждым расчётом) связан с ObserveUntil в App/GameModules.

Патрули-заглушки (временно)

Решение команды 31.10.2026: для проверки М1 соседние поселения иногда отправляют тестовые отряды к другим городам и лагерям. Это временная тестовая механика, а не ИИ соседей.

  • Патрули — обычные походы Мира (MarchData.patrol): Разведка видит их через тот же IWorldMap, что и настоящие армии. Когда появится PvP, их выключают в таблице — Разведка не меняется.
  • Боя, добычи и разбития лагеря нет. Армия игрока, окна итогов и события похода их не касаются.
  • Выходят из ближайших к игроку соседних городов и идут к ближайшим к игроку целям — чтобы проходили через обзор.
  • Выпускаются по расписанию из seed карты: тот же расчёт после офлайна даёт те же патрули. Сохраняются в секции world.
  • Таблица MarchConfig: patrolsEnabled (вкл/выкл), patrolMaxActive 3, patrolIntervalMinutes 10 реальных минут, patrolSoldiersMin/Max 10–40.

Карта мира

WorldMap/IntelligenceOverlay.cs рисует то, что вернула Разведка:

  • туман: не исследовано — тёмное, исследовано — притушено, в обзоре — чисто;
  • чужая армия в обзоре — красный ромб, подпись «чужая армия / ~42–62 воинов» или имя владельца, если опознан;
  • последний контакт — бледный ромб «контакт N мин назад».

Свои походы рисуются как раньше (MarchView). Чужие походы WorldMapController сам не рисует — только через Разведку.

Что видно вне обзора (решения по 8 вопросам Саши от 31.10, п. 1 — «Объекты видны, туман — для армий»):

  • города, замок, лагеря и ресурсные точки видны всегда — как ориентиры, туман затемняет только землю;
  • закрытые сведения — только пока объект в зоне обзора: гарнизон (на карте и в окне атаки), запас и срок ресурсной точки. Вне обзора — «неизвестно: вне обзора»;
  • поэтому вне обзора нет и прогноза: ни шанса победы, ни «сколько унесут». Напасть или пойти на сбор можно;
  • то, что игрок знает сам, видно всегда: лагерь разбит им и когда появится, на точке идёт его сбор;
  • IntelligenceConfig.hideUnexploredObjects (выключено) закрывает неисследованное вместе с объектами — полное скрытие для М1 не требуется, переключатель оставлен (тап по скрытому объекту при нём работает).

Таблица IntelligenceConfig

Assets/Resources/IntelligenceConfig.asset, числа — ТЕСТ: settlementRadius 5, armyRadius 1 (клеток), observationPercent 10/20/30, testObservationLevel (только для теста), lastContactMinutes 10, approxPercent 20, identifyPercent 50, sampleStepSeconds 10, hideUnexploredObjects.

Сохранение

Секция "intelligence", простые строки (модуль без Unity):

  • tick=<мс> — до какого момента посчитано наблюдение;
  • obzor=<уровень>;
  • grid=<ширина>x<высота>:<hex> — исследованные клетки, по биту на клетку;
  • contact=<армия>|<владелец>|<опознан>|<видна>|x|y|toX|toY|min|max|<видели>|<номер наблюдения>.

Сброс (ResetState): туман закрыт, контактов нет, «Обзор» 0.

Файлы

Файл Что это
IntelligenceService.cs IntelligenceRules (числа) и IntelligenceService (IIntelligence, ISaveParticipant).
Bogatyri.Intelligence.asmdef Сборка: только ядро, без Unity.

Вне модуля: App/IntelligenceConfig.cs (таблица), WorldMap/IntelligenceOverlay.cs (рисование), World/Simulation/WorldSimulation.Patrols.cs (патрули и позиция армии в момент времени — часть Мира).

Тесты

ModuleTests: вход и выход из обзора, последний контакт и его устаревание, свои армии как источники, «Обзор» заменяет уровень, туман «исследовано» остаётся, офлайн-проход через обзор, воспроизводимые броски и ~50% опознаний, новое событие при повторном входе, сохранение и загрузка без повторного обнаружения; патрули без боёв и событий, выключение, воспроизводимость и сохранение, позиция по времени, патрули замечаются Разведкой.

Решения и план

  • М2–М4 по ТЗ: башни, герой-разведчик, разведка поселений, отчёты — следующими этапами.

Журнал изменений

Дата Кто Что
04.11.2026 Claude 2.5D: туман рисуется в текстуре земли (объекты стоят над ней и видны всегда), метки чужих армий — ромбы-кубы с подписью к камере. hideUnexploredObjects в 3D пока только сильнее затемняет землю.
01.11.2026 Claude Поход «Разведка» (решения 31.10, п. 2) — команда Мира; что войско увидит, показывает Разведка. См. World.md.
01.11.2026 Claude Решения 31.10, п. 1: объекты видны всегда, а гарнизоны, запас и срок точек, прогноз боя и сбора — только в зоне обзора (WorldMapController).
31.10.2026 Claude Исправлено: после перезапуска или перемотки обратный путь войска не открывал туман (до расчёта боя Разведка считала, что войско стоит у цели). Мир досчитывается по событиям (WorldSimulation.AdvanceInSteps), Разведка — до каждого из них. Туман темнее.
31.10.2026 Claude Модуль создан: этап М1 — туман, источники обзора, «Обзор», чужие армии, примерная численность, опознание, последний контакт, офлайн-наблюдение, сохранение. Патрули-заглушки соседей для проверки (выключаются в MarchConfig).