
Hi, jien Nikita Brizhak, żviluppatur tas-server minn Pixonic. Illum nixtieq nitkellem dwar il-kumpens għad-dewmien fil-multiplayer mobbli.
Inkitbu ħafna artikli dwar il-kumpens għad-dewmien tas-server, inkluż bir-Russu. Dan mhux sorprendenti, peress li din it-teknoloġija ilha tintuża b'mod attiv fil-ħolqien ta 'FPS multiplayer mill-aħħar tas-snin 90. Per eżempju, tista 'tiftakar il-mod QuakeWorld, li kien wieħed mill-ewwel li użah.
Aħna nużawha wkoll fl-isparatur mobbli multiplayer tagħna Dino Squad.
F'dan l-artikolu, l-għan tiegħi mhuwiex li nirrepeti dak li diġà nkiteb elf darba, iżda li ngħid kif implimentajna l-kumpens tad-dewmien fil-logħba tagħna, b'kont meħud tal-munzell tat-teknoloġija tagħna u l-karatteristiċi ewlenin tal-logħob.
Ftit kelmiet dwar il-kortiċi u t-teknoloġija tagħna.
Dino Squad huwa shooter PvP mobbli tan-netwerk. Il-plejers jikkontrollaw id-dinosawri mgħammra b'varjetà ta 'armi u jiġġieldu lil xulxin f'timijiet 6v6.
Kemm il-klijent kif ukoll is-server huma bbażati fuq Unity. L-arkitettura hija pjuttost klassika għat-tiraturi: is-server huwa awtoritarju, u t-tbassir tal-klijenti jaħdem fuq il-klijenti. Is-simulazzjoni tal-logħba hija miktuba bl-użu ta 'ECS intern u tintuża kemm fuq is-server kif ukoll fuq il-klijent.
Jekk din hija l-ewwel darba li smajt dwar il-kumpens għad-dewmien, hawn eskursjoni qasira fil-kwistjoni.
Fil-logħob FPS multiplayer, il-logħba hija ġeneralment simulata fuq server remot. Il-plejers jibagħtu l-input tagħhom (informazzjoni dwar iċ-ċwievet ippressati) lis-server, u bi tweġiba s-server jibgħatilhom stat tal-logħba aġġornat b'kont meħud tad-dejta riċevuta. B'din l-iskema ta 'interazzjoni, id-dewmien bejn l-ippressar taċ-ċavetta 'l quddiem u l-mument li l-karattru tal-plejer jimxi fuq l-iskrin dejjem ikun akbar mill-ping.
Filwaqt li fuq netwerks lokali dan id-dewmien (popolarment imsejjaħ input lag) jista 'ma jkunx innotabbli, meta tilgħab permezz tal-Internet toħloq sensazzjoni ta' "jiżżerżaq fuq is-silġ" meta tikkontrolla karattru. Din il-problema hija doppjament rilevanti għan-netwerks mobbli, fejn il-każ meta l-ping ta 'plejer huwa ta' 200 ms għadu meqjus bħala konnessjoni eċċellenti. Ħafna drabi l-ping jista 'jkun 350, 500, jew 1000 ms. Imbagħad isir kważi impossibbli li tilgħab shooter mgħaġġel b'lag input.
Is-soluzzjoni għal din il-problema hija tbassir ta' simulazzjoni min-naħa tal-klijent. Hawnhekk il-klijent innifsu japplika l-input għall-karattru tal-plejer, mingħajr ma jistenna tweġiba mis-server. U meta tasal ir-risposta, sempliċement tqabbel ir-riżultati u taġġorna l-pożizzjonijiet tal-avversarji. Id-dewmien bejn l-ippressar ta 'ċavetta u l-wiri tar-riżultat fuq l-iskrin f'dan il-każ huwa minimu.
Huwa importanti li tifhem l-isfumatura hawn: il-klijent dejjem jiġbed lilu nnifsu skont l-aħħar input tiegħu, u l-għedewwa - b'dewmien tan-netwerk, skont l-istat preċedenti mid-dejta mis-server. Jiġifieri, meta jispara fuq ghadu, il-plejer jarah fil-passat relattiv għalih innifsu. Aktar dwar it-tbassir tal-klijenti .
Għalhekk, il-previżjoni tal-klijent issolvi problema waħda, iżda toħloq oħra: jekk plejer jispara fil-punt fejn l-ghadu kien fil-passat, fuq is-server meta jispara fl-istess punt, l-ghadu jista 'ma jkunx aktar f'dak il-post. Il-kumpens għad-dewmien tas-server jipprova jsolvi din il-problema. Meta arma tiġi sparata, is-server jerġa 'jġib l-istat tal-logħba li l-plejer ra lokalment fil-ħin tal-isparatura, u jiċċekkja jekk verament setax laqat lill-ghadu. Jekk it-tweġiba hija "iva," il-hit tingħadd, anke jekk l-ghadu m'għadux fuq is-server f'dak il-punt.
Armati b'dan l-għarfien, bdejna nimplimentaw il-kumpens tad-dewmien tas-server f'Dino Squad. L-ewwelnett, kellna nifhmu kif nirrestawraw fuq is-server dak li ra l-klijent? U x'hemm bżonn eżattament li jiġi rrestawrat? Fil-logħba tagħna, hits mill-armi u l-abbiltajiet huma kkalkulati permezz ta 'raycasts u overlays - jiġifieri, permezz ta' interazzjonijiet mal-colliders fiżiċi tal-għadu. Għaldaqstant, kellna bżonn nirriproduċu l-pożizzjoni ta 'dawn il-colliders, li l-plejer "ra" lokalment, fuq is-server. Dak iż-żmien konna nużaw il-verżjoni tal-Unità 2018.x. L-API tal-fiżika hemm statika, id-dinja fiżika teżisti f'kopja waħda. M'hemm l-ebda mod biex issalva l-istat tagħha u mbagħad tirrestawraha mill-kaxxa. Allura x'għandek tagħmel?
Is-soluzzjoni kienet fil-wiċċ l-elementi kollha tagħha kienu diġà ntużaw minna biex insolvu problemi oħra:
- Għal kull klijent, irridu nkunu nafu f'liema ħin ra l-avversarji meta għafas it-tasti. Aħna diġà ktibna din l-informazzjoni fil-pakkett tad-dħul u użajna biex naġġustaw il-previżjoni tal-klijent.
- Irridu nkunu nistgħu naħżnu l-istorja tal-istati tal-logħob. Huwa fih li se nżommu l-pożizzjonijiet tal-avversarji tagħna (u għalhekk il-colliders tagħhom). Diġà kellna storja tal-istat fuq is-server, użajna biex nibnu . Billi nkunu nafu l-ħin it-tajjeb, nistgħu faċilment insibu l-istat it-tajjeb fl-istorja.
- Issa li għandna l-istat tal-logħba mill-istorja fl-idejn, jeħtieġ li nkunu nistgħu nissinkronizzaw id-dejta tal-plejers mal-istat tad-dinja fiżika. Kolliders eżistenti - jimxu, dawk neqsin - joħolqu, dawk bla bżonn - jeqirdu. Din il-loġika kienet diġà miktuba wkoll u kienet tikkonsisti f'diversi sistemi ECS. Użajna biex inżommu diversi kmamar tal-logħob fi proċess wieħed Unity. U peress li d-dinja fiżika hija waħda għal kull proċess, kellha terġa 'tintuża bejn il-kmamar. Qabel kull qurdien tas-simulazzjoni, aħna "reset" l-istat tad-dinja fiżika u reinitialized dan b'dejta għall-kamra attwali, tipprova tuża mill-ġdid oġġetti tal-logħob Unity kemm jista 'jkun permezz ta' sistema ta 'pooling għaqlija. Kulma baqa’ kien li tinvoka l-istess loġika għall-istat tal-logħba mill-passat.
Billi għaqqad dawn l-elementi kollha flimkien, aħna ltqajna "magna taż-żmien" li tista 'treġġa' lura l-istat tad-dinja fiżika għall-mument it-tajjeb. Il-kodiċi rriżulta li kien sempliċi:
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;
}
}Kulma baqa’ kien li wieħed jifhem kif tuża din il-magna biex tikkumpensa faċilment għall-isparaturi u l-abbiltajiet.
Fl-aktar każ sempliċi, meta l-mekkaniżmi huma bbażati fuq hitscan wieħed, kollox jidher ċar: qabel ma l-plejer jispara, jeħtieġ li jreġġa 'lura d-dinja fiżika għall-istat mixtieq, jagħmel raycast, jgħodd il-hit jew miss, u lura d-dinja għall-istat inizjali.
Imma ftit li xejn hemm mekkaniċi bħal dawn f'Dino Squad! Ħafna mill-armi fil-logħba joħolqu projettili - balal b'ħajja twila li jtiru għal diversi qurdien ta 'simulazzjoni (f'xi każijiet, għexieren ta' qurdien). X'għandek tagħmel magħhom, f'liema ħin għandhom itiru?
В dwar il-munzell tan-netwerk Half-Life, il-guys minn Valve staqsew l-istess mistoqsija, u t-tweġiba tagħhom kienet din: il-kumpens tad-dewmien tal-projettili huwa problematiku, u huwa aħjar li jiġi evitat.
Ma kellniex din l-għażla: l-armi bbażati fuq il-projettili kienu karatteristika ewlenija tad-disinn tal-logħba. Allura kellna noħorġu b’xi ħaġa. Wara ftit brainstorming, ifformulajna żewġ għażliet li dehru li jaħdmu:
1. Aħna norbtu l-projettili mal-ħin tal-plejer li ħoloqha. Kull qurdien tas-simulazzjoni tas-server, għal kull bulit ta 'kull plejer, aħna nerġgħu lura d-dinja fiżika għall-istat tal-klijent u nwettqu l-kalkoli meħtieġa. Dan l-approċċ għamilha possibbli li jkun hemm tagħbija distribwita fuq is-server u ħin tat-titjir prevedibbli tal-projettili. Il-prevedibbiltà kienet speċjalment importanti għalina, peress li għandna l-projettili kollha, inklużi l-projettili tal-għadu, imbassra fuq il-klijent.

Fl-istampa, l-attur fil-qurdien 30 jispara missila b'antiċipazzjoni: jara f'liema direzzjoni qed jimxi l-ghadu u jaf il-veloċità approssimattiva tal-missila. Lokalment jara li laqat il-mira fit-33 qurka. Grazzi għal kumpens tad-dewmien, se jidher ukoll fuq is-server
2. Nagħmlu kollox l-istess bħal fl-ewwel għażla, iżda, wara li ngħaddu qurdien wieħed tas-simulazzjoni tal-balal, ma nieqfux, iżda nkomplu nissimulaw it-titjira tagħha fl-istess qurdien tas-server, kull darba li nġibu l-ħin tiegħu eqreb lejn is-server immarka waħda waħda u taġġorna l-pożizzjonijiet tal-kollider. Aħna nagħmlu dan sakemm isseħħ waħda minn żewġ affarijiet:
- Il-bullet skada. Dan ifisser li l-kalkoli spiċċaw, nistgħu ngħoddu miss jew hit. U dan fl-istess qurdien li fih kien sparat it-tir! Għalina dan kien kemm plus u minus. A plus - għaliex għall-plejer tal-isparar dan naqqas b'mod sinifikanti d-dewmien bejn il-hit u t-tnaqqis fis-saħħa tal-għadu. L-iżvantaġġ huwa li l-istess effett kien osservat meta l-avversarji sparaw lejn il-plejer: l-ghadu, jidher, spara biss rokit bil-mod, u l-ħsara kienet diġà magħduda.
- Il-bullet laħqet il-ħin tas-server. F'dan il-każ, is-simulazzjoni tagħha se tkompli fil-qurdien tas-server li jmiss mingħajr ebda kumpens ta 'dewmien. Għal projettili bil-mod, dan jista 'teoretikament inaqqas in-numru ta' rollbacks tal-fiżika meta mqabbel mal-ewwel għażla. Fl-istess ħin, it-tagħbija irregolari fuq is-simulazzjoni żdiedet: is-server kien jew idle, jew f'server wieħed tick kien qed jikkalkula tużżana qurdien ta 'simulazzjoni għal diversi balal.

L-istess xenarju bħal fl-istampa preċedenti, iżda kkalkulat skont it-tieni skema. Il-missila "qabdet" mal-ħin tas-server fl-istess immarka li seħħet l-isparatura, u l-hit jista 'jingħadd sa mill-qurdien li jmiss. Fil-31 qurdien, f'dan il-każ, il-kumpens għad-dewmien m'għadux applikat
Fl-implimentazzjoni tagħna, dawn iż-żewġ approċċi kienu differenti fi ftit linji ta 'kodiċi biss, għalhekk ħloqna t-tnejn, u għal żmien twil kienu jeżistu b'mod parallel. Skont il-mekkanika tal-arma u l-veloċità tal-bullet, għażilna għażla waħda jew oħra għal kull dinosawru. Il-punt ta 'bidla hawnhekk kien id-dehra fil-logħba tal-mekkanika bħal "jekk tolqot lill-għadu kemm-il darba f'tali żmien, ikseb tali u tali bonus." Kwalunkwe mekkanik fejn il-ħin li fih il-plejer laqat lill-għadu kellu rwol importanti rrifjuta li jaħdem mat-tieni approċċ. Allura spiċċajna għaddejjin bl-ewwel għażla, u issa tapplika għall-armi kollha u l-abbiltajiet attivi kollha fil-logħba.
Separatament, ta 'min tqajjem il-kwistjoni tal-prestazzjoni. Kieku ħsibt li dan kollu jrattab l-affarijiet, inwieġeb: hu. L-unità hija pjuttost bil-mod biex tiċċaqlaq colliders u tixgħel u titfi. F'Dino Squad, fl-"agħar" każ, jista' jkun hemm diversi mijiet ta' projettili eżistenti simultanjament fil-ġlieda. Iċ-ċaqliq tal-colliders biex jgħodd kull projettili individwalment huwa lussu mhux aċċessibbli. Għalhekk, kien assolutament meħtieġ għalina li nimminimizzaw in-numru ta '"rollbacks" tal-fiżika. Biex tagħmel dan, ħloqna komponent separat fl-ECS li fih nirreġistraw il-ħin tal-plejer. Żidna mal-entitajiet kollha li jeħtieġu kumpens għad-dewmien (proġettili, kapaċitajiet, eċċ.). Qabel ma nibdew nipproċessaw entitajiet bħal dawn, sa dan iż-żmien aħna nipproċessawhom u nipproċessawhom flimkien, billi nġibu lura d-dinja fiżika darba għal kull cluster.
F'dan l-istadju għandna sistema li taħdem b'mod ġenerali. Il-kodiċi tiegħu f'forma kemmxejn simplifikata:
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);
}
}
}
}Kulma baqa’ kien li jiġu kkonfigurati d-dettalji:
1. Ifhem kemm għandek tillimita d-distanza massima tal-moviment fil-ħin.
Kien importanti għalina li nagħmlu l-logħba aċċessibbli kemm jista 'jkun f'kundizzjonijiet ta' netwerks mobbli fqar, għalhekk illimitajna l-istorja b'marġni ta '30 qurdien (b'rata ta' qurdien ta '20 Hz). Dan jippermetti lill-plejers jolqtu lill-avversarji anke f'pings għoljin ħafna.
2. Iddetermina liema oġġetti jistgħu jiġu mċaqalqa fil-ħin u liema ma jistgħux.
Aħna, ovvjament, qed nimxu lill-avversarji tagħna. Iżda tarki tal-enerġija li jistgħu jiġu installati, pereżempju, mhumiex. Iddeċidejna li kien aħjar li nagħtu prijorità lill-abbiltà difensiva, kif spiss isir fl-isparaturi onlajn. Jekk il-plejer diġà poġġa tarka fil-preżent, balal ikkumpensati b'dewmien mill-passat m'għandhomx itiru minnu.
3. Iddeċiedi jekk huwiex meħtieġ li tikkumpensa għall-abbiltajiet tad-dinosawri: gidma, denb strajk, eċċ Iddeċidejna dak li kien meħtieġ u pproċessahom skond l-istess regoli bħall-balal.
4. Iddetermina x'għandek tagħmel mal-colliders tal-plejer li għalih qed isir kumpens ta 'dewmien. B'mod tajjeb, il-pożizzjoni tagħhom m'għandhiex tinbidel fil-passat: il-plejer għandu jara lilu nnifsu fl-istess ħin li fih issa jinsab fuq is-server. Madankollu, aħna wkoll irrombla lura l-colliders tal-plejer tal-isparar, u hemm diversi raġunijiet għal dan.
L-ewwel, ittejjeb il-clustering: nistgħu nużaw l-istess stat fiżiku għall-plejers kollha b'pings mill-qrib.
It-tieni nett, fir-raycasts u l-koinċidenza kollha aħna dejjem neskludu l-colliders tal-plejer li għandu l-abbiltajiet jew il-projettili. F'Dino Squad, il-plejers jikkontrollaw id-dinosawri, li għandhom ġeometrija pjuttost mhux standard skont l-istandards tal-isparaturi. Anki jekk il-plejer jispara f'angolu mhux tas-soltu u t-trajettorja tal-bullet tgħaddi mill-kollider tad-dinosawru tal-plejer, il-bullet jinjoraha.
It-tielet nett, aħna nikkalkulaw il-pożizzjonijiet tal-arma tad-dinosawru jew il-punt ta 'applikazzjoni tal-kapaċità billi tuża dejta mill-ECS anki qabel il-bidu tal-kumpens tad-dewmien.
Bħala riżultat, il-pożizzjoni reali tal-colliders tal-plejer ikkumpensat b'dewmien mhix importanti għalina, għalhekk ħadna triq aktar produttiva u fl-istess ħin aktar sempliċi.
Il-latenza tan-netwerk ma tistax sempliċement titneħħa, tista' tiġi mgħottija biss. Bħal kull metodu ieħor ta 'travestiment, il-kumpens għad-dewmien tas-server għandu l-kompromessi tiegħu. Ittejjeb l-esperjenza tal-logħob tal-plejer li qed jispara għad-detriment tal-plejer li jkun sparat fuqu. Għal Dino Squad, madankollu, l-għażla hawnhekk kienet ovvja.
Naturalment, dan kollu kellu jitħallas ukoll mill-kumplessità miżjuda tal-kodiċi tas-server kollu kemm hu - kemm għall-programmaturi kif ukoll għad-disinjaturi tal-logħob. Jekk aktar kmieni s-simulazzjoni kienet sejħa sekwenzjali sempliċi ta 'sistemi, allura b'kumpens ta' dewmien, dehru linji u fergħat nested fiha. Għaddejna wkoll ħafna sforz biex nagħmluha konvenjenti biex taħdem magħhom.
Fil-verżjoni tal-2019 (u forsi ftit qabel), Unity żiedet appoġġ sħiħ għal xeni fiżiċi indipendenti. Implimentajnahom fuq is-server kważi immedjatament wara l-aġġornament, għax ridna neħilsu malajr mid-dinja fiżika komuni għall-kmamar kollha.
Aħna tajna kull kamra tal-logħob ix-xena fiżika tagħha stess u b'hekk eliminajna l-ħtieġa li "tnaddaf" ix-xena mid-dejta tal-kamra ġirien qabel ma tikkalkula s-simulazzjoni. L-ewwelnett, tat żieda sinifikanti fil-produttività. It-tieni nett, għamilha possibbli li teħles minn klassi sħiħa ta 'bugs li qamu jekk il-programmatur għamel żball fil-kodiċi tat-tindif tax-xena meta żied elementi ġodda tal-logħob. Żbalji bħal dawn kienu diffiċli biex jiġu debug, u ħafna drabi rriżultaw fl-istat ta 'oġġetti fiżiċi fix-xena ta' kamra waħda "jiċċirkola" f'kamra oħra.
Barra minn hekk, għamilna xi riċerka dwar jekk ix-xeni fiżiċi jistgħux jintużaw biex jaħżnu l-istorja tad-dinja fiżika. Jiġifieri, kondizzjonali, talloka mhux xena waħda għal kull kamra, iżda 30 xena, u agħmel buffer ċikliku minnhom, li fihom taħżen l-istorja. B'mod ġenerali, l-għażla rriżultat li kienet qed taħdem, iżda aħna ma implimentajnhiex: ma wriet l-ebda żieda tal-ġenn fil-produttività, iżda kienet teħtieġ bidliet pjuttost riskjużi. Kien diffiċli li wieħed ibassar kif is-server se jġib ruħu meta jaħdem għal żmien twil b'tant xeni. Għalhekk, segwejna r-regola: “Jekk ma tinqasamx, ma tiffissahx".
Sors: www.habr.com
