Skip to content

Latest commit

 

History

History
162 lines (135 loc) · 21.4 KB

File metadata and controls

162 lines (135 loc) · 21.4 KB

Стив вместо Геральта: можно ли сделать как в SkyCraft

Проверено 2026-10-03 на Witcher 3 5.00c (сейв в Белом Саду) пробными exec-функциями spike\mod\modMCW\content\scripts\local\mcw_steve.ws. Метки: [проверено] — в игре, [проверить] — нет.

Как это сделано в SkyCraft

chasmlol/SkyCraft (Skyrim SE 1.7, docs/DESIGN.md):

  • Игроком управляет скрытый клиент Майнкрафта (Fabric): движение и физика, удары, щит, лук, инвентарь, здоровье. Окно MC скрыто, но «думает», что в фокусе. Ввод из окна Скайрима плагин отдаёт клиенту MC.
  • Скайрим держит невидимую куклу игрока. Каждый кадр плагин ставит её и её Havok-капсулу в позицию из MC, а камеру Скайрима переписывает видом MC (матрица, FOV).
  • Руку с предметом и HUD рисует сам Майнкрафт в отдельных слоях. Плагин встраивает их в кадр Скайрима через общие текстуры GPU, с тестом глубины для слоя мира.
  • Коллизия Скайрима отдаётся в MC. Havok-лучи сеткой вокруг игрока превращаются в AABB, а миксин подмешивает их в столкновения MC.
  • Бой. Удар MC по прокси NPC → плагин зовёт боевой конвейер Скайрима (реакция, кровь, агрессия). Удар NPC по кукле перехватывается и уходит в MC как player.hurt: броня, щит и блок считает MC.
  • Всё это — нативный плагин SKSE на C++ (CommonLibSSE-NG, Address Library, хуки, найденные в Ghidra).

Что из этого есть в Ведьмаке без нативного кода

Часть SkyCraft У нас Итог
Камера по виду MC CStaticCamera из gameplay\poster\poster_camera.w2ent + Run(), затем TeleportWithRotation каждый кадр [проверено] 54 перемещения/с, камера рендера в медиане в 1 см от цели, максимум 10 см (один кадр движения). «Полёт» 5 м/с вперёд и 3 м/с вверх над Белым Садом плавный. У шаблона камера сдвинута от origin (121, −40, 146 см) и смотрит назад — это калибруется или делается свой шаблон в REDkit
Камера через GetGameCamera() SetCameraWorldPosition/Rotation каждый кадр [проверено] не годится: штатный контроллер тянет камеру обратно, ошибка 1–2,4 м
Кукла игрока TeleportWithRotation игрока каждый кадр [проверено] 157 телепортов за 3 с, ошибка в медиане 3 см; Геральт висит в 4 м над землёй и движется по заданной траектории. Разовый телепорт с SetGravity(false) и BlockAllActions куклу не держит: падает и сдвигается
Скрыть тело было SetVisibility(false) у CActor; с 2026-10-04 — только предметы Геральта (MCWF_HideItems) [проверено] SetVisibility(false) прячет Геральта из кадра, но и от ИИ: деревья поведения NPC проверяют видимость цели (CBTCondIsVisible), враги ходили рядом, не нападая. Тело Геральта — предметы (голова, тело, волосы, броня), прячутся они, актёр видим
Удар MC по NPC было W3DamageAction + ProcessAction; с 2026-10-04 — W3Action_Attack (удар Геральта его мечом x урон MC / 6, ванильные парирование и уклонение NPC) [проверено] волк: HP 145 → 125 (−20) с 3 м, реакция и полоска здоровья; 2026-10-04 — удары и стрелы MC по гусям и курам
Урон NPC по игроку → в MC @wrapMethod(W3PlayerWitcher) ReduceDamage копит урон и обнуляет его [проверено] взрыв и горение: 120 событий, 692 HP перехвачено, здоровье Геральта полное
Рука, предмет и HUD Майнкрафта оверлей окна: захват окна MC → вырезание фона на GPU → прозрачное окно поверх игры (cs2-gothic\overlay\gpu_overlay.cpp, уже работает в CS2 × Готика) [проверить] с клиентом MC; Ведьмак в оконном режиме — уже так
Блоки мира MC наши сущности modMCWBlocks через mcw_batch [проверено] живой прогон (bridge\SMOKE.md)
Коллизия Ведьмака для физики MC сейчас: колонны рельефа mcw_ground → barrier, 40 колонн/с [проверить] для элитр мало: нужен пакетный луч (100 лучей за exec, ответ ≤ 1999 байт) или рельеф из .w2ter офлайн
Клиент MC вместо сервера Fabric-клиент, скрытое окно «в фокусе», ввод из моста, рисует только руку и HUD на зелёном фоне [проверить] — главный новый кусок
Ввод мост читает клавиатуру (GetAsyncKeyState, уже есть) и мышь (Raw Input с RIDEV_INPUTSINK), шлёт в клиент MC [проверить]

Вывод

Да, схему SkyCraft можно повторить, и нативный плагин для этого не нужен. Всё, что в SkyCraft делают хуки (камера, кукла, урон в обе стороны), в Ведьмаке 5.00c доступно из скриптов, а мы до них дотягиваемся exec-каналом (1 кадр задержки, до 32 вызовов за кадр). Удары мечом, блок щитом, лук и полёт на элитрах — это логика клиента Майнкрафта; Ведьмаку остаётся показать камеру, куклу и ответную реакцию NPC.

Чем будет хуже SkyCraft:

  • Задержка. Там общая память и синхронизация по кадрам, у нас TCP и exec: мышь → клиент MC → мост → камера Ведьмака ≈ 2–3 кадра (50–75 мс при 40 FPS). Смягчение: обзор мышью мост шлёт в Ведьмака сам, мимо MC; камеру сглаживает таймер внутри мода (каждый кадр по времени движка) [проверить].
  • Нет теста глубины для руки и предметов MC: оверлей рисуется поверх всего. Для руки и HUD это нормально (в MC они тоже поверх мира), для вида от третьего лица — нет.
  • Вид от третьего лица (F5): тело Стива — сущности Ведьмака из коробок (голова, торс, руки, ноги, плащ-элитры), собранные тем же конвейером, что блоки, со скином MC; позы конечностей мост берёт из модели игрока MC и шлёт каждый кадр [проверить]. С тенями и светом Ведьмака, но без скиннинга.
  • Катсцены, диалоги, лошадь, меню Ведьмака — управление на это время отдаём Ведьмаку, как SkyCraft отдаёт сцены Скайриму. Пауза без фокуса — в движке: окно Ведьмака должно оставаться в фокусе, клиент MC скрыт.

Вид от первого лица: сделано (2026-10-03)

Взгляд считает Ведьмак, позиция глаза — от Геральта (потом — от клиента MC). Код — mcw_steve.ws (mcwf_on, mcwf_eye, mcwf_state, таймер MCWF_Tick на игроке), в мосте — клавиша F4 и секция [fp] в bridge.toml.

  • [проверено] Таймер @addMethod(W3PlayerWitcher) timer function + AddTimer( имя, 0, true ) компилируется и тикает каждый кадр (~41 тик/с при 40 FPS).
  • [проверено] Мышь в скрипте: theInput.GetActionValue('GI_MouseDampX'/'GI_MouseDampY') — 0,4 единицы на пиксель, +X вправо, +Y вниз. При sens = 30 — 0,12° на пиксель, как у штатной камеры. Камера рендера смотрит туда же, куда скрипт (курс и наклон совпали до сотых).
  • [проверено] Камера в голове Геральта (z + 1,75 м), тело скрыто. WASD ведёт Геральта примерно по взгляду (курс движения 53,8° при взгляде 42,3°, рядом стена дома) [проверить] на открытом месте.
  • [проверено] Строить по центру экрана: mcw_look берёт камеру рендера, то есть нашу. Блок земли поставлен на землю и второй — на его грань; дальше 4,5 блока Майнкрафт отказывает («too far»).
  • Прицела на экране нет — он придёт с HUD Майнкрафта в оверлее.
  • Для Майнкрафта: mcwf_eye(x, y, z, vx, vy, vz) — позиция глаза от клиента MC, ответ — взгляд Ведьмака (look <yaw> <pitch>); таймер экстраполирует позицию по скорости до 0,1 с.

Скрытый клиент Майнкрафта: сделано (2026-10-03)

Клиент — mcclient/README.md, оверлей — overlay\mcw_overlay.cpp, сторона моста — bridge\client.py, подмена Геральта на сервере — mc\...\Mcw.java (dropPuppet, joined, left).

  • [проверено] Клиент 1.21.11 из dev-окружения Loom (run_client.ps1) стартует за ~15 с и сразу заходит на сервер. Окно создаётся скрытым и показывается через SetWindowPos(HWND_BOTTOM, SWP_NOACTIVATE): при запуске клиента Ведьмак остался на переднем плане и не встал на паузу.
  • [проверено] Подмена Геральта: клиент с ником Geralt входит — марионетка уходит (PlayerList.remove, playerdata сохранена), игрок клиента стоит в её точке; клиент выходит — марионетка возвращается из той же playerdata. Между ними 1–2 тика без Геральта: сообщения моста получают error no_geralt, hello ждёт.
  • [проверено] Windows.Graphics.Capture снимает окно клиента (OpenGL), даже когда оно целиком закрыто окном Ведьмака. Окно клиента оверлей держит в размер клиентской области Ведьмака (1920×1080), захват ложится 1:1.
  • [проверено] Клиент без мира: 42–60 FPS при 1920×1080 параллельно с Ведьмаком.
  • [проверено] В Ведьмаке от первого лица видны рука с предметом, хотбар, сердца, голод, опыт и белый прицел Майнкрафта. ЛКМ в окне Ведьмака → мост (GetAsyncKeyState, 100 Гц) → клиент: рука машет; от нажатия до сдвига руки на экране 120–180 мс (кадры экрана каждые ~60 мс). NumPad2 выбрал второй слот: в руке земля вместо камня.
  • [проверено] Удары Геральта на время режима Стива блокирует mcwf_block (BlockAction с источником MCWF): на ЛКМ Геральт не бьёт, но игра показывает панель подсказок («Стальное оружие / Ускориться…») [проверить], какой блок её прячет.
  • Ловушки, найденные по дороге, — в NOTES.md, раздел «Клиент Майнкрафта 1.21.11».

Ходит клиент MC: сделано (2026-10-03)

В режиме Стива (client.drive, по умолчанию) WASD, пробел, левые Shift и Ctrl уходят клиенту, движение и бой Геральта заблокированы (mcwf_block 2). Клиент шлёт глаз каждый кадр (eye), мост ставит туда камеру Ведьмака и куклу (mcwf_mc, src 1), взгляд Ведьмака возвращается клиенту (look).

  • [проверено] Ходьба: 5 м за 1,2 с (4,3 м/с, ходьба MC), задний ход в гору с 1,68 до 2,55 по высотам Ведьмака, камера идёт следом на высоте глаза MC. Инерции Ведьмака нет: разгон и торможение — как в MC.
  • [проверено] Земля для физики — непрерывные высоты колонн 1×1 из mcw_ground (terrain), а не округлённый barrier: с ним склон превращался в ступени по блоку, и MC без прыжка застревал (подъём на ступеньку — 0,6).
  • [проверено] Камера poster_camera.w2ent от первого лица: FOV 60, вертикальный. С вертикальным 60 у клиента рамка блока MC легла на блок Ведьмака (с горизонтальным масштаб расходился в 1,75 раза, как tan 30° / tan 18°). Камера геймплея при этом — 67.
  • [проверено] От первого лица прячутся и надетые предметы (MCWF_HideItems, раз в 30 кадров заново): мечей, волос и головы в кадре нет даже при взгляде под ноги.
  • [проверено] Новый блок в Ведьмаке растворяется ~0,5 с (CreateEntity); созданный заранее скрытым и показанный SetHideInGame( false, true ) — виден сразу, и после телепорта тоже. Блоки идут из пула: от клика до блока ~120 мс, MC сам предсказывает установку, и рамка с подсветкой переезжают на новый блок через ~50 мс.
  • [проверено] Провал: если клиент оказался внутри столбика земли, MC его не сталкивает (с формой, в которой сущность уже стоит), и игрок падает в пустоту. Кукла шла за ним кадр за кадром и ушла под мир, мост отдал эту точку серверу, и сервер возвращал туда игрока после каждой смерти. Теперь клиент выталкивает игрока на поверхность колонны, а мост не ведёт камеру и куклу, если ноги MC больше чем на 2 м ниже известной земли.

Дома, лошадь, тело Стива: сделано (2026-10-03)

  • [проверено] Коллизия домов для физики MC (mcw_cols в mcw_collide.ws, bridge\solid.py, Solid клиента): вошёл в дом Белого Сада, стены, шкафы и полки держат, проход между комнатами есть, на крышу не выбрасывает. Многие дома деревни цельные и в самом Ведьмаке. Створки толкаемых дверей тоньше шага лучей (25 см) — проходятся насквозь.
  • [проверено] Лошадь MC: X в режиме Стива — сервер ставит её за спиной (Horses), ПКМ — сесть, 10 м за 2,5 с, Shift — слезть; сервер не откатывает её на своём barrier (миксин на handleMoveVehicle). В Ведьмаке — 17 коробок modMCWModels с седлом, поза от клиента каждый кадр (horses -> mcwm_horse). Ноги в движении со стороны ещё не видел.
  • [проверено] Тело Стива: 20 коробок со скином на костях Геральта (mcwm_skin), видны от третьего лица; от первого лица спрятаны. Геральт под ними — актёр видимый, спрятаны его предметы (тело, голова, волосы, броня — предметы): невидимый актёр прячет и всё прикреплённое к нему. Катсцену в этом теле ещё не видел.

Бой: сделано (2026-10-04)

Код — mcw_combat.ws (Ведьмак), bridge\combat.py (мост), mc\...\Npcs.java и ArrowWalls.java (сервер), NpcProxies и Outline.cracks (клиент); настройки — [combat], [arrows] в bridge.toml. Устройство — DEVELOPMENT.md, «Как устроено»; ловушки — NOTES, «Бой, стрелы, трещины».

  • [проверено] Прокси NPC: невидимые стойки для брони с размером капсулы NPC на сервере, у клиента — позиции от моста напрямую перед каждым выбором цели. Удары мечом и стрелы MC по гусям и курам Белого Сада проходят, NPC в Ведьмаке получает урон и реакцию.
  • [проверено] Стрела arrow_01.w2ent стримит меш: пул стрел, созданный на дальней парковке, был невидим; пул под Геральтом — виден (снимок окна).
  • [проверено] CalcBoundingBox людей — 2–3 м в ширину (статичные габариты меша): хитбокс — по капсуле.
  • [проверить] После исправлений 2026-10-04: нападают ли враги на видимую куклу; парирование и уклонение NPC при задержке удара 0,2 с; щит MC как защита куклы; стрелы в стенах домов; шкала урона (ref_mc_dmg) против волков и бандитов.

Что делать дальше (по порядку риска)

Актуальный порядок работ с критериями готовности — DEVELOPMENT.md, раздел «Что дальше». Ниже — исходный набросок на момент проверки.

  1. Клиент MC (Fabric, тот же 1.21.11): скрытое окно «в фокусе», ввод из сокета моста, мир не рисуется (фон — ключевой цвет), рисуются рука, предмет и HUD. Захват и оверлей поверх Ведьмака — gpu_overlay.
  2. Мост: поза игрока из клиента MC → кукла и камера в Ведьмаке каждый кадр (одной exec-функцией), мышь и клавиши → в клиент MC; режим «Ведьмак управляет сам» для сцен.
  3. Коллизия для физики MC: пакетные лучи вокруг игрока, потом рельеф из .w2ter.
  4. Прокси NPC в MC (позиции и хитбоксы из FindGameplayEntitiesInRange), удары → ProcessAction, урон по игроку → player.hurt.
  5. Тело Стива для F5 из коробок, элитры.