مختصات منفی محاسبات چانک را در دو نقطه دچار مشکل میکنند، نه یکی
تقسیم با قطع اعشار، بلوک −1 را به جای چانک −1 در چانک 0 قرار میدهد، و یک % ساده آفست درونچانکی −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 rounds toward negative infinity. They agree for positives and disagree for every negative that is not an exact multiple:
- بلوک
−1→floor(−1/16) = −1✓, buttrunc(−1/16) = 0✗
بلوک −1 یک بلوک در غرب مبدأ است و به چانک −1 تعلق دارد. قطع اعشار آن را در کنار بلوک +1 در چانک 0 قرار میدهد. هر اندیس منفی چانک یک واحد بالاتر از مقدار واقعی به دست میآید.
باقیمانده. در JavaScript، Java، C و بیشتر زبانهای دیگر، % keeps the sign of the left operand:
- بلوک
−1→ correct offset15, but−1 % 16 = −1✗
یک آفست −1 اصلاً موقعیتی درون یک چانک با عرض 16 نیست. ایندکسگذاری آرایه بلوک با آن، یا خطا میدهد یا بدون خطا خانهٔ اشتباهی را میخواند.
یک مثال حلشده
بلوک −1290 روی یک محور:
| مرحله | درست | سادهانگارانه |
|---|---|---|
| چانک | floor(−1290/16) = −81 | trunc = −80 ✗ |
| آفست در چانک | 6 | −1290 % 16 = −10 ✗ |
| ریجن | floor(−81/32) = −3 | trunc = −2 ✗ |
| آفست در ریجن | 15 | −81 % 32 = −17 ✗ |
چهار مقدار، چهار پاسخ اشتباه، هیچکدام آنقدر خارج از محدوده نیستند که مشخصاً خراب به نظر برسند. ریجن −3 چانکهای −96 تا −65 را پوشش میدهد، و چانک −81 به اندازهٔ 15 واحد از شروع آن فاصله دارد — که دقیقاً همان چیزی است که باقیماندهٔ تصحیحشده برمیگرداند.
تبدیل به ندر در یک جهت همراه با اتلاف داده است
اورورلد به ندر بر 8 تقسیم میشود، و همچنین جزء صحیح (کف) گرفته میشود:
netherX = floor(overworldX / 8)
بازگشت در 8 ضرب میشود. این نیست یک رفت و برگشت کامل. floor throws away the remainder, so returning lands you on a multiple of 8:
- اورورلد
1000→ Nether125→ back to1000✓ - اورورلد
1007→ Nether125→ back to1000✗ — seven blocks short
میزان خطا 0 تا 7 بلوک در هر محور است، بنابراین همزمان تا 7 در X و 7 در Z. این کل دلیلی است که اتصال دقیق پورتال نیازمند یادداشت کردن مختصات ندر است به جای محاسبهٔ مجدد آن: وقتی تقسیم کردید، موقعیت اورورلد که از آن آمده دیگر قابل بازیابی نیست.
برای یک هاب ندر این موضوع بهندرت اهمیت دارد — 7 بلوک درون شعاع دریافت خود پورتال قرار میگیرد. برای متصل کردن دو پورتال که نباید ترافیک یکدیگر را بربایند، اهمیت بسیار زیادی دارد.
مختصات منفی اورورلد به همان شیوهٔ آشنا وضعیت را بدتر میکنند: اورورلد −1 gives Nether floor(−1/8) = −1, while truncation gives 0 and sends you to the wrong side of the axis.