Ujemne współrzędne psują matematykę chunków w dwóch miejscach, nie w jednym
Dzielenie z obcięciem umieszcza blok −1 w chunku 0 zamiast −1, a zwykły % daje przesunięcie w chunku −1 zamiast 15. Oba są błędne i oba wyglądają poprawnie, dopóki nie pójdziesz na zachód od spawnu.
Każde obliczenie chunka jest trywialne w dodatniej ćwiartce i błędne w pozostałych trzech. Są dokładnie dwa miejsca, w których się to psuje, są one od siebie niezależne, a oba dają wyniki, które wyglądają wiarygodnie.
Dwie operacje
chunk = floor(block / 16) not trunc(block / 16)
offset = ((block % 16) + 16) % 16 not block % 16
Współrzędne regionu to ta sama para, o poziom wyżej, z 32 zamiast 16:
region = floor(chunk / 32) -> r.<x>.<z>.mca
regionOff = ((chunk % 32) + 32) % 32
Region ma więc 32 × 32 chunki, czyli 512 × 512 bloków.
Gdzie każde z nich gryzie
Dzielenie. Większość języków obcina w stronę zera, a floor zaokrągla w stronę minus nieskończoności. Zgadzają się dla liczb dodatnich i różnią się dla każdej ujemnej, która nie jest dokładną wielokrotnością:
- blok
−1→floor(−1/16) = −1✓, aletrunc(−1/16) = 0✗
Blok −1 leży jeden blok na zachód od początku układu i należy do chunka −1. Obcięcie umieszcza go w chunku 0, obok bloku +1. Każdy ujemny indeks chunka wychodzi o jeden za wysoko.
Reszta z dzielenia. W JavaScripcie, Javie, C i większości innych % zachowuje znak lewego argumentu:
- blok
−1→ poprawne przesunięcie15, ale−1 % 16 = −1✗
Przesunięcie −1 w ogóle nie jest pozycją wewnątrz 16-blokowego chunka. Indeksowanie nim tablicy bloków albo zgłosi błąd, albo po cichu odczyta niewłaściwą komórkę.
Rozpisany przykład
Blok −1290 na jednej osi:
| krok | poprawnie | naiwnie |
|---|---|---|
| chunk | floor(−1290/16) = −81 | trunc = −80 ✗ |
| przesunięcie w chunku | 6 | −1290 % 16 = −10 ✗ |
| region | floor(−81/32) = −3 | trunc = −2 ✗ |
| przesunięcie w regionie | 15 | −81 % 32 = −17 ✗ |
Cztery wartości, cztery błędne odpowiedzi, żadna z nich nie poza zakresem na tyle, by wyglądać oczywiście na zepsutą. Region −3 obejmuje chunki od −96 do −65, a chunk −81 leży 15 od jego początku — co jest dokładnie tym, co zwraca poprawiona reszta z dzielenia.
Konwersja do Netheru jest stratna w jednym kierunku
Z Overworldu do Netheru dzieli się przez 8, i to również zaokrągla w dół:
netherX = floor(overworldX / 8)
Powrót mnoży twoją dokładną pozycję przez 8, więc cały blok Netheru 125 mapuje się z powrotem na coś w zakresie 1000–1007, w zależności od tego, gdzie w tym bloku stoisz. To nie jest podróż w obie strony dla współrzędnych blokowych. floor wyrzuca resztę:
- Overworld
1000→ Nether125→ z powrotem1000✓ - Overworld
1007→ Nether125→ współrzędna blokowa mówi1000✗ — siedem bloków za mało
Błąd wynosi od 0 do 7 bloków na oś, więc do 7 na X i 7 na Z jednocześnie. To jest cały powód, dla którego precyzyjne łączenie portali wymaga zapisania współrzędnej Netheru, a nie wyprowadzania jej ponownie: gdy już podzielisz, pozycja w Overworldzie, z której pochodziła, nie jest już odzyskiwalna.
W przypadku hubu w Netherze rzadko to ma znaczenie — 7 bloków mieści się w promieniu przechwytywania samego portalu. Przy łączeniu dwóch portali, które nie mogą podkradać sobie ruchu, ma to ogromne znaczenie.
Ujemne współrzędne Overworldu pogarszają to w znajomy sposób: Overworld −1 daje Nether floor(−1/8) = −1, podczas gdy obcięcie daje 0 i wysyła cię na niewłaściwą stronę osi.