При одинаковом пинге 2 один игрок видит соперника с опозданием 44 мс, а другой — 6 мс. Разницу даёт фаза тиков — сдвиг между тиками сервера и вашего клиента. В табе её не видно, но именно она решает размены, КБ и тот самый «рич 3,2».
Ниже — разбор и документация: как устроена фаза, почему она плывёт, как её выравнивает мод Tick Sync, сколько это даёт на самом деле и что вышло, когда мы проверили всё на себе.
Возьмём двух игроков с одинаковым пингом 2, одинаковыми клиентами и реакцией. Они бегут друг на друга — и один попадает первым в четырёх разменах из пяти. Это не читы и не «у него руки лучше».
Пинг 2 у обоих, а игрок Б бьёт первым в 4 разменах из 5.
В Майнкрафте есть задержка, которую пинг в табе не показывает вообще. Она случайная, у каждого своя и доходит до 50 мс — даже когда пинг 2. Например, при одинаковых 2 мс в табе реальная задержка у меня без мода может быть 44 мс, а у PynPun с модом — 6 мс.
В табе у обоих 2 мс, на деле 44 и 6 мс (пример). В таб попадает только дорога пакета.
Один PvP-клиент прямо обещает в рекламе «минус 25 мс к любому серверу». Правда ли это — проверим. По пунктам:
Майнкрафт считает мир не непрерывно, а шагами — тиками. Их 20 в секунду, значит один тик длится 50 мс. Между тиками мир стоит, а в тик игра двигает игроков и мобов и считает удары.
Мир двигается шагами по 50 мс, а сервер и клиент — два метронома на одной скорости.
Важная деталь: тикает и сервер, и ваш клиент — каждый по своим часам. Сервер начал считать тики, когда запустился, а клиент — когда вы запустили игру. Темп одинаковый, 20 в секунду, но щелчки не совпадают — как у двух метрономов, которые включили в разные моменты.
Источник: Minecraft Wiki — Tick, 20 игровых тиков в секунду.
Представьте курьера, который кладёт газету в ящик строго каждые 50 минут: в 12:00, 12:50, 13:40. Вы тоже проверяете ящик раз в 50 минут, но по своему расписанию.
Если вы заглядываете в 12:45, 13:35 и 14:25, газета каждый раз лежит 45 минут, и вы всегда читаете старые новости. Если в 12:05, 12:55 и 13:45 — она лежит всего 5 минут. Курьер одинаково быстрый, вы проверяете одинаково часто: разница только в сдвиге вашего расписания относительно курьера. Этот сдвиг и есть фаза.
Газета лежит 45 или 5 минут; сдвиг расписания — это фаза. Вторая половина ролика переводит аналогию на Minecraft.
В Майнкрафте курьер — это сервер: в такт своим тикам он рассылает, где стоят игроки. Дорога — это пинг. Проверка ящика — ваш клиентский тик: только в него игра применяет пришедшие данные — двигает соперника, его хитбокс и вас самих, включая ваш КБ.
То же пишет автор мода Tick Sync: клиент ждёт конца текущего тика, прежде чем применить пришедший пакет. В его примере пакет пришёл на 2-й миллисекунде тика и ждёт 48.
Пинг — это путь туда и обратно, поэтому при пинге 2 пакет от сервера летит к каждому игроку 1 мс. Сервер отправляет данные в 0, 50 и 100 мс, и к обоим они приходят в 1, 51 и 101 мс.
У игрока А тики идут в 44, 94 и 144 мс. Пакет пришёл в 1, а ближайший тик только в 44: данные лежат 43 мс, и так каждый раз. У игрока Б тики в 6, 56 и 106 мс: пакет пришёл в 1, тик в 6 — данные лежат 5 мс.
Пакет летит 1 мс и ждёт тика: у А — 43 мс, у Б — 5 мс.
В табе у обоих 2. Но А видит соперника с опозданием 1 + 43 = 44 мс, а Б — 1 + 5 = 6 мс. Разница 38 мс, и пинг её не показывает: при пинге 2 почти вся задержка — это ожидание тика.
Дорога плюс ожидание: 44 мс против 6 мс при одинаковом пинге.
Игрок Б — в удачной фазе. В комьюнити это состояние иногда называют «Потоком». Числа 44 и 6 — пример: у каждого игрока своя фаза, а арифметику можно проверить в симуляции из материалов к статье.
Удачная фаза работает как пинг на десятки миллисекунд ниже. В PvP это заметно в трёх местах: размен, КБ и «рич».
Игрок с удачной фазой раньше видит соперника в зоне удара, раньше кликает — и его удар первым долетает до сервера. Грубо говоря, в размене решает сумма: пинг плюс ожидание своего тика. У игрока А это 2 + 43 = 45, у игрока Б — 2 + 5 = 7.
Пинг + ожидание: 4 из 5 разменов при одинаковом пинге и 7 из 10 у игрока с пингом 20.
В нашей симуляции игрок Б при таких фазах бьёт первым в 81% разменов — примерно в четырёх из пяти. Игрок с пингом 20 и удачной фазой (20 + 5 = 25) забирает около 70% разменов у игрока с пингом 2 и неудачной фазой (2 + 45 = 47). Не все размены, потому что клик тоже ждёт своего тика и добавляет случайности.
Отбрасывание приходит к жертве пакетом и применяется только в её тик. С пингом 20 и удачной фазой вы начинаете лететь через 15 мс после того, как сервер засчитал удар: 10 мс на дорогу и 5 на ожидание. С пингом 2 и неудачной фазой — через 46 мс. Пинг в десять раз хуже, а отлетаете раньше.
Пинг 20 с удачной фазой отлетает через 15 мс, пинг 2 с неудачной — через 46 мс.
Reach Display меряет дистанцию на вашем экране в момент клика — и не врёт. Но у соперника картинка старше. Спринт — около 5,6 блока в секунду, значит 38 мс — это примерно 0,2 блока.
У вас на экране 2,8 блока, у него в тот же момент — около 3,0. А если он ещё и отлетает в комбе, на его записи удар выглядит как с 3,1–3,2.
У вас 2,8 блока, у него 3,0, а в комбе — 3,2.
Правы оба: каждый видит свою картинку. А сервер проверяет удар по своим координатам, а не по чьему-то экрану.
Фазу никто не выбирает. Клиент считает тики с запуска игры, сервер — со своего запуска, и подгонять их друг к другу никто не пытается. Поэтому ожидание выпадает случайно: любое значение от 0 до 50 мс одинаково вероятно, в среднем — 25.
Шесть тысяч запусков игры: ожидание распределено ровно, среднее — 25 мс.
Перезапустили игру — новая лотерея. А вот перезаход на тот же сервер фазу, скорее всего, не меняет: клиент продолжает считать тики от запуска игры.
И фаза не стоит на месте. Часы компьютера и сервера идут чуть-чуть по-разному. Если ваш тик на деле длится, скажем, 50,003 мс, за один тик это ничто, а примерно за 14 минут набегает целый круг в 50 мс. На разных компьютерах полный круг занимает от десятка минут до часа.
Пример: 15 минут игры за 15 секунд. «Поток», граница, вязко и снова «Поток».
Поэтому бывает так: сначала всё летает, потом соперник начинает дёргаться, потом игра становится вязкой, а затем снова приходит «Поток». Подёргивание — это момент, когда пакеты приходят ровно на границе вашего тика: один успевает и лежит 1 мс, следующий опаздывает и лежит 49 — и модель соперника дёргается.
Фраза «вчера сервер летал, а сегодня вязкий» иногда буквально про фазу.
Бои на пинге 2 из этого разбора мы снимали на моём сервере — CisPractice. Из Москвы пинг туда около 2 мс, так что почти вся ваша задержка там и есть фаза. Хотите проверить её на себе — заходите: IP cisprac.xyz.
Остальные раунды нашего теста сыграны на шведском sworder.xyz с пингом 20 — подробности в разделе «Наш тест».
Фаза — скрытая задержка от 0 до 50 мс, которой нет в пинге. Она случайная, держится минутами и плывёт. Её можно выровнять — и тогда у вас всегда будет удачная.
Что даёт выравнивание фазы и чего не даёт, по пунктам.
| Даёт | Не даёт |
|---|---|
| Свежую картинку: до −18 мс на приёме данных | Другой пинг: дорога пакета остаётся той же |
| Чаще первый удар в разменах | Ускорение клика: он всё равно ждёт тика |
| Быстрый отлёт после удара | Полной пользы на скачущем Wi‑Fi и 60 FPS |
| Одинаковое ощущение в каждой сессии | Честности, если мод только у части игроков |
Дальше — как это устроено на самом деле, с кодом.
На самом деле ожиданий два. Первое — сервер ждёт свой тик, чтобы обработать ваши пакеты: удары и движение. Второе — клиент ждёт свой тик, чтобы применить пакеты сервера: позиции и КБ.
Два ожидания, сервер с очередью против Paper, код Paper и вывод: остаётся ожидание на клиенте.
Первое ожидание зависит от ядра сервера. Ванильный сервер 1.21.9 и новее (и 1.8) разбирает пакеты игроков только в начале тика — это ещё от 0 до 50 мс на каждый удар. Paper будит сервер, как только пакет пришёл, и обрабатывает его сразу, если сервер в этот момент не занят тиком.
Это видно прямо в коде Paper 1.21.11. В патче PacketProcessor, строки 31–43 есть комментарий «wake up main thread inbetween ticks to process packets» и вызов LockSupport.unpark. В патче MinecraftServer, строка 918 — «process packets while waiting inbetween ticks», а в строках 1012–1015 видно, как Paper заменяет ванильный processQueuedPackets() в начале тика. Оптимизация Moonrise для Fabric делает то же: «Handle packets sent while the integrated/dedicated server is waiting for next tick (lowering perceived latency)».
Значит, на Paper и его форках удары засчитываются по приходу. Остаётся только второе ожидание — на вашей стороне, и убрать его может только мод на клиенте.
Tick Sync — открытый мод под Fabric для 1.21.1 и новее, включая версии 26.x (сборка 1.4.0 есть для 1.21.1–1.21.11 и 26.1–26.3, скачать — на странице версий). Он сдвигает ваши тики так, чтобы они наступали сразу после прихода пакетов. Работает в четыре шага:
Четыре шага мода: один длинный тик, и ожидание падает с 43 до ~5 мс.
Перезаходить на сервер с модом не нужно: дрейф часов и смену пинга он ловит сам, а при входе на сервер начинает замер заново. Игра при этом не ускоряется: тиков по-прежнему 20 в секунду.
Функция matchTickSync считает сдвиг, а shiftNextTickDuration растягивает следующий тик (строки 259–295). По умолчанию мод только растягивает тики. Режим fast sync умеет и укорачивать — тогда клиент на мгновение тикает чаще 20 раз в секунду. Для античита это похоже на Timer, поэтому на PvP-серверах fast sync лучше не включать.
Фрагмент исходников Tick Sync: расчёт сдвига и длинный тик.
Цена базового режима — примерно раз в одну-три минуты один тик длиннее обычного на 15–25 мс, когда мод подправляет фазу. Это микрозаминка, которую вы вряд ли заметите. При FPS ниже 40 и сильно скачущей сети мод не синхронизирует вовсе (canSync, строки 131–134).
При ровной сети и высоком FPS — около 17–18 мс, а не 25, как обещает реклама. MCPVP Client пишет про «Client-Server tick alignment to reduce your effective latency by 25ms to any server». Но 25 — это ровно среднее того самого ожидания от 0 до 50, то есть теоретический потолок.
Цитата рекламы: «минус 25 мс к любому серверу».
На практике мод оставляет запас на скачки пинга — джиттер: если пакет опоздает хоть на миллисекунду, он пролежит почти 50. Я повторил алгоритм Tick Sync в симуляции прямо по его исходникам. Вот средний выигрыш по модели — это оценка, а не замер:
| Джиттер | Выигрыш при 240 FPS, мс | Выигрыш при 60 FPS, мс |
|---|---|---|
| 1 мс (хороший кабель) | 17,6 | 7,1 |
| 2 мс | 14,3 | 8,3 |
| 3 мс | 12,5 | 7,5 |
| 5 мс | 10,0 | 5,3 |
| 8 мс | 7,4 | 2,8 |
| 10 мс | 5,5 | 2,3 |
| 15 мс | 1,2 | 0,4 |
Столбики «джиттер → выигрыш» при 240 и 60 FPS, затем линии «пинг → выигрыш»: Paper, Wi‑Fi, сервер с очередью.
На Paper выигрыш не зависит от величины пинга: те же ≈ 17 мс и при пинге 2, и при 120, если сеть ровная. Портит его не высокий пинг, а скачущая сеть и низкий FPS.
Клиентский тик случается только на границе кадра, а на 60 FPS кадр длится 17 мс — выигрыш падает примерно до 7 мс. От 144 FPS он почти полный. На ванильном сервере с очередью выигрыш идёт пилой: от 0 до 35 мс в зависимости от пинга.
Частый вопрос: если пинг и так 2, мод уведёт его в минус? Нет. Мод срезает ожидание тика, а не дорогу пакета: ожидание бывает от 0 до 50, в среднем 25, а мод делает его примерно 7. На пинге 2 было в среднем 1 + 25 = 26 мс, стало 1 + 7 = 8.
Минус 18 мс из ожидания, а не из пинга; кабель, 60 FPS и Wi‑Fi.
С модом каждый из нас выигрывал на 35 процентных пунктов чаще — но это иллюстрация, а не доказательство. Я (Hanosuko) и PynPun — оба из Москвы, пинг одинаковый. Мы сыграли 32 раунда на двух серверах — на моём CisPractice с пингом 0–2 и на шведском sworder.xyz с пингом 20 — и ставили мод по очереди: сначала мне, потом PynPun, потом снова мне.
| Сессия | Сервер | Пинг, мс | Мод у | Счёт Hanosuko : PynPun |
|---|---|---|---|---|
| 1 | cisprac.xyz | 0 | Hanosuko | 4 : 5 |
| 2 | cisprac.xyz | 2 | PynPun | 0 : 4 |
| 3 | sworder.xyz (Швеция) | 20 | PynPun | 1 : 5 |
| 4 | sworder.xyz (Швеция) | 20 | Hanosuko | 6 : 7 |
Раунды по сессиям: в клетках — голова того, у кого мод (зелёная — выиграл раунд, красная — проиграл), затем доли побед.
| Игрок | Без мода | С модом |
|---|---|---|
| PynPun | 12 из 22 (55%) | 9 из 10 (90%) |
| Hanosuko | 1 из 10 (10%) | 10 из 22 (45%) |
Мод был у меня, а PynPun без мода поймал природный «Поток»: из первых восьми раундов он взял шесть. Минут через пять «Поток» у него уплыл — ровно как в теории про дрейф фазы, — и дальше я взял четыре раунда из пяти.
Сессия 4 на sworder.xyz: 6 из 8 у PynPun в «Потоке», потом 4 из 5 у Hanosuko с модом.
Совпало: тот, кто играл без мода, жаловался на «рич 3,2» у соперника — это та самая старая картинка. Ощущение, что искусственный «Поток» хуже природного, тоже объяснимо: мод держит запас 6–16 мс, а удачная природная фаза бывает 1–5 мс. Мод даёт не лучший «Поток», а гарантированный неплохой.
Спорно: ощущения от КБ противоречили друг другу, а жалобу «моделька лагает» с модом стоит сверить со значком синхронизации на отладочном экране.
Что совпало с теорией и что спорно.
32 раунда — это мало, и мы знали, у кого мод. Точный тест Фишера даёт p ≈ 0,06 — на грани значимости. В сессии 4 разница «до/после» даёт p ≈ 0,09, причём границу мы провели уже после игры.
Чтобы такой тест стал доказательством, синхронизацию должен включать третий человек и не говорить кому. Нужно по 40–50 раундов на каждое положение и включённый у обоих отладочный экран Tick Sync — он даже с выключенной синхронизацией показывает реальную фазу игрока. Все бои нашего теста целиком — в телеграм-канале t.me/hanosuko.
Better Hitreg — другой популярный мод, и он про другое. В момент удара он сам проигрывает красную вспышку и звук, не дожидаясь подтверждения сервера, а серверный дубль потом глушит. Попадание ощущается быстрее примерно на ваш пинг.
Но это только вид и звук: сервер засчитывает удар в тот же момент, КБ и размены не меняются. Автор сам пишет в README: «All custom hits are in appearance only, your actual hits are not modified in any way». А выравнивание фазы меняет реальное: вы видите позиции, хитбоксы и свой КБ свежее.
Better Hitreg показывает вспышку сразу, но только для вида; выравнивание фазы делает свежее сами данные.
| Better Hitreg | Tick Sync | |
|---|---|---|
| Что лечит | Задержку отклика на ваш удар | Ожидание входящих данных до тика |
| Как | Сам рисует вспышку и звук, глушит серверный дубль | Сдвигает тики сразу после прихода пакетов |
| Что меняется в игре | Ничего, только вид и звук | Позиции, хитбоксы и ваш КБ свежее |
| Выигрыш | ≈ ваш пинг, только в ощущениях | До ~18 мс настоящей задержки |
| Риск | Может показать попадание, которого не было | Почти нет; fast sync похож на Timer |
Фаза есть у всех, и это не баг — так Майнкрафт работал всегда. Но если мод выравнивания стоит только у вас, у вас до 15–18 мс преимущества над теми, у кого его нет.
Фаза есть у всех; мод только у вас — преимущество 15–18 мс; мод у всех — честно.
Поэтому прежде чем ставить мод, проверьте правила сервера: где-то это могут считать нарушением. Честный вариант — когда мод есть у всех, например сервер кладёт его в свою сборку. Тогда «Поток» становится нормой, и лотерея исчезает.
А разница в пинге между игроками остаётся: её мод не выравнивает. Админам стоит посмотреть на плагин KnockbackSync: он пересчитывает отбрасывание так, будто оно сделано на клиенте, и делает КБ одинаковым при разном пинге.
Не верьте на слово — фазу можно проверить четырьмя способами.
useDebugScreen в файле config/ticksync-config.json. Экран показывает Tick Delay — сколько пакеты ждут вашего тика. Он работает даже с выключенной синхронизацией, то есть показывает вашу природную фазу./hitreg alertDelays в Better Hitreg. После каждого удара мод пишет в чат, через сколько миллисекунд вы увидели отлёт соперника. В удачной фазе это число меньше, правда, оно идёт шагами по 50 мс.Четыре способа проверки. Сообщения чата на видео — пример, а не запись из игры.
Чтобы выравнивание фазы дало полный эффект, нужны четыре вещи:
Чек-лист из финала ролика.
Все числа о выигрыше — оценка по моделям, а не замер в игре. Скрипты и данные теста — в репозитории tick-phase-minecraft на GitHub и в архиве с материалами к статье (ZIP, 13 КБ), для запуска нужны Python 3, numpy и scipy.
simulation.py: оба бегут с одной скоростью, реакция одинаковая, сервер на Paper. Результат: при пинге 2 у обоих и ожидании 43 против 5 игрок Б бьёт первым в 81% разменов, при 20 + 5 против 2 + 45 — в 70%.ticksync_model.py, которая повторяет алгоритм мода по исходникам (коммит d0ae181): замер, запас 6–16 мс, порог и сдвиг тика. Условия: джиттер по нормальному закону, часы клиента ±20 ppm, серверу на тик до отправки дано 5 мс. Простая модель с идеальным запасом даёт потолок на 3–5 мс выше.test_raundy.csv, разбор с тестом Фишера — в test_analysis.py.Ссылки на код закреплены за конкретными коммитами, чтобы строки не уехали.
| Источник | Что подтверждает |
|---|---|
| Minecraft Wiki — Tick | 20 тиков в секунду, тик = 50 мс |
| Tick Sync — Modrinth | Клиент ждёт конца тика, прежде чем применить пакет; мод сдвигает тики на клиенте |
| Tick Sync — версии | Сборка 1.4.0 для 1.21.1–1.21.11 и 26.1–26.3 |
| Tick Sync — TickSyncMain.java | Расчёт сдвига и растягивание тика; fast sync — отдельный режим |
| Paper 1.21.11 — патч PacketProcessor | Paper будит сервер на каждый пакет между тиками |
| Paper 1.21.11 — патч MinecraftServer | Ваниль разбирает очередь пакетов в начале тика, Paper это меняет |
| Moonrise — Modrinth · код | Обработка пакетов во время ожидания тика снижает задержку |
| MCPVP Client | Реклама «−25 мс к любому серверу» за счёт выравнивания тиков |
| Better Hitreg — README · Modrinth | Кастомные удары только для вида, настоящие не меняются; команда /hitreg alertDelays |
| KnockbackSync | Выравнивание КБ при разном пинге на стороне сервера |
| tick-phase-minecraft — GitHub | Наши тесты: скрипты моделей и раунды по сессиям |
| t.me/hanosuko | Записи всех боёв нашего теста |