Megapack. Ինչպես Factorio-ն լուծեց 200 խաղացողի բազմախաղացող խնդիրը

Megapack. Ինչպես Factorio-ն լուծեց 200 խաղացողի բազմախաղացող խնդիրը
Այս տարվա մայիսին որպես խաղացող մասնակցել եմ MMO միջոցառումներ KatherineOfSky. Նկատեցի, որ երբ խաղացողների թիվը հասնում է որոշակի քանակի, մի քանի րոպեն մեկ նրանցից մի քանիսը «ընկնում են»։ Բարեբախտաբար քո (բայց ոչ ինձ համար) ես այն խաղացողներից մեկն էի, ովքեր անջատվեցին ամեն անգամ, նույնիսկ լավ կապով։ Ես սա ընդունեցի որպես անձնական մարտահրավեր և սկսեցի փնտրել խնդրի պատճառները: Երեք շաբաթ վրիպազերծումից, փորձարկումից և ուղղումից հետո սխալը վերջապես շտկվեց, բայց ճանապարհորդությունն այնքան էլ հեշտ չէր:

Multiplayer խաղերի հետ կապված խնդիրները շատ դժվար է գտնել: Դրանք սովորաբար տեղի են ունենում ցանցի շատ կոնկրետ պարամետրերի և խաղի շատ հատուկ պայմանների ներքո (այս դեպքում՝ ունենալով ավելի քան 200 խաղացող): Եվ նույնիսկ երբ խնդիրը կարող է վերարտադրվել, այն չի կարող ճիշտ կարգաբերվել, քանի որ ընդմիջման կետերի տեղադրումը դադարեցնում է խաղը, շփոթեցնում է ժամանակաչափերը և սովորաբար հանգեցնում է կապի ժամանակի ավարտին: Բայց շնորհիվ համառության և հրաշալի գործիքի, որը կոչվում է անշնորհք Ինձ հաջողվեց պարզել, թե ինչ է կատարվում։

Մի խոսքով, սխալի և հետաձգված վիճակի սիմուլյացիայի թերի իրականացման պատճառով հաճախորդը երբեմն հայտնվում էր մի իրավիճակում, երբ նա ստիպված էր ուղարկել ցանցային փաթեթ, որը բաղկացած է խաղացողի մուտքագրման ընտրության գործողություններից մոտավորապես 400 խաղի սուբյեկտներից մեկ ժամացույցի ցիկլում ( մենք սա անվանում ենք «մեգա-փաթեթ»): Այնուհետև սերվերը պետք է ոչ միայն ճիշտ ստանա այս բոլոր մուտքային գործողությունները, այլև ուղարկի դրանք բոլոր մյուս հաճախորդներին: Եթե ​​ունես 200 հաճախորդ, սա արագ խնդիր է դառնում: Սերվերի հղումը արագորեն խցանվում է, ինչը հանգեցնում է փաթեթների կորստի և նորից պահանջվող փաթեթների կասկադի: Ներածման գործողության հետաձգումն այնուհետև ստիպում է ավելի շատ հաճախորդներ ուղարկել մեգափաթեթներ, ինչը հանգեցնում է ավալանշի ավելի մեծացման: Բախտավոր հաճախորդներին հաջողվում է վերականգնվել, մյուսները ընկնում են:

Megapack. Ինչպես Factorio-ն լուծեց 200 խաղացողի բազմախաղացող խնդիրը
Խնդիրը բավականին սկզբունքային էր, և այն շտկելու համար ինձնից պահանջվեց 2 շաբաթ: Դա բավականին տեխնիկական է, ուստի ես կբացատրեմ հյութալի տեխնիկական մանրամասները ստորև: Բայց նախ դուք պետք է իմանաք, որ հունիսի 0.17.54-ին թողարկված 4 տարբերակից ի վեր, կապի ժամանակավոր խնդիրների դեպքում, մուլտիպլեյերը դարձել է ավելի կայուն, իսկ ուշացումները թաքցնելը դարձել է շատ ավելի քիչ խելագար (ավելի քիչ դանդաղում և հեռահաղորդում): Ես նաև փոխել եմ մարտական ​​հետաձգման թաքնված ձևը և հուսով եմ, որ դա մի փոքր ավելի հարթ կդարձնի:

Multiplayer Mega Pack - Տեխնիկական մանրամասներ

Պարզ ասած, խաղի մեջ մուլտիպլեյերն աշխատում է այսպես. բոլոր հաճախորդները մոդելավորում են խաղի վիճակը՝ ստանալով և ուղարկելով միայն խաղացողի մուտքը (կոչվում է «ներածման գործողություններ», Ներածման գործողություններ) Սերվերի հիմնական խնդիրն է փոխանցումը Ներածման գործողություններ և վերահսկել, որ բոլոր հաճախորդները կատարեն նույն գործողությունները նույն ժամացույցի ցիկլում: Այս մասին ավելին կարող եք կարդալ գրառման մեջ FFF-149.

Քանի որ սերվերը պետք է որոշումներ կայացնի, թե ինչ գործողություններ պետք է կատարի, խաղացողի գործողությունները շարժվում են մոտավորապես այս ճանապարհով. խաղացողի գործողություն -> խաղի հաճախորդ -> ցանց -> սերվեր -> ցանց -> խաղի հաճախորդ: Սա նշանակում է, որ յուրաքանչյուր խաղացողի գործողությունը կատարվում է միայն ցանցով շրջագայություն կատարելուց հետո: Դրա պատճառով խաղը սարսափելի դանդաղ կթվա, ուստի խաղի մեջ մուլտիպլեյերի ներդրումից գրեթե անմիջապես հետո ներդրվեց ուշացումները թաքցնելու մեխանիզմ: Հետաձգումը թաքցնելը նմանակում է խաղացողի մուտքը՝ առանց հաշվի առնելու այլ խաղացողների գործողությունները և սերվերի որոշումները:

Megapack. Ինչպես Factorio-ն լուծեց 200 խաղացողի բազմախաղացող խնդիրը
Factorio-ն խաղային վիճակ ունի Խաղի պետություն քարտի, խաղացողի, սուբյեկտների և մնացած ամեն ինչի ամբողջական վիճակն է: Այն դետերմինիստական ​​կերպով մոդելավորվում է բոլոր հաճախորդների մոտ՝ հիմնվելով սերվերից ստացված գործողությունների վրա: Խաղի վիճակը սուրբ է, և եթե այն երբևէ սկսի տարբերվել սերվերից կամ որևէ այլ հաճախորդից, ապա տեղի է ունենում համաժամացում:

Սակայն Խաղի պետություն ունենք ձգձգումների վիճակ Լատենտային վիճակ. Այն պարունակում է հիմնական վիճակի փոքր ենթաբազմություն: Լատենտային վիճակ սուրբ չէ և պարզապես ներկայացնում է պատկերն այն մասին, թե ինչպիսին կլինի խաղի վիճակը ապագայում՝ հիմնված խաղացողների տվյալների վրա Ներածման գործողություններ.

Այդ նպատակով մենք պահպանում ենք ստեղծվածի պատճենը Ներածման գործողություններ ուշացման հերթում.

Megapack. Ինչպես Factorio-ն լուծեց 200 խաղացողի բազմախաղացող խնդիրը
Այսինքն, հաճախորդի կողմից գործընթացի վերջում նկարը նման է հետևյալին.

  1. Մենք դիմում ենք Ներածման գործողություններ բոլոր խաղացողները դեպի Խաղի պետություն ինչպես են այս մուտքային գործողությունները ստացվել սերվերից:
  2. Մենք ամեն ինչ հեռացնում ենք ուշացման հերթից Ներածման գործողություններ, որոնց վրա, ըստ սերվերի, արդեն դիմել են Խաղի պետություն.
  3. Ջնջել Լատենտային վիճակ և զրոյացնել այն այնպես, որ այն ճիշտ տեսք ունենա, ինչ Խաղի պետություն.
  4. Մենք կիրառում ենք բոլոր գործողությունները հետաձգման հերթից մինչև Լատենտային վիճակ.
  5. տվյալների հիման վրա Խաղի պետություն и Լատենտային վիճակ Մենք խաղը մատուցում ենք խաղացողին:

Այս ամենը կրկնվում է ամեն չափով։

Չափազանց դժվար? Մի հանգստացեք, սա դեռ ամենը չէ: Անվստահելի ինտերնետ կապերը փոխհատուցելու համար մենք ստեղծել ենք երկու մեխանիզմ.

  • Բաց թողնված տիզ. երբ սերվերը դա որոշում է Ներածման գործողություններ կկատարվի խաղի ռիթմով, ապա եթե չի ստացել Ներածման գործողություններ ինչ-որ խաղացող (օրինակ՝ ավելացած ուշացման պատճառով), նա չի սպասի, այլ կտեղեկացնի այս հաճախորդին. «Ես հաշվի չեմ առել ձեր Ներածման գործողություններ, ես կփորձեմ դրանք ավելացնել հաջորդ տողում»։ Դա արվում է այնպես, որ մեկ խաղացողի միացման (կամ համակարգչի) հետ կապված խնդիրների պատճառով քարտեզի թարմացումը մյուսների համար չդանդաղի: Հարկ է նշել, որ Ներածման գործողություններ չեն անտեսվում, այլ ուղղակի մի կողմ են դրվում։
  • Ամբողջական շրջադարձային ուշացում. սերվերը փորձում է գուշակել, թե որքան է հաճախորդի և սերվերի միջև ընկած ժամանակահատվածը յուրաքանչյուր հաճախորդի համար: Յուրաքանչյուր 5 վայրկյանը մեկ, անհրաժեշտության դեպքում, այն հաճախորդի հետ բանակցում է նոր հետաձգման մասին (հիմնվելով այն բանի վրա, թե ինչպես է նախկինում եղել կապը), և համապատասխանաբար մեծացնում կամ նվազեցնում է շրջագայության հետաձգումը:

Ինքնուրույն, այս մեխանիզմները բավականին պարզ են, բայց երբ դրանք օգտագործվում են միասին (ինչը հաճախ տեղի է ունենում կապի խնդիրների դեպքում), կոդի տրամաբանությունը դառնում է դժվար կառավարելի և շատ եզրային դեպքերով։ Բացի այդ, երբ այս մեխանիզմները գործում են, սերվերը և հետաձգման հերթը պետք է պատշաճ կերպով իրականացնեն հատուկը Ներածման գործողություն անվանել StopMovementInTheNextTick. Սրա շնորհիվ, եթե կապի հետ կապված խնդիրներ առաջանան, կերպարն ինքնուրույն չի վազի (օրինակ՝ գնացքի դիմաց)։

Այժմ մենք պետք է ձեզ բացատրենք, թե ինչպես է գործում սուբյեկտի ընտրությունը: Փոխանցվող տեսակներից մեկը Ներածման գործողություն սուբյեկտի ընտրության վիճակի փոփոխություն է: Այն բոլորին ասում է, թե որ կառույցի վրա է խաղացողը սավառնում: Ինչպես կարող եք պատկերացնել, սա հաճախորդների կողմից ուղարկվող մուտքագրման ամենատարածված գործողություններից մեկն է, ուստի թողունակությունը խնայելու համար մենք այն օպտիմալացրել ենք, որպեսզի հնարավորինս քիչ տարածք զբաղեցնի: Այն աշխատում է այնպես, որ երբ ընտրվում է յուրաքանչյուր էություն, քարտեզի բացարձակ, բարձր ճշգրտության կոորդինատները պահելու փոխարեն, խաղը պահպանում է ցածր ճշգրտության հարաբերական օֆսեթ նախորդ ընտրությունից: Սա լավ է աշխատում, քանի որ մկնիկի ընտրանքները հակված են շատ մոտ լինել նախորդ ընտրությանը: Սա բարձրացնում է երկու կարևոր պահանջ. Ներածման գործողություններ Դրանք երբեք չպետք է բաց թողնվեն և պետք է լրացվեն ճիշտ հերթականությամբ: Այս պահանջները բավարարված են Խաղի պետություն. Բայց քանի որ առաջադրանքը Լատենտային վիճակ խաղացողի համար «բավականին լավ տեսք ունենալով», նրանք բավարարված չեն ուշացման վիճակում: Լատենտային վիճակ հաշվի չի առնում շատ եզրային պատյաններ, կապված ժամացույցի ցիկլերի շրջանցման և երկկողմանի փոխանցման ուշացումների փոփոխման հետ:

Դուք արդեն կարող եք կռահել, թե ուր է սա գնում: Մենք վերջապես սկսում ենք տեսնել megapack-ի խնդրի պատճառները: Խնդիրի արմատն այն է, որ սուբյեկտների ընտրության տրամաբանությունը հիմնված է Լատենտային վիճակ, և այս վիճակը միշտ չէ, որ պարունակում է ճիշտ տեղեկատվություն։ Հետևաբար, մեգափաթեթը ստեղծվում է այսպես.

  1. Խաղացողը կապի հետ կապված խնդիրներ ունի:
  2. Գործի են դրվում ժամացույցի ցիկլերը բաց թողնելու և երկկողմանի փոխանցման հետաձգումը կարգավորելու մեխանիզմները:
  3. Հետաձգման պետական ​​հերթը հաշվի չի առնում այս մեխանիզմները։ Սա հանգեցնում է նրան, որ որոշ գործողություններ վաղաժամ հեռացվեն կամ կատարվեն սխալ հերթականությամբ, ինչը հանգեցնում է սխալ Լատենտային վիճակ.
  4. Նվագարկիչը կապի խնդիր ունի և սերվերին հասնելու համար մոդելավորում է մինչև 400 ցիկլ:
  5. Յուրաքանչյուր նշանի վրա ստեղծվում է նոր գործողություն, որը փոխում է օբյեկտի ընտրությունը և պատրաստվում է սերվեր ուղարկելու համար:
  6. Հաճախորդը սերվեր է ուղարկում 400+ միավորի ընտրության փոփոխություններից բաղկացած մեգախմբաքանակ (և այլ գործողություններով. կրակոցների վիճակները, քայլելու վիճակները և այլն նույնպես տուժել են այս խնդրից):
  7. Սերվերը ստանում է 400 մուտքային գործողություն: Քանի որ չի թույլատրվում բաց թողնել մուտքագրման որևէ գործողություն, այն պատվիրում է բոլոր հաճախորդներին կատարել այդ գործողությունները և դրանք ուղարկել ցանցով:

Զավեշտն այն է, որ թողունակությունը խնայելու համար նախատեսված մեխանիզմը հանգեցրեց ցանցի հսկայական փաթեթների ստեղծմանը:

Մենք լուծեցինք այս խնդիրը՝ շտկելով թարմացման և հետաձգված հերթի աջակցության բոլոր եզրային դեպքերը: Թեև դա բավականին քիչ ժամանակ խլեց, ի վերջո արժե այն ճիշտ ձևակերպել, քան հենվել արագ հաքերների վրա:

Source: www.habr.com

Добавить комментарий