Megapack: Factorio ishlab chiquvchilari 200 o'yinchi uchun multiplayer bilan muammoni qanday hal qilishdi

Megapack: Factorio ishlab chiquvchilari 200 o'yinchi uchun multiplayer bilan muammoni qanday hal qilishdi
Shu yilning may oyida men o'yinchi sifatida ishtirok etdim MMO voqealari KatherineOfSky. O'yinchilar soni ma'lum bir raqamga yetganda, har bir necha daqiqada ularning ba'zilari "tushib qolishini" payqadim. Baxtingizga (lekin men uchun emas), men aloqani uzgan o'yinchilardan biri edim har safar, hatto yaxshi aloqa bilan ham. Men buni shaxsiy muammo sifatida qabul qildim va muammoning sabablarini qidira boshladim. Uch haftalik disk raskadrovka, sinov va tuzatishlardan soβ€˜ng, xato nihoyat tuzatildi, ammo sayohat unchalik oson boβ€˜lmadi.

Ko'p o'yinchi o'yinlari bilan bog'liq muammolarni kuzatib borish juda qiyin. Ular odatda juda o'ziga xos tarmoq parametrlari va juda o'ziga xos o'yin sharoitlarida (bu holda 200 dan ortiq o'yinchiga ega) sodir bo'ladi. Muammoni takrorlash mumkin bo'lsa ham, uni to'g'ri tuzatib bo'lmaydi, chunki to'xtash nuqtalarini kiritish o'yinni to'xtatadi, taymerlarni chalkashtirib yuboradi va odatda ulanish vaqti tugashiga olib keladi. Lekin qat'iyat va ajoyib vosita deb nomlangan rahmat jirkanch Men nima bo'layotganini bilishga muvaffaq bo'ldim.

Muxtasar qilib aytganda, xatolik va kechikish holatini simulyatsiya qilishning to'liq amalga oshirilmaganligi sababli, mijoz ba'zan bir soat siklida taxminan 400 ta o'yin ob'ektini o'yinchining kiritish tanlash harakatlaridan iborat tarmoq paketini yuborishi kerak bo'lgan vaziyatga tushib qoladi ( biz buni "mega-paket" deb ataymiz). Keyin server nafaqat ushbu kiritish harakatlarini to'g'ri qabul qilishi, balki ularni boshqa barcha mijozlarga ham yuborishi kerak. Agar sizda 200 ta mijoz bo'lsa, bu tezda muammoga aylanadi. Serverga havola tezda tiqilib qoladi, bu paketlarning yo'qolishiga va qayta so'ralgan paketlar kaskadiga olib keladi. Kiritish harakatini kechiktirish yanada ko'proq mijozlarning megapaketlarni yuborishiga olib keladi, bu esa ko'chkining yanada kattalashishiga olib keladi. Baxtli mijozlar tiklanishga muvaffaq bo'lishadi, qolganlari esa yiqilib tushadi.

Megapack: Factorio ishlab chiquvchilari 200 o'yinchi uchun multiplayer bilan muammoni qanday hal qilishdi
Muammo juda muhim edi va uni tuzatish uchun menga 2 hafta kerak bo'ldi. Bu juda texnik, shuning uchun men quyida shirali texnik tafsilotlarni tushuntiraman. Lekin birinchi navbatda shuni bilishingiz kerakki, 0.17.54-iyun kuni chiqarilgan 4 versiyasidan boshlab, vaqtinchalik ulanish muammolari sharoitida multiplayer yanada barqaror bo'lib qoldi va kechikishlarni yashirish juda kam xatoga aylandi (kamroq sekinlashuv va teleportatsiya). Men jangovar kechikishlarni yashirish usulini ham o'zgartirdim va bu uni biroz yumshoqroq qiladi deb umid qilaman.

Multiplayer Mega Pack - Texnik tafsilotlar

Oddiy qilib aytganda, o'yinda multiplayer shunday ishlaydi: barcha mijozlar o'yin holatini taqlid qiladi, faqat o'yinchi ma'lumotlarini qabul qiladi va yuboradi ("kirish harakatlari" deb ataladi), Kirish harakatlari). Serverning asosiy vazifasi uzatishdir Kirish harakatlari va barcha mijozlar bir xil soat siklida bir xil amallarni bajarishini nazorat qilish. Bu haqda ko'proq maqolada o'qishingiz mumkin FFF-149.

Server qanday harakatlarni bajarish haqida qaror qabul qilishi kerakligi sababli, o'yinchining harakatlari taxminan shu yo'lda harakat qiladi: o'yinchi harakati -> o'yin mijozi -> tarmoq -> server -> tarmoq -> o'yin mijozi. Bu shuni anglatadiki, har bir o'yinchining harakati faqat tarmoq bo'ylab sayohat qilgandan keyin amalga oshiriladi. Shu sababli, o'yin juda sekin ko'rinadi, shuning uchun o'yinda multiplayer kiritilgandan so'ng, kechikishlarni yashirish mexanizmi joriy etildi. Kechikishni yashirish boshqa o'yinchilarning harakatlari va server qarorlarini hisobga olmasdan o'yinchi kiritishini simulyatsiya qiladi.

Megapack: Factorio ishlab chiquvchilari 200 o'yinchi uchun multiplayer bilan muammoni qanday hal qilishdi
Faktorio o'yin holatiga ega O'yin holati karta, o'yinchi, ob'ektlar va boshqa barcha narsalarning to'liq holati. U barcha mijozlarda serverdan olingan harakatlar asosida aniq simulyatsiya qilinadi. O'yin holati muqaddasdir va agar u serverdan yoki boshqa mijozdan farq qila boshlasa, u holda sinxronizatsiya sodir bo'ladi.

tashqari O'yin holati bizda kechikish holati mavjud Kechikish holati. U asosiy holatning kichik to'plamini o'z ichiga oladi. Kechikish holati muqaddas emas va shunchaki o'yinchi kiritishlari asosida o'yin holati kelajakda qanday ko'rinishini tasvirlaydi Kirish harakatlari.

Shu maqsadda biz yaratilgan nusxani saqlaymiz Kirish harakatlari kechikish navbatida.

Megapack: Factorio ishlab chiquvchilari 200 o'yinchi uchun multiplayer bilan muammoni qanday hal qilishdi
Ya'ni, mijoz tomonidagi jarayon oxirida rasm quyidagicha ko'rinadi:

  1. Murojaat qiling Kirish harakatlari barcha o'yinchilar uchun O'yin holati ushbu kiritish harakatlari serverdan qanday qabul qilingan.
  2. Biz hamma narsani kechikish navbatidan olib tashlaymiz Kirish harakatlari, serverga ko'ra, allaqachon qo'llanilgan O'yin holati.
  3. O'chir Kechikish holati va uni qayta o'rnating, shunda u xuddi shunday ko'rinadi O'yin holati.
  4. Biz barcha amallarni kechikish navbatidan boshlab qo'llaymiz Kechikish holati.
  5. Ma'lumotlarga asoslangan O'yin holati ΠΈ Kechikish holati Biz o'yinni o'yinchiga beramiz.

Bularning barchasi har bir o'lchovda takrorlanadi.

Juda qiyinmi? Tinchlanmang, bu hammasi emas. Ishonchsiz Internet ulanishlarini qoplash uchun biz ikkita mexanizmni yaratdik:

  • O'tkazib yuborilgan belgilar: server buni hal qilganda Kirish harakatlari o'yinning zarbasida qatl qilinadi, keyin u qabul qilmagan bo'lsa Kirish harakatlari ba'zi bir o'yinchi (masalan, kechikishning kuchayishi tufayli) u kutmaydi, lekin bu mijozga xabar beradi "Men sizning e'tiboringizga olmadim. Kirish harakatlari, men ularni keyingi satrga qo'shishga harakat qilaman." Bu bitta o'yinchining ulanishi (yoki kompyuteri) bilan bog'liq muammolar tufayli xaritani yangilash hamma uchun sekinlashmasligi uchun amalga oshiriladi. Shuni ta'kidlash joizki Kirish harakatlari e'tibordan chetda qolmaydi, shunchaki chetga suriladi.
  • To'liq aylanish kechikishi: Server har bir mijoz uchun mijoz va server o'rtasidagi aylanish kechikishi qancha ekanligini taxmin qilishga harakat qiladi. Har 5 soniyada, agar kerak bo'lsa, mijoz bilan yangi kechikish haqida muzokaralar olib boradi (ulanish o'tmishda o'zini qanday tutganiga qarab) va shunga mos ravishda aylanish kechikishini oshiradi yoki kamaytiradi.

O'z-o'zidan, bu mexanizmlar juda oddiy, ammo ular birgalikda ishlatilganda (bu ko'pincha ulanish muammolari bilan sodir bo'ladi), kod mantig'ini boshqarish qiyin bo'ladi va juda ko'p chekka holatlar mavjud. Bundan tashqari, ushbu mexanizmlar ishga tushganda, server va kechikish navbati maxsusni to'g'ri amalga oshirishi kerak Kirish harakati nom ostida Harakatni TheNextTick ichida to'xtating. Buning yordamida, agar ulanish bilan bog'liq muammolar mavjud bo'lsa, xarakter o'z-o'zidan yugurmaydi (masalan, poezd oldida).

Endi biz sizga ob'ektni tanlash qanday ishlashini tushuntirishimiz kerak. O'tkazilgan turlardan biri Kirish harakati ob'ektni tanlash holatidagi o'zgarishdir. U barchaga o'yinchi qaysi ob'ekt ustida harakat qilayotganini aytadi. Tasavvur qilganingizdek, bu mijozlar tomonidan yuboriladigan eng keng tarqalgan kiritish amallaridan biridir, shuning uchun tarmoqli kengligini tejash uchun biz uni iloji boricha kamroq joy egallash uchun optimallashtirdik. Uning ishlash usuli shundan iboratki, har bir ob'ekt tanlanganda, o'yin mutlaq, yuqori aniqlikdagi xarita koordinatalarini saqlash o'rniga, oldingi tanlovdan past aniqlikdagi nisbiy ofsetni saqlaydi. Bu yaxshi ishlaydi, chunki sichqonchani tanlash avvalgi tanlovga juda yaqin bo'ladi. Bu ikkita muhim talabni keltirib chiqaradi: Kirish harakatlari Ular hech qachon o'tkazib yuborilmasligi kerak va to'g'ri tartibda to'ldirilishi kerak. Ushbu talablar uchun javob beradi O'yin holati. Lekin vazifa beri Kechikish holati o'yinchi uchun "etarlicha yaxshi ko'rinishda" ular kechikish holatidan mamnun emaslar. Kechikish holati hisobga olmaydi ko'plab chekka holatlar, soat sikllarini o'tkazib yuborish va ikki tomonlama uzatish kechikishlarini o'zgartirish bilan bog'liq.

Bu qaerga ketayotganini allaqachon taxmin qilishingiz mumkin. Biz nihoyat megapaket muammosining sabablarini ko'rishni boshlaymiz. Muammoning ildizi shundaki, ob'ektni tanlash mantig'iga tayanadi Kechikish holati, va bu holat har doim ham to'g'ri ma'lumotni o'z ichiga olmaydi. Shunday qilib, megapaket quyidagi kabi hosil bo'ladi:

  1. Pleyerda ulanish muammolari bor.
  2. Soat tsikllarini o'tkazib yuborish va ikki tomonlama uzatishning kechikishini tartibga solish mexanizmlari o'ynaydi.
  3. Kechikish holati navbati bu mexanizmlarni hisobga olmaydi. Bu ba'zi harakatlarning muddatidan oldin olib tashlanishiga yoki noto'g'ri tartibda bajarilishiga olib keladi, natijada noto'g'ri Kechikish holati.
  4. Pleyerda ulanish muammosi bor va serverga yetib olish uchun 400 tsiklgacha simulyatsiya qiladi.
  5. Har bir belgida ob'ekt tanlovini o'zgartiruvchi yangi harakat yaratiladi va serverga yuborish uchun tayyorlanadi.
  6. Mijoz serverga 400+ ob'ekt tanlash o'zgarishlarining mega-to'plamini yuboradi (va boshqa harakatlar bilan: tortishish holatlari, yurish holatlari va boshqalar ham bu muammodan aziyat chekdi).
  7. Server 400 ta kiritish amallarini oladi. Har qanday kiritish harakatlarini o'tkazib yuborishga ruxsat berilmaganligi sababli, u barcha mijozlarga ushbu amallarni bajarishni buyuradi va ularni tarmoq bo'ylab yuboradi.

Ajablanarlisi shundaki, tarmoqli kengligini tejash uchun mo'ljallangan mexanizm katta tarmoq paketlarini yaratish bilan yakunlandi.

Biz bu muammoni yangilash va orqada qolgan navbatni qo'llab-quvvatlashning barcha chekka holatlarini tuzatish orqali hal qildik. Bu biroz vaqt talab qilgan bo'lsa-da, oxir-oqibat tezkor xakerlarga tayangandan ko'ra, uni to'g'rilashga arziydi.

Manba: www.habr.com

a Izoh qo'shish