MC Toolkit

Руководства / Команды и данные

Отрицательные координаты ломают математику чанков в двух местах, а не в одном

Усекающее деление помещает блок −1 в чанк 0 вместо −1, а обычный % даёт смещение внутри чанка −1 вместо 15. Оба неверны, и оба выглядят правильно, пока не уйдёшь западнее точки появления.

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

Две операции

chunk  = floor(block / 16)          not  trunc(block / 16)
offset = ((block % 16) + 16) % 16   not  block % 16

Координаты региона — та же пара, на уровень выше, с 32 вместо 16:

region     = floor(chunk / 32)   ->  r.<x>.<z>.mca
regionOff  = ((chunk % 32) + 32) % 32

Итак, регион — это 32 × 32 чанка, то есть 512 × 512 блоков.

Где каждая из них кусается

Деление. В большинстве языков оно усекается к нулю, а floor округляет к минус бесконечности. Для положительных чисел они совпадают, а для всех отрицательных, не являющихся точным кратным, расходятся:

  • блок −1 → floor(−1/16) = −1 ✓, но trunc(−1/16) = 0 ✗

Блок −1 находится на один блок западнее начала координат и принадлежит чанку −1. Усечение помещает его в чанк 0, рядом с блоком +1. Каждый отрицательный индекс чанка получается на единицу больше, чем нужно.

Остаток. В JavaScript, Java, C и большинстве других языков % сохраняет знак левого операнда:

  • блок −1 → правильное смещение 15, но −1 % 16 = −1 ✗

Смещение −1 вообще не является позицией внутри чанка шириной 16. Обращение к массиву блоков с таким индексом либо выбрасывает исключение, либо молча читает не ту ячейку.

Разобранный пример

Блок −1290 по одной оси:

шагправильнонаивно
чанкfloor(−1290/16) = −81trunc = −80 ✗
смещение в чанке6−1290 % 16 = −10 ✗
регионfloor(−81/32) = −3trunc = −2 ✗
смещение в регионе15−81 % 32 = −17 ✗

Четыре значения, четыре неверных ответа, и ни один из них не выходит за границы настолько, чтобы выглядеть явно сломанным. Регион −3 охватывает чанки от −96 до −65, и чанк −81 находится на 15 позиций от его начала — ровно это и возвращает исправленный остаток.

Преобразование Незера теряет данные в одном направлении

Из Верхнего мира в Незер делят на 8, и тоже с округлением вниз:

netherX = floor(overworldX / 8)

Обратный переход умножает вашу точную позицию на 8, так что весь блок Незера 125 отображается обратно куда-то в 1000–1007, в зависимости от того, где внутри этого блока вы стоите. Для блочных координат это не круговой рейс. floor отбрасывает остаток:

  • Верхний мир 1000 → Незер 125 → обратно 1000 ✓
  • Верхний мир 1007 → Незер 125 → блочная координата даёт 1000 ✗ — на семь блоков меньше

Погрешность составляет от 0 до 7 блоков на ось, то есть до 7 по X и 7 по Z одновременно. Именно поэтому для точной привязки порталов координату Незера нужно записывать, а не выводить заново: после деления исходную позицию в Верхнем мире уже не восстановить.

Для хаба в Незере это редко имеет значение — 7 блоков укладываются в собственный радиус захвата портала. Но для связывания двух порталов, которые не должны перехватывать трафик друг друга, это очень важно.

Отрицательные координаты Верхнего мира усугубляют ситуацию привычным образом: Верхний мир −1 даёт Незер floor(−1/8) = −1, тогда как усечение даёт 0 и отправляет вас не в ту сторону оси.

Набор инструментов для координат →

Другие руководства

Смотреть все →