Remastered 5.01 · DX12

Охота
на двоих

Кооп-мод для The Witcher 3: Wild Hunt — Remastered, хотфикс 5.01. Хост симулирует мир, гости получают снимки. Код на C++20.

Из README

Хост симулирует мир. Гости приходят своими ведьмаками и видны остальным куклами.

I

Сводка

Кривая считает только опубликованные записи. Кольцо справа — этапы ROADMAP по состоянию в репозитории.

Журнал по дням

Публичных записей пока нет, кривую строить не из чего.

Этапы ROADMAP

5 / 9
Этапы ROADMAP5ROADMAP

II

Что мод уже обещает

Метка — про текущую сборку. У карточки «в работе» две строки: что уже есть и чего не хватает, чтобы закрыть.

  • 01 в работе

    Свой ведьмак

    Уже есть Каждый ведёт своего Геральта и входит со своего последнего сохранения.

    Ещё нет Общее зерно сейва не передаётся. Уровень, умения и инвентарь ещё не отделены от мира хоста, поэтому свой ведьмак не закрыт.

  • 02 в игре

    Вход

    Уже есть Игра без флагов уже хост. Гость заходит своим ведьмаком по публичному адресу, общая локальная сеть не нужна.

  • 03 в игре

    Актуальная версия

    Уже есть Сборка стоит на текущем патче Remastered, DX12. Чужой exe хуки не получает. Это не заморозка на 5.01: с новым патчем игры пин переносится на него.

  • 04 в работе

    Кукла

    Уже есть Чужой ведьмак виден в мире: шаг, поворот и ник уже приходят.

    Ещё нет Два живых клиента ещё не закрыли забег друг вокруг друга. Пока этого нет, кукла остаётся в работе.

  • 05 в работе

    Бой

    Уже есть Удар, знаки, бомба, арбалет, парирование, уклон, прицел и кувырок уходят событием, соседняя кукла играет замах.

    Ещё нет Нет формулы оружия и хит-реакции. Удар и знак по одному врагу на двух клиентах ещё не сошлись.

  • 06 в игре

    Броня и мечи

    Уже есть Кукла надевает сталь, серебро, доспех, перчатки, штаны и сапоги. По сети идут шесть кодов, не имена.

  • 07 в работе

    Конь и лодка

    Уже есть Меш, посадка и движение коня и лодки уже реплицируются. На панели есть Пешком, Конь и Лодка.

    Ещё нет Поза в седле не держится: кукла стоит сквозь лошадь. Клипы посадки эту стойку не заменяют.

  • 08 в игре

    Соло-бот

    Уже есть Кнопка «Бот» на панели --debug гоняет куклу следом, по кругу или бродить. Второй человек не нужен.

    Ещё нет Это проверка одному, не живой игрок. Панель включается только с --debug.

  • 09 дальше

    Общий мир

    Уже есть Общих NPC, лута, времени, погоды и квестов в сборке нет.

    Ещё нет Слой ждёт закрытого боя. Пока двое не бьют одного врага и лут не сходится, мир не начинается.

  • 10 дальше

    Relay

    Уже есть Локальная игра идёт прямым входом. Кода комнаты и личного профиля в сессии нет.

    Ещё нет Интернет через relay не откроется раньше квестов. Лимит сессии задуман до восьми игроков.

  • 11 дальше

    Dedicated-сервер

    Уже есть Сессию сейчас держит открытая игра хоста. Отдельного процесса нет.

    Ещё нет Появится, когда мир сможет жить без окна Ведьмака. В этой сборке такого процесса нет.

III

ROADMAP

План разработки по слоям: следующий этап открывается по мере готовности предыдущего. Статусы, чеклисты и критерии готовности читаются напрямую из ROADMAP.md.

  1. 01 Протокол и симуляция сделано
  2. 02 Разведка 5.01 сделано
  3. 03 LAN и куклы в работе
  4. 04 Бой в работе
  5. 05 Внешность и транспорт в работе
  6. 06 NPC и мир ждёт
  7. 07 Квесты ждёт
  8. 08 Relay и профили ждёт
  9. 09 Пауза неактивного окна не в очереди
  1. ROADMAP · 01

    сделано

    Протокол и симуляция

    сделано локально, тесты зелёные

    • Версионированный бинарный кадр: ненадёжный снимок позы и надёжное событие.
    • Дельта и квантование позиции до сантиметров.
    • Интерес: не дальше радиуса игроков, не больше 64 NPC.
    • Интерполяция чужого актёра с буфером около 100 мс.
    • Очередь команд с сетевого потока на главный. Движок из этой очереди не вызывается: у симуляции нет зависимости на w3mp_engine.
    • Правило авторитета: локальное движение принимается, телепорт и невозможная скорость отвергаются.

    Готово, когда w3mp_tests покрывает потерю пакетов, дельту, лимит NPC и отвергнутый телепорт без запуска Ведьмака.

  2. ROADMAP · 02

    сделано

    Разведка 5.01

    сделано: хук записал позу, выход в меню без падения

    • Подтвердить путь exe. Ожидание: bin/x64_dx12/witcher3.exe. Если ремастер лежит в другом каталоге, записать фактический.
    • Снять SHA-256 и ProductVersion в signatures/5.01.json.
    • Найти тик, локального игрока, позицию и CRTTISystem. Адреса — паттерны в том же JSON, не константы в коде.
    • w3mp.asi логирует позу и выгружается без хуков геймплея, если хеш не совпал. Совпал — ставит хук тика и пишет одну строку позы в лог.

    Готово, когда плагин на чужом exe не ставит хуки, а на 5.01 пишет позу и не роняет выход в меню.

  3. ROADMAP · 03

    в работе

    LAN и куклы

    в работе: проверка по открытому UDP 40100 и публичному IPv4. Куклу спавнит scope-скрипт, позу в неё отдаёт ASI через консоль скриптов

    • Панель --debug в плагине, флаги --host и --client. Окно не на WitcherScript.
    • Куклу спавнит один scope-файл. Два клиента видят куклы друг друга.
    • Интерполяция из задачи 1 применяется к кукле, вместе с поворотом. Кости по сети не едут: едут режим движения и id действия.

    Готово, когда два клиента бегают друг вокруг друга на DX12 5.01 и расходятся без краша.

  4. ROADMAP · 04

    в работе

    Бой

    в работе, шаг 3 открыт: кнопка «Удар», попадание подтверждает хост

    • События: атака, знак, бомба, арбалет, парирование, уклонение, цель.
    • Попадание подтверждает хост. Эффект знака гость проигрывает локально от события.

    Готово, когда удар и знак по одному врагу на двух клиентах сходятся с авторитетом хоста.

  5. ROADMAP · 05

    в работе

    Внешность и транспорт

    броня и меши лошади и лодки есть. Поза в седле открыта: кукла стоит, ноги сквозь брюхо

    • Сет брони и мечи: кукла надевает сталь, серебро, доспех, перчатки, штаны и сапоги отправителя. Канал Gear несёт шесть кодов одним кадром, кнопка «Броня».
    • Лошадь и лодка: синхронизация посадки, перемещения и высадки, спавн и удаление мешей транспорта.

    Готово: второй клиент видит смену брони, посадку на лошадь и в лодку.

  6. ROADMAP · 06

    ждёт

    NPC и мир

    ждёт 4

    • Подавить локальный AI гостя в радиусе сессии. Реплика NPC приходит с хоста.
    • Агро, цель, масштаб здоровья от размера пати.
    • Факты, контейнеры, двери, время, погода. Локальная смена факта на госте отбрасывается, если это не подтверждение хоста.

    Готово, когда два клиента бьют одного и того же врага, лут и время суток не разъезжаются.

  7. ROADMAP · 07

    ждёт

    Квесты

    ждёт 6

    • Гость получает сейв-зерно, которое записал хост на 5.01, и грузит его. Сейв 4.04 в сессию не подмешивается.
    • Пути к Documents\The Witcher 3 идут через широкие Win32-API.
    • Журнал и блоки квестов ведёт хост. Диалог ведёт тот, кто взаимодействует; выбор уходит на хост.
    • Политика катсцены одна: либо пати на той же сцене, либо гости замерли до конца. Выбор фиксируется в коде после первой рабочей сцены.

    Готово, когда гость входит в сессию с зерна хоста, проходит одну развилку диалога и после повторного входа видит тот же журнал.

  8. ROADMAP · 08

    ждёт

    Relay и профили

    ждёт 3, в интернет не раньше 7

    • w3mp-relay: код комнаты, пробитие NAT, запасной UDP, SQLite-профиль персонажа.
    • В LAN прямой UDP остаётся. В интернете тот же протокол идёт через relay.
    • Профиль гостя не пишет инвентарь в сейв Геральта хоста.
    • Лимит 8 игроков. Несовпадение хеша exe — отказ на входе.

    Готово, когда два клиента за NAT входят по коду комнаты, личный инвентарь гостя переживает перезаход, девятый игрок и чужой exe получают отказ.

  9. ROADMAP · 09

    не в очереди

    Пауза неактивного окна

    низкий приоритет, не в очереди 3–8

    Готово, когда неактивное окно продолжает симуляцию без имитации переднего плана, а фокус переключается обычным кликом.

IV

Два способа держать мир

Сейчас мир живёт внутри открытой игры хоста. Выделенный сервер будет отдельным процессом, без Ведьмака на экране. Его ещё нет.

01

уже в сборке

Гость

Свой ведьмак, --client и публичный IPv4 хоста. Кукла на стороне остальных.

  • --client --ip=IPv4
  • Буфер позы ~100 мс
  • Канал Gear: 6 кодов
02

уже в сборке

Игра-хост

Ведьмак слушает UDP 40100 на всех интерфейсах и раздаёт снимки состояния мира.

  • UDP 0.0.0.0:40100
  • Снимки состояния мира
  • До 64 NPC в радиусе
03

ещё нет

Dedicated

Процесс без окна игры. Сессия останется, когда хост закроет Ведьмака. В этой сборке его нет.

  • Без окна witcher3.exe
  • Отдельный процесс мира
  • В сборке пока нет

V

Решения сессии

Абзацы берутся из docs/business/coop.md. Первое предложение снаружи, остальное — под спойлером.

  • Режим

    PvE-кооп на 2–8 игроков в одном мире хоста

  • Чей мир

    Сейв ремастера 5.01, который записал хост.

    Весь абзац

    Гости получают это зерно при входе

  • Чей персонаж

    У каждого свой ведьмак: уровень, умения, инвентарь, внешность.

    Весь абзац

    Это не инвентарь сейва хоста

  • Что общее

    NPC, лут, время, погода, факты, квесты, диалоги

  • Что не делаем в первой версии

    MMO, PvP, отдельный Гвинт, синхра партиклов

  • Какая игра

    Только Remastered 5.01.

    Весь абзац

    Не Next-Gen 4.04 и не Classic 1.32

  • Пара на одном ПК

    scripts/launch.ps1 --pair открывает хост и гость рядом, оба в окне, ники Host и Guest.

    Весь абзац

    Это проверка без второй машины. Оба продолжают один и тот же локальный сейв. Общее зерно по-прежнему не передаётся. Схема: session.md

  • Вход по сети

    Без флагов игра уже хост на 0.0.0.0:40100.

    Весь абзац

    Гость запускается с --client --ip публичного IPv4 хоста. Панель Host, Join и Бот только у --debug и сидит в углу окна игры. Общая LAN не нужна. Это не меню WitcherScript. Схема: session.md

  • Быстрый вход

    Хост и гость пропускают ролики, скрывают заставку экрана загрузки и грузят каждый своё последнее локальное сохранение.

    Весь абзац

    --menu оставляет обычное меню. Общее зерно сейва хоста — следующий шаг. Схема: session.md

  • Чужая кукла

    Видимый персонаж в мире хоста и гостя.

    Весь абзац

    Идёт к интерполированной позе другого игрока и поворачивается вместе с ним. Пока кукла едет, шаг даёт её собственный граф Gameplay, а не отдельный клип с нуля на каждом скачке. Стоя граф получает нулевую скорость и остаётся в idle. Плавание, нырок, блок, бой и прыжок приходят словом актёра и ставятся на этот же граф. Шаг Геральта на неё не копируется, и поза чужим клипом не затирается. Над ним его ник из --nickname. Скачок только если разрыв больше порога хоста, по умолчанию 15 м. Период выборки и потолок шага задаёт хост в w3mp.cfg, гость берёт тот же набор из пакета. Внешность: кукла надевает стальной и серебряный меч, доспех, перчатки, штаны и сапоги отправителя. На проводе шесть кодов предметов, не имена. Транспорт: на коне или в лодке кукла принимает позу всадника, спавнит под собой сущность лошади или лодки и ведет её вместе со своим движением. Если лошадь вызвана на X и стоит рядом неоседланной, она синхронизируется и видна другим игрокам; при посадке на E кукла занимает седло, а при спешивании лошадь остаётся в мире

  • Проверка одному

    Панель --debug, кнопка «Бот»: след повторяет путь, бродит ходит рядом, круг обходит Геральта.

    Весь абзац

    Кнопка «Удар» и F9: бот играет замах, без надписи на экране. Хост пишет Damage, если бот ближе 3 м. Кнопка «Знак» и F8: бот по очереди кастует Аард, Ирден, Игни, Квен и Аксий. Хост пишет Damage, если бот ближе 5 м и это не Квен. Кнопка справа от «Знак» и F6 по кругу: бомба, арбалет, парирование, уклон, прицел, кувырок. Хост пишет Damage за бомбу ближе 12 м и за арбалет ближе 30 м. Кнопка «Броня» реплицирует сет экипировки. Кнопка справа от «Бот» циклически переключает транспорт бота (пешком, конь верхом, лодка, конь пеший) для соло-проверки. Второй человек для этой проверки не нужен. Схема: session.md, combat.md

  • Экран

    С --debug в углу окна роль HOST или CLIENT, bind и цель.

    Весь абзац

    F10 прячет панель. F9 играет замах бота, F8 — знак, F6 — следующий приём (бомба, арбалет, парирование, уклон, прицел, кувырок), отдельной надписи нет. Подсказка внизу слева: «F6 - приём F7 - мышь F8 - знак F9 - удар F10 - меню». Заголовок панели можно перетащить. Кнопка «Игроки» открывает список ников и позиций. Свой адрес игроком не считается. Подключение и отключение показывают «ник подключился» и «ник отключился» и без этого флага

  • ESC

    Меню открывается, мир не ставится на паузу.

    Весь абзац

    Установщик переписывает файл меню в игре: одного скрипта мало, движок ставит паузу из этого файла. Новый клиент получает тот же шаг из install.ps1. Сворачивание окна меню закрывает. Неактивное окно не останавливает мир: время и кукла идут, пока фокус у другого клиента. Клавиши остаются у активного окна. Статус: в работе, ждёт проверку в игре

VI

Как войти

Шаги берутся из pack/README.txt. Нужно окно или рамка без exclusive fullscreen: панель и уведомления живут поверх окна.

  1. 01

    Распакуй архив в любую папку.

  2. 02

    В папке архива выполни: powershell -NoProfile -ExecutionPolicy Bypass -File install.ps1

    Весь абзац

    Скрипт найдёт Ведьмак в Steam, попросит права администратора, положит w3mp.asi в bin\x64_dx12 и один раз поставит dinput8.dll, если его там ещё нет. Потом запустит игру.

  3. 03

    Нужен именно Remastered 5.01. Другой exe плагин отвергнет: в логе будет rejected, hooks not installed.

  4. 04

    Игра в окне или без рамки. Поверх exclusive fullscreen панель и уведомление не видны.

  5. 05

    Запуск без флагов уже хост: UDP 40100 на всех интерфейсах. Отдельного окна нет. Свой публичный IPv4 напиши второму игроку. На роутере должен быть открыт UDP 40100. Рядом с w3mp.asi лежит w3mp.cfg: хост читает его один раз. Если файла нет, install.ps1 кладёт значения по умолчанию и готовый файл не затирает. Гость эти числа берёт из пакета хоста.

  6. 06

    Второй запускает: powershell -NoProfile -ExecutionPolicy Bypass -File install.ps1 --client --ip=этот.адрес

    Весь абзац

    Порт остаётся 40100. Общая локальная сеть не нужна. Первым шлёт гость. Хост отвечает на адрес, с которого пришёл пакет.

  7. 07

    Панель в левом верхнем углу окна игры: powershell -NoProfile -ExecutionPolicy Bypass -File install.ps1 --debug

    Весь абзац

    На ней роль HOST или CLIENT, bind, цель и кнопки Host, Join, Бот, Игроки. Заголовок можно перетащить. «Игроки» открывает список ников и позиций. Пока курсор на панели, камера игры не крутится. F10 закрывает панель и список, внизу слева остаётся «F10 - дебаг меню». Ещё раз F10 открывает. По умолчанию панель открыта.

  8. 08

    Оба заходят в мир, не остаются в меню, и двигаются.

  9. 09

    Лог: bin\x64_dx12\w3mp.log

    Весь абзац

    Должны быть accepted 5.01, w3mp: host 0.0.0.0:40100 или w3mp: client и адрес, w3mp: udp 0.0.0.0:40100. У гостя — w3mp: client и вписанный адрес. У хоста — w3mp: peer с адресом, откуда пришёл пакет. Когда второй двигается, у хоста появляется w3mp: remote и три числа. И наоборот. Своя поза пишется как w3mp: pose и на втором компьютере: её пишет сам плагин. Новый игрок показывает «ник подключился» сверху окна игры. Уход — «ник отключился», если пакетов нет дольше 3 с. В exclusive fullscreen уведомления нет. Ник и скрытие бота читаются из файла позы. Для них -debugscripts не нужен. Ник: --nickname Имя в параметрах запуска. Без него будет Player и три цифры. Ник виден над куклой другого игрока. Над своим Геральтом его нет. После входа в мир: w3mp: doll 0 armed, затем w3mp: pose file и всплывашка с ником, например w3mp: Bot. w3mp: exec closed значит, что порт 37001 не открыт. Это запасной канал. -debugscripts сам не добавляется: с ним загрузка мира идёт в разы дольше. Флаг можно передать вручную. w3mp: pose file create или move — файл позы не записался. w3mp: no pose — скрипт его не прочитал. Кукла сначала стоит в 8 м по X от Геральта, потом встаёт на чужую позу. Строка w3mp: remote без числа id в начале пишет наблюдатель w3mp_watch. Строка плагина начинается с id игрока. Адрес в строке «откуда» не должен быть адресом этого компьютера. Своё эхо игроком не считается. Панель для этого нужна с --debug. Если куклы нет, в Documents\The Witcher 3\scriptslog.txt ищется строка W3MP. В mods.settings должна быть секция [modw3mp] и Enabled=1.

VII

Кадры

png, jpg и webp из каталога shots репозитория WitcherMP и из static/shots этого сайта появляются здесь сами.

В каталоге shots пока пусто. Положи png, jpg или webp в shots репозитория или в static/shots сайта.

VIII

Журнал

Админ публикует записи после сверки с репозиторием. Коммиты про сборку, документацию и инструменты агента скрыты.

В этой выборке пусто.

IX

Бета-тестеры

Войди через Telegram. Пустят только тех, кого админ уже записал.

ruen