Ki jan nou amelyore mekanik kalkil balistik pou yon tirè mobil ak yon algorithm konpansasyon latansi rezo

Ki jan nou amelyore mekanik kalkil balistik pou yon tirè mobil ak yon algorithm konpansasyon latansi rezo

Alo, mwen se Nikita Brizhak, yon devlopè sèvè nan Pixonic. Jodi a mwen ta renmen pale sou konpansasyon pou lag nan multijoueurs mobil.

Anpil atik yo te ekri sou konpansasyon lag sèvè, ki gen ladan nan Ris. Sa a se pa etone, depi teknoloji sa a te aktivman itilize nan kreyasyon FPS multijoueurs depi fen ane 90 yo. Pou egzanp, ou ka sonje mod la QuakeWorld, ki te youn nan premye moun ki sèvi ak li.

Nou itilize li tou nan tirè multijoueurs mobil nou an Dino Squad.

Nan atik sa a, objektif mwen se pa repete sa ki te deja ekri mil fwa, men di ki jan nou aplike konpansasyon lag nan jwèt nou an, pran an kont pil teknoloji nou an ak karakteristik debaz jeu.

Yon kèk mo sou cortical nou an ak teknoloji.

Dino Squad se yon rezo mobil tirè PvP. Jwè yo kontwole dinozò yo ekipe ak yon varyete de zam epi goumen youn ak lòt nan ekip 6v6.

Tou de kliyan an ak sèvè a baze sou Inite. Achitekti a se byen klasik pou tirè: sèvè a se otoritè, ak prediksyon kliyan ap travay sou kliyan yo. Se simulation jwèt la ekri lè l sèvi avèk ECS nan kay la epi yo itilize sou tou de sèvè a ak kliyan.

Si sa a se premye fwa ou te tande sou konpansasyon lag, isit la se yon levasyon tou kout nan pwoblèm nan.

Nan jwèt FPS multijoueurs, match la anjeneral simulation sou yon sèvè aleka. Jwè yo voye opinyon yo (enfòmasyon sou kle yo bourade) nan sèvè a, epi an repons sèvè a voye yo yon eta jwèt mete ajou pran an kont done yo resevwa. Avèk konplo entèraksyon sa a, delè ki genyen ant peze kle a pi devan ak moman karaktè jwè a deplase sou ekran an ap toujou pi gran pase ping la.

Pandan ke sou rezo lokal yo reta sa a (populè yo rele input lag) ka inapèsi, lè w ap jwe sou entènèt la li kreye yon santiman nan "glise sou glas" lè w ap kontwole yon karaktè. Pwoblèm sa a se doubl enpòtan pou rezo mobil, kote ka a lè ping yon jwè a se 200 ms toujou konsidere kòm yon koneksyon ekselan. Souvan ping la ka 350, 500, oswa 1000 ms. Lè sa a, li vin prèske enposib yo jwe yon tirè vit ak lag opinyon.

Solisyon pwoblèm sa a se prediksyon simulation bò kliyan. Isit la kliyan an tèt li aplike opinyon nan karaktè jwè a, san yo pa tann pou yon repons nan men sèvè a. Epi lè yo resevwa repons lan, li tou senpleman konpare rezilta yo epi mete ajou pozisyon opozan yo. Delè ki genyen ant peze yon kle ak montre rezilta a sou ekran an nan ka sa a se minim.

Li enpòtan pou w konprann nuans la isit la: kliyan an toujou trase tèt li dapre dènye opinyon li yo, ak lènmi - ak reta rezo a, dapre eta anvan an soti nan done ki soti nan sèvè a. Sa vle di, lè yo tire sou yon lènmi, jwè a wè l 'nan tan lontan an parapò ak tèt li. Plis sou prediksyon kliyan nou te ekri pi bonè.

Kidonk, prediksyon kliyan rezoud yon pwoblèm, men kreye yon lòt: si yon jwè tire nan pwen kote lènmi an te nan tan lontan an, sou sèvè a lè tire nan menm pwen an, lènmi an ka pa nan plas sa a ankò. Sèvè lag konpansasyon eseye rezoud pwoblèm sa a. Lè yo tire yon zam, sèvè a retabli eta jwèt la ke jwè a te wè lokalman nan moman piki a, epi tcheke si li vrèman te kapab frape lènmi an. Si repons lan se "wi," frape a konte, menm si lènmi an pa sou sèvè a ankò nan pwen sa a.

Ame ak konesans sa a, nou te kòmanse aplike konpansasyon lag sèvè nan Dino Squad. Premye a tout, nou te dwe konprann ki jan yo retabli sou sèvè a sa kliyan an te wè? Ak ki sa egzakteman bezwen retabli? Nan jwèt nou an, frape nan zam ak kapasite yo kalkile atravè raycasts ak superpositions - se sa ki, atravè entèraksyon ak kolizyon fizik lènmi an. An konsekans, nou te bezwen repwodui pozisyon kolizyon sa yo, ki jwè a "wè" lokalman, sou sèvè a. Nan moman sa a nou t ap itilize vèsyon Unity 2018.x. API fizik la gen estatik, mond fizik la egziste nan yon kopi sèl. Pa gen okenn fason pou konsève pou eta li yo ak Lè sa a, retabli li nan bwat la. Se konsa, kisa pou fè?

Solisyon an te sou sifas la; tout eleman li yo te deja itilize pa nou pou rezoud lòt pwoblèm:

  1. Pou chak kliyan, nou bezwen konnen ki lè li te wè opozan lè li te peze kle yo. Nou te deja ekri enfòmasyon sa yo nan pakè D' a epi itilize li pou ajiste prediksyon kliyan an.
  2. Nou bezwen pou kapab sere istwa jwèt eta yo. Li se nan li ke nou pral kenbe pozisyon yo nan opozan nou yo (ak Se poutèt sa kolizyon yo). Nou te deja gen yon istwa eta sou sèvè a, nou te itilize li pou konstwi delta. Konnen bon moman, nou te kapab fasil jwenn bon eta nan listwa.
  3. Kounye a ke nou gen eta jwèt la nan istwa nan men, nou bezwen kapab senkronize done jwè ak eta a nan mond fizik la. Kolizyon ki deja egziste - deplase, moun ki manke - kreye, sa ki pa nesesè - detwi. Lojik sa a te deja ekri tou e li te genyen plizyè sistèm ECS. Nou itilize li pou kenbe plizyè chanm jwèt nan yon sèl pwosesis Unity. Epi depi mond fizik la se youn pou chak pwosesis, li te dwe reyitilize ant chanm yo. Anvan chak tik nan simulation la, nou "reset" eta a nan mond fizik la ak reinisyalize li ak done pou sal aktyèl la, ap eseye reitilize objè jwèt Unity otank posib atravè yon sistèm pisin entelijan. Tout sa ki te rete se te envoke menm lojik pou eta jwèt la nan tan lontan an.

Lè nou mete tout eleman sa yo ansanm, nou te resevwa yon "machin tan" ki ta ka woule tounen eta a nan mond fizik la nan moman an dwa. Kòd la te vin senp:

public class TimeMachine : ITimeMachine
{
     //История игровых состояний
     private readonly IGameStateHistory _history;

     //Текущее игровое состояние на сервере
     private readonly ExecutableSystem[] _systems;

     //Набор систем, расставляющих коллайдеры в физическом мире 
     //по данным из игрового состояния
     private readonly GameState _presentState;

     public TimeMachine(IGameStateHistory history, GameState presentState, ExecutableSystem[] timeInitSystems)
     {
         _history = history; 
         _presentState = presentState;
         _systems = timeInitSystems;  
     }

     public GameState TravelToTime(int tick)
     {
         var pastState = tick == _presentState.Time ? _presentState : _history.Get(tick);
         foreach (var system in _systems)
         {
             system.Execute(pastState);
         }
         return pastState;
     }
}

Tout sa ki te rete se konnen ki jan yo sèvi ak machin sa a fasil konpanse pou vaksen ak kapasite.

Nan ka ki pi senp la, lè mekanik yo baze sou yon sèl hitscan, tout bagay sanble klè: anvan jwè a tire, li bezwen woule mond fizik la nan eta a vle, fè yon raycast, konte frape oswa miss la, ak retounen mond lan nan eta inisyal la.

Men, gen trè kèk mekanik sa yo nan Dino Squad! Pifò nan zam yo nan jwèt la kreye pwojektil - bal ki dire lontan ki vole pou plizyè tik simulation (nan kèk ka, plizyè douzèn tik). Kisa yo dwe fè ak yo, ki lè yo ta dwe vole?

В ansyen atik sou pil rezo Half-Life a, mesye yo soti nan Valve te poze menm kesyon an, ak repons yo te sa a: konpansasyon pwojektil lag se pwoblèm, epi li se pi bon pou fè pou evite li.

Nou pa t 'gen opsyon sa a: zam ki baze sou pwojektil yo te yon karakteristik kle nan konsepsyon jwèt la. Se konsa, nou te gen pou vini ak yon bagay. Apre kèk brainstorming, nou formul de opsyon ki te sanble travay:

1. Nou mare pwojektil la ak tan jwè ki te kreye li a. Chak tik nan simulation sèvè a, pou chak bal nan chak jwè, nou woule tounen mond fizik la nan eta kliyan an epi fè kalkil ki nesesè yo. Apwòch sa a te fè li posib pou gen yon chaj distribiye sou sèvè a ak tan vòl previzib nan pwojektil. Previzibilite te espesyalman enpòtan pou nou, depi nou gen tout pwojektil, ki gen ladan pwojektil lènmi, prevwa sou kliyan an.

Ki jan nou amelyore mekanik kalkil balistik pou yon tirè mobil ak yon algorithm konpansasyon latansi rezo
Nan foto a, jwè a nan tik 30 tire yon misil nan patisipe: li wè nan ki direksyon lènmi an ap kouri epi li konnen vitès la apwoksimatif nan misil la. Lokalman li wè ke li frape sib la nan tik la 33yèm. Mèsi a konpansasyon lag, li pral parèt tou sou sèvè a

2. Nou fè tout bagay menm jan ak premye opsyon a, men, apre nou fin konte yon sèl tik nan simulation bal la, nou pa sispann, men nou kontinye simulation vòl li nan menm tik sèvè a, chak fwa pote tan li pi pre sèvè a. youn pa youn tik ak mete ajou pozisyon kolizyon yo. Nou fè sa jiskaske youn nan de bagay rive:

  • Bal la ekspire. Sa vle di ke kalkil yo fini, nou ka konte yon miss oswa yon frape. Lè sa a se nan tik la menm nan ki te tire a te tire! Pou nou sa a te tou de yon plis ak yon mwens. Yon plis - paske pou jwè a tire sa a siyifikativman redwi reta ki genyen ant frape a ak diminisyon nan sante lènmi an. Inconvénient la se ke yo te obsève menm efè a lè opozan te tire sou jwè a: lènmi an, ta sanble, sèlman tire yon fize dousman, ak domaj la te deja konte.
  • Bal la rive nan tan sèvè. Nan ka sa a, simulation li yo ap kontinye nan pwochen tik sèvè a san okenn konpansasyon lag. Pou pwojektil dousman, sa a ta ka teyorikman redwi kantite fizik rollbacks konpare ak premye opsyon an. An menm tan an, chaj la inegal sou simulation la te ogmante: sèvè a te swa san fè anyen konsa, oswa nan yon sèl tik sèvè li te kalkile yon douzèn tik simulation pou plizyè bal.

Ki jan nou amelyore mekanik kalkil balistik pou yon tirè mobil ak yon algorithm konpansasyon latansi rezo
Senaryo a menm jan ak foto anvan an, men kalkile dapre dezyèm konplo a. Misil la "atre" ak tan sèvè a nan menm tik ki piki a te fèt, epi yo ka konte frape a osi bonè ke pwochen tik la. Nan 31yèm tik la, nan ka sa a, konpansasyon lag pa aplike ankò

Nan aplikasyon nou an, de apwòch sa yo diferan nan jis yon koup nan liy nan kòd, kidonk nou te kreye tou de, ak pou yon tan long yo te egziste nan paralèl. Tou depan de mekanik zam la ak vitès bal la, nou te chwazi youn oswa yon lòt opsyon pou chak dinozò. Pwen an vire isit la se aparans nan jwèt la nan mekanik tankou "si ou frape lènmi an anpil fwa nan tèl ak tèl tan, jwenn tèl ak tèl bonis." Nenpòt mekanisyen kote lè jwè a frape lènmi an te jwe yon wòl enpòtan te refize travay ak dezyèm apwòch la. Se konsa, nou te fini ale ak premye opsyon an, epi li kounye a aplike a tout zam ak tout kapasite aktif nan jwèt la.

Separeman, li vo ogmante pwoblèm nan nan pèfòmans. Si ou te panse ke tout bagay sa yo ta ralanti bagay sa yo, mwen reponn: li se. Inite se byen ralanti nan deplase kolizyon ak vire yo ak sou yo. Nan Dino Squad, nan "pi move" ka a, ka gen plizyè santèn pwojektil ki egziste ansanm nan konba. Deplase kolizyon pou konte chak pwojektil endividyèlman se yon liks ki pa abòdab. Se poutèt sa, li te absoliman nesesè pou nou minimize kantite "rollbacks" fizik. Pou fè sa, nou te kreye yon eleman separe nan ECS kote nou anrejistre tan jwè a. Nou ajoute li nan tout antite ki mande pou konpansasyon lag (pwojektil, kapasite, elatriye). Anvan nou kòmanse trete antite sa yo, nou gwoupe yo nan moman sa a epi trete yo ansanm, woule mond fizik la yon fwa pou chak gwoup.

Nan etap sa a, nou gen yon sistèm travay jeneralman. Kòd li nan yon fòm yon ti jan senplifye:

public sealed class LagCompensationSystemGroup : ExecutableSystem
{
     //Машина времени
     private readonly ITimeMachine _timeMachine;

     //Набор систем лагкомпенсации
     private readonly LagCompensationSystem[] _systems;
     
     //Наша реализация кластеризатора
     private readonly TimeTravelMap _travelMap = new TimeTravelMap();

    public LagCompensationSystemGroup(ITimeMachine timeMachine, 
        LagCompensationSystem[] lagCompensationSystems)
     {
         _timeMachine = timeMachine;
         _systems = lagCompensationSystems;
     }

     public override void Execute(GameState gs)
     {
         //На вход кластеризатор принимает текущее игровое состояние,
         //а на выход выдает набор «корзин». В каждой корзине лежат энтити,
         //которым для лагкомпенсации нужно одно и то же время из истории.
         var buckets = _travelMap.RefillBuckets(gs);

         for (int bucketIndex = 0; bucketIndex < buckets.Count; bucketIndex++)
         {
             ProcessBucket(gs, buckets[bucketIndex]);
         }

         //В конце лагкомпенсации мы восстанавливаем физический мир 
         //в исходное состояние
         _timeMachine.TravelToTime(gs.Time);
     }

     private void ProcessBucket(GameState presentState, TimeTravelMap.Bucket bucket)
     {
         //Откатываем время один раз для каждой корзины
         var pastState = _timeMachine.TravelToTime(bucket.Time);

         foreach (var system in _systems)
         {
               system.PastState = pastState;
               system.PresentState = presentState;

               foreach (var entity in bucket)
               {
                   system.Execute(entity);
               }
          }
     }
}

Tout sa ki te rete se konfigirasyon detay yo:

1. Konprann konbyen yo limite distans maksimòm mouvman an nan tan.

Li te enpòtan pou nou fè jwèt la aksesib ke posib nan kondisyon pòv rezo mobil, kidonk nou limite istwa a ak yon maj nan 30 tik (ak yon pousantaj tik nan 20 Hz). Sa a pèmèt jwè yo frape opozan menm nan ping trè wo.

2. Detèmine ki objè yo ka deplase nan tan epi ki pa kapab.

Nou, nan kou, ap deplase opozan nou yo. Men, plak pwotèj enèji enstale, pou egzanp, yo pa. Nou te deside ke li te pi bon bay priyorite nan kapasite nan defans, menm jan se souvan fè nan tirè sou entènèt. Si jwè a te deja mete yon plak pwotèj nan prezan an, bal lag-konpanse soti nan tan lontan an pa ta dwe vole nan li.

3. Deside si li nesesè pou konpanse kapasite dinozò yo: mòde, frape ke, elatriye Nou deside sa ki nesesè epi trete yo dapre menm règ ak bal.

4. Detèmine kisa pou w fè ak kolizyon jwè a pou konpansasyon lag ap fèt. Nan yon bon fason, pozisyon yo pa ta dwe chanje nan tan lontan an: jwè a ta dwe wè tèt li nan menm tan an nan ki li se kounye a sou sèvè a. Sepandan, nou menm tou nou woule tounen kolizyon yo nan jwè a tire, e gen plizyè rezon pou sa.

Premyèman, li amelyore gwoupman: nou ka itilize menm eta fizik la pou tout jwè ki gen ping fèmen.

Dezyèmman, nan tout raycasts ak sipèpoze nou toujou eskli kolizyon yo nan jwè a ki posede kapasite yo oswa pwojektil. Nan Dino Squad, jwè yo kontwole dinozò, ki gen jeyometri olye ki pa estanda pa estanda tirè yo. Menm si jwè a tire nan yon ang etranj ak trajectoire bal la pase nan kolizyon dinozò jwè a, bal la pral inyore li.

Twazyèmman, nou kalkile pozisyon zam dinozò a oswa pwen aplikasyon kapasite a lè l sèvi avèk done ki soti nan ECS la menm anvan kòmansman konpansasyon lag.

Kòm yon rezilta, pozisyon reyèl la nan kolizyon yo nan lag-konpanse jwè a pa enpòtan pou nou, kidonk nou te pran yon chemen ki pi pwodiktif ak an menm tan pi senp.

Rezo latansi pa ka senpleman retire, li ka sèlman maske. Tankou nenpòt lòt metòd degize, konpansasyon lag sèvè gen konpwomi li yo. Li amelyore eksperyans nan jwèt nan jwè a ki ap tire nan depans lan nan jwè a yo te tire sou. Pou Dino Squad, sepandan, chwa a isit la te evidan.

Natirèlman, tout bagay sa a te dwe peye pou konpleksite a ogmante nan kòd la sèvè kòm yon antye - tou de pou pwogramè ak konsèpteur jwèt. Si pi bonè simulation la te yon senp apèl sekans nan sistèm, Lè sa a, ak konpansasyon lag, bouk enbrike ak branch parèt nan li. Nou menm tou nou te pase anpil efò pou fè li pratik pou travay avèk yo.

Nan vèsyon 2019 la (e petèt yon ti kras pi bonè), Unity te ajoute sipò konplè pou sèn fizik endepandan. Nou aplike yo sou sèvè a prèske imedyatman apre aktyalizasyon a, paske nou te vle byen vit debarase m de mond fizik ki komen nan tout chanm yo.

Nou te bay chak chanm jwèt pwòp sèn fizik li e konsa elimine nesesite pou "klè" sèn nan done yo nan sal vwazen an anvan yo kalkile simulation la. Premyèman, li te bay yon ogmantasyon siyifikatif nan pwodiktivite. Dezyèmman, li te fè li posib yo debarase m de yon klas antye nan pinèz ki te parèt si pwogramè a te fè yon erè nan kòd netwayaj sèn nan lè ajoute nouvo eleman jwèt. Erè sa yo te difisil pou debogaj, epi yo souvan lakòz eta objè fizik nan sèn yon chanm nan "ap koule tankou dlo" nan yon lòt chanm.

Anplis de sa, nou te fè kèk rechèch sou si sèn fizik yo ta ka itilize nan magazen istwa a nan mond fizik la. Sa vle di, kondisyonèl, asiyen pa yon sèl sèn nan chak chanm, men 30 sèn, epi fè yon tanpon siklik soti nan yo, nan ki sere istwa a. An jeneral, opsyon a te vin ap travay, men nou pa t aplike li: li pa t montre okenn ogmantasyon fou nan pwodiktivite, men li te mande chanjman pito riske. Li te difisil pou predi ki jan sèvè a ta konpòte lè w ap travay pou yon tan long ak anpil sèn. Se poutèt sa, nou te swiv règ la: "Si li pa kase, pa ranje li'.

Sous: www.habr.com

Add nouvo kòmantè