Megapack: Factorio 200-ойыншы көп ойыншы мәселесін қалай шешті

Megapack: Factorio 200-ойыншы көп ойыншы мәселесін қалай шешті
Осы жылдың мамыр айында мен ойыншы ретінде қатыстым MMO оқиғалары KatherineOfSky. Ойыншылардың саны белгілі бір санға жеткенде бірнеше минут сайын олардың кейбіреулері «құлап кететінін» байқадым. Бақытымызға орай (бірақ мен үшін емес), мен байланысын үзген ойыншылардың бірі болдым әр кезде, тіпті жақсы байланыс болса да. Мен мұны жеке сынақ ретінде қабылдадым және мәселенің себептерін іздей бастадым. Үш апта бойы жөндеуден, тестілеуден және түзетулерден кейін қате түзетілді, бірақ сапар оңай болған жоқ.

Көп ойыншы ойындарындағы проблемаларды қадағалау өте қиын. Олар әдетте өте нақты желі параметрлерінде және өте ерекше ойын шарттарында (бұл жағдайда 200-ден астам ойыншы бар) орын алады. Тіпті мәселені қайта шығаруға болатын болса да, оны дұрыс жөндеу мүмкін емес, себебі тоқтау нүктелерін енгізу ойынды тоқтатады, таймерлерді шатастырады және әдетте қосылымның күту уақытының аяқталуына әкеледі. Бірақ табандылық пен керемет құралдың арқасында жасырын Мен не болып жатқанын біліп үлгердім.

Қысқасы, қатеге және кідіріс күйін модельдеудің толық орындалмауына байланысты клиент кейде бір сағаттық циклде шамамен 400 ойын нысандарын ойыншының енгізу таңдау әрекеттерінен тұратын желілік пакетті жіберуге тура келетін жағдайға тап болады ( біз мұны «мега-пакет» деп атаймыз). Содан кейін сервер осы енгізу әрекеттерінің барлығын дұрыс қабылдап қана қоймай, оларды барлық басқа клиенттерге жіберуі керек. Егер сізде 200 клиент болса, бұл тез арада мәселеге айналады. Серверге сілтеме тез бітеліп қалады, бұл пакеттердің жоғалуына және қайта сұралған пакеттердің каскадына әкеледі. Енгізу әрекетін кейінге қалдыру одан да көп клиенттердің мегапакеттер жіберуіне себеп болады, бұл көшкіннің одан да үлкен болуына әкеледі. Бақытты клиенттер қалпына келеді, қалғандарының бәрі құлап кетеді.

Megapack: Factorio 200-ойыншы көп ойыншы мәселесін қалай шешті
Мәселе өте маңызды болды және оны түзетуге 2 апта қажет болды. Бұл өте техникалық, сондықтан мен төменде күрделі техникалық мәліметтерді түсіндіремін. Бірақ алдымен, сіз 0.17.54 маусымда шыққан 4 нұсқасынан бастап уақытша қосылым ақаулары жағдайында мультиплеердің тұрақтылығы жоғарылағанын және кідірістерді жасыру әлдеқайда аз қателескенін (баяулау және телепортация) білуіңіз керек. Мен сондай-ақ жауынгерлік лагты жасыру әдісін өзгерттім және бұл оны біршама тегіс етеді деп үміттенемін.

Көп ойыншы Mega Pack - Техникалық мәліметтер

Қарапайым тілмен айтқанда, ойындағы мультипликатор келесідей жұмыс істейді: барлық клиенттер ойынның күйін имитациялайды, тек ойыншының енгізуін қабылдайды және жібереді («енгізу әрекеттері» деп аталады), Енгізу әрекеттері). Сервердің негізгі міндеті – тасымалдау Енгізу әрекеттері және барлық клиенттердің бір сағат циклінде бірдей әрекеттерді орындауын бақылау. Бұл туралы толығырақ посттан оқи аласыз FFF-149.

Сервер қандай әрекеттерді орындау керектігі туралы шешім қабылдауы керек болғандықтан, ойыншының әрекеттері шамамен осы жолмен қозғалады: ойыншы әрекеті -> ойын клиенті -> желі -> сервер -> желі -> ойын клиенті. Бұл әрбір ойыншының әрекеті желі бойынша айналмалы саяхат жасағаннан кейін ғана орындалатынын білдіреді. Осыған байланысты ойын өте баяу болып көрінеді, сондықтан ойынға мультипликатор енгізілгеннен кейін бірден кешігулерді жасыру механизмі енгізілді. Кідірісті жасыру басқа ойыншылардың әрекеттерін және сервер шешімдерін есепке алмай, ойыншы енгізуін имитациялайды.

Megapack: Factorio 200-ойыншы көп ойыншы мәселесін қалай шешті
Factorio ойын күйіне ие Ойын жағдайы картаның, ойыншының, нысандардың және басқалардың толық күйі. Ол серверден алынған әрекеттерге негізделген барлық клиенттерде детерминирленген модельденеді. Ойын күйі қасиетті және егер ол серверден немесе кез келген басқа клиенттен ерекшелене бастаса, синхрондау орын алады.

қоспағанда Ойын жағдайы бізде кідіріс бар Кешіктіру күйі. Ол негізгі күйдің шағын жиынын қамтиды. Кешіктіру күйі қасиетті емес және жай ғана ойыншы енгізулеріне негізделген ойын күйінің болашақта қандай болатынын бейнелейді Енгізу әрекеттері.

Осы мақсатта біз жасалғанның көшірмесін сақтаймыз Енгізу әрекеттері кідірту кезегінде.

Megapack: Factorio 200-ойыншы көп ойыншы мәселесін қалай шешті
Яғни, клиент жағындағы процестің соңында сурет келесідей болады:

  1. Қолдану Енгізу әрекеттері барлық ойыншылар Ойын жағдайы осы енгізу әрекеттерінің серверден алынған жолы.
  2. Біз бәрін кешіктіру кезегінен алып тастаймыз Енгізу әрекеттері, серверге сәйкес, ол қазірдің өзінде қолданылған Ойын жағдайы.
  3. Жою Кешіктіру күйі және оны қалпына келтіріңіз, осылайша ол дәл солай көрінеді Ойын жағдайы.
  4. Біз кешіктіру кезегінен бастап барлық әрекеттерді қолданамыз Кешіктіру күйі.
  5. Деректер негізінде Ойын жағдайы и Кешіктіру күйі Біз ойынды ойыншыға береміз.

Мұның бәрі әр өлшемде қайталанады.

Тым қиын ба? Демалмаңыз, бұл бәрі емес. Сенімсіз Интернет қосылымдарының орнын толтыру үшін біз екі механизмді жасадық:

  • Қабылданбаған кенелер: сервер мұны шешкенде Енгізу әрекеттері ойынның ырғағында орындалады, егер ол алмаса Енгізу әрекеттері кейбір ойыншы (мысалы, кідірістің артуына байланысты), ол күтпейді, бірақ бұл клиентке «Мен сіздің назарыңызды ескермедім. Енгізу әрекеттері, мен оларды келесі жолақта қосуға тырысамын. Бұл бір ойыншының қосылуына (немесе компьютеріне) байланысты ақауларға байланысты картаны жаңарту басқалардың барлығы үшін баяуламауы үшін жасалады. Айта кеткен жөн Енгізу әрекеттері назардан тыс қалмайды, жай ғана шетке қалдырылады.
  • Толық бару кідірісі: сервер әр клиент үшін клиент пен сервер арасындағы бару кідірісі қандай екенін анықтауға тырысады. Әрбір 5 секунд сайын ол қажет болған жағдайда клиентпен жаңа кідіріс туралы келіссөздер жүргізеді (байланыстың бұрынғы әрекетіне байланысты) және сәйкесінше бару кідірісін арттырады немесе азайтады.

Өз бетінше, бұл механизмдер өте қарапайым, бірақ олар бірге пайдаланылған кезде (бұл көбінесе қосылым проблемаларында болады), кодтың логикасын басқару қиынға соғады және көптеген шеткі жағдайлармен. Бұған қоса, бұл механизмдер іске қосылғанда, сервер және кідіріс кезегі арнайыны дұрыс орындауы керек Енгізу әрекеті аты астында MovementInTheNextTick ішінде тоқтату. Осының арқасында байланыста қиындықтар туындаса, кейіпкер өздігінен жүгірмейді (мысалы, пойыздың алдында).

Енді біз сізге нысанды таңдау қалай жұмыс істейтінін түсіндіруіміз керек. Берілетін түрлердің бірі Енгізу әрекеті нысан таңдау күйінің өзгеруі болып табылады. Ол барлығына ойыншының меңзерді қай нысанның үстіне апарып жатқанын айтады. Өзіңіз ойлағандай, бұл клиенттер жіберетін ең көп тараған енгізу әрекеттерінің бірі, сондықтан өткізу қабілеттілігін сақтау үшін біз оны мүмкіндігінше аз орын алатындай етіп оңтайландырдық. Оның жұмыс істеу тәсілі мынада: әрбір нысан таңдалғанда, абсолютті, жоғары дәлдіктегі карта координаттарын сақтаудың орнына, ойын алдыңғы таңдаудан төмен дәлдіктегі салыстырмалы ығысуды сақтайды. Бұл жақсы жұмыс істейді, себебі тінтуір таңдаулары алдыңғы таңдауға өте жақын болады. Бұл екі маңызды талапты тудырады: Енгізу әрекеттері Оларды ешқашан өткізіп жіберуге болмайды және дұрыс ретпен толтырылуы керек. Бұл талаптар орындалады Ойын жағдайы. Бірақ тапсырма бері Кідіріс күйі Ойыншы үшін «жеткілікті жақсы көрінуде» олар кідіріс күйіне қанағаттанбайды. Кешіктіру күйі есепке алмайды көптеген шеткі жағдайлар, сағаттық циклдарды өткізіп жіберумен және айналмалы жіберу кідірістерін өзгертумен байланысты.

Мұның қайда бара жатқанын қазірдің өзінде болжай аласыз. Біз, сайып келгенде, мегабунд мәселесінің себептерін көре бастадық. Мәселенің түпкі мәні мынада: нысанды таңдау логикасына сүйенеді Кешіктіру күйі, және бұл күй әрқашан дұрыс ақпаратты қамтымайды. Осылайша, мегапакет келесідей жасалады:

  1. Ойнатқышта байланыс ақаулары бар.
  2. Сағат циклдерін өткізіп жіберу және екі жаққа жіберудің кешігуін реттеу механизмдері іске қосылады.
  3. Кешігу күйінің кезегі бұл механизмдерді есепке алмайды. Бұл кейбір әрекеттердің мерзімінен бұрын жойылуына немесе қате тәртіпте орындалуына, нәтижесінде қате Кешіктіру күйі.
  4. Ойнатқышта қосылым ақауы бар және серверді қуып жету үшін 400 циклге дейін модельдейді.
  5. Әрбір құсбелгі қойылғанда нысан таңдауын өзгертетін жаңа әрекет жасалады және серверге жіберуге дайындалады.
  6. Клиент серверге 400+ нысан таңдау өзгерістерінің мега-бумасын жібереді (және басқа әрекеттермен: түсіру күйлері, жүру күйлері және т.б. да осы мәселеден зардап шеккен).
  7. Сервер 400 енгізу әрекетін қабылдайды. Енгізу әрекеттерін өткізіп жіберуге рұқсат етілмегендіктен, ол барлық клиенттерге сол әрекеттерді орындауға бұйрық береді және оларды желі арқылы жібереді.

Бір қызығы, өткізу қабілеттілігін үнемдеуге арналған механизм үлкен желі пакеттерін жасаумен аяқталды.

Біз бұл мәселені жаңартудың және артта қалған кезекті қолдаудың барлық шеткі жағдайларын түзету арқылы шештік. Бұл біршама уақытты қажет етсе де, ақырында жылдам бұзуға сенбей, оны дұрыс қабылдау керек болды.

Ақпарат көзі: www.habr.com

пікір қалдыру