நெட்வொர்க் தாமத இழப்பீட்டு அல்காரிதம் மூலம் மொபைல் ஷூட்டருக்கான பாலிஸ்டிக் கணக்கீட்டின் இயக்கவியலை நாங்கள் எவ்வாறு உருவாக்கினோம்

நெட்வொர்க் தாமத இழப்பீட்டு அல்காரிதம் மூலம் மொபைல் ஷூட்டருக்கான பாலிஸ்டிக் கணக்கீட்டின் இயக்கவியலை நாங்கள் எவ்வாறு உருவாக்கினோம்

வணக்கம், நான் நிகிதா பிரிஷாக், பிக்சோனிக் சேவையக டெவலப்பர். இன்று நான் மொபைல் மல்டிபிளேயரில் பின்னடைவை ஈடுசெய்வது பற்றி பேச விரும்புகிறேன்.

ரஷ்ய மொழி உட்பட சர்வர் லேக் இழப்பீடு பற்றி பல கட்டுரைகள் எழுதப்பட்டுள்ளன. 90 களின் பிற்பகுதியிலிருந்து மல்டிபிளேயர் எஃப்.பி.எஸ் உருவாக்கத்தில் இந்த தொழில்நுட்பம் தீவிரமாகப் பயன்படுத்தப்படுவதால் இது ஆச்சரியமல்ல. எடுத்துக்காட்டாக, QuakeWorld mod ஐ நீங்கள் நினைவில் கொள்ளலாம், இது முதலில் பயன்படுத்தப்பட்ட ஒன்றாகும்.

எங்கள் மொபைல் மல்டிபிளேயர் ஷூட்டர் டினோ ஸ்குவாடிலும் இதைப் பயன்படுத்துகிறோம்.

இந்த கட்டுரையில், எனது குறிக்கோள் ஏற்கனவே ஆயிரம் முறை எழுதப்பட்டதை மீண்டும் செய்வதல்ல, ஆனால் எங்கள் தொழில்நுட்ப அடுக்கு மற்றும் முக்கிய விளையாட்டு அம்சங்களை கணக்கில் எடுத்துக்கொண்டு, எங்கள் விளையாட்டில் பின்னடைவு இழப்பீட்டை எவ்வாறு செயல்படுத்தினோம் என்பதைக் கூறுவது.

எங்கள் கார்டெக்ஸ் மற்றும் தொழில்நுட்பம் பற்றி சில வார்த்தைகள்.

டினோ ஸ்குவாட் ஒரு நெட்வொர்க் மொபைல் பிவிபி ஷூட்டர். வீரர்கள் பலவிதமான ஆயுதங்களைக் கொண்ட டைனோசர்களைக் கட்டுப்படுத்துகிறார்கள் மற்றும் 6v6 அணிகளில் ஒருவருக்கொருவர் சண்டையிடுகிறார்கள்.

கிளையன்ட் மற்றும் சர்வர் இரண்டும் யூனிட்டியை அடிப்படையாகக் கொண்டவை. கட்டிடக்கலை ஷூட்டர்களுக்கு மிகவும் உன்னதமானது: சேவையகம் சர்வாதிகாரமானது மற்றும் கிளையன்ட் கணிப்பு வாடிக்கையாளர்களுக்கு வேலை செய்கிறது. கேம் சிமுலேஷன் இன்-ஹவுஸ் ECS ஐப் பயன்படுத்தி எழுதப்பட்டது மற்றும் சர்வர் மற்றும் கிளையன்ட் இரண்டிலும் பயன்படுத்தப்படுகிறது.

பின்னடைவு இழப்பீடு பற்றி நீங்கள் கேள்விப்படுவது இதுவே முதல் முறை என்றால், இந்த சிக்கலுக்கான ஒரு சுருக்கமான உல்லாசப் பயணம்.

மல்டிபிளேயர் FPS கேம்களில், போட்டி பொதுவாக ரிமோட் சர்வரில் உருவகப்படுத்தப்படுகிறது. வீரர்கள் தங்கள் உள்ளீட்டை (அழுத்தப்பட்ட விசைகள் பற்றிய தகவல்களை) சேவையகத்திற்கு அனுப்புகிறார்கள், அதற்கு பதிலளிக்கும் விதமாக, பெறப்பட்ட தரவை கணக்கில் எடுத்துக்கொண்டு சேவையகம் புதுப்பிக்கப்பட்ட விளையாட்டு நிலையை அவர்களுக்கு அனுப்புகிறது. இந்த ஊடாடல் திட்டத்துடன், முன்னோக்கி விசையை அழுத்துவதற்கும் பிளேயர் கேரக்டர் திரையில் நகரும் தருணத்திற்கும் இடையிலான தாமதம் எப்போதும் பிங்கை விட அதிகமாக இருக்கும்.

உள்ளூர் நெட்வொர்க்குகளில் இந்த தாமதம் (பிரபலமாக உள்ளீடு லேக் என்று அழைக்கப்படுவது) கவனிக்கப்படாமல் இருக்கலாம், இணையத்தில் விளையாடும் போது அது ஒரு பாத்திரத்தை கட்டுப்படுத்தும் போது "பனி மீது சறுக்கி" போன்ற உணர்வை உருவாக்குகிறது. இந்தச் சிக்கல் மொபைல் நெட்வொர்க்குகளுக்கு இரட்டிப்பாகத் தொடர்புடையது, ஒரு பிளேயரின் பிங் 200 எம்எஸ் ஆக இருக்கும் போது அது இன்னும் சிறந்த இணைப்பாகக் கருதப்படுகிறது. பெரும்பாலும் பிங் 350, 500 அல்லது 1000 ms ஆக இருக்கலாம். பின்னர் உள்ளீடு பின்னடைவுடன் வேகமாக சுடும் வீரரை விளையாடுவது கிட்டத்தட்ட சாத்தியமற்றதாகிவிடும்.

இந்தச் சிக்கலுக்கான தீர்வு வாடிக்கையாளர் பக்க உருவகப்படுத்துதலாகும். இங்கே கிளையன்ட் தானே பிளேயர் கேரக்டருக்கு உள்ளீட்டைப் பயன்படுத்துகிறது, சேவையகத்தின் பதிலுக்காக காத்திருக்காமல். பதில் கிடைத்ததும், அது வெறுமனே முடிவுகளை ஒப்பிட்டு எதிரிகளின் நிலைகளை புதுப்பிக்கிறது. இந்த விஷயத்தில் ஒரு விசையை அழுத்தி முடிவை திரையில் காண்பிப்பதற்கான தாமதம் மிகக் குறைவு.

இங்கே நுணுக்கத்தைப் புரிந்துகொள்வது முக்கியம்: கிளையன்ட் எப்போதும் அதன் கடைசி உள்ளீட்டின் படி தன்னை ஈர்க்கிறது, மற்றும் எதிரிகள் - நெட்வொர்க் தாமதத்துடன், சேவையகத்திலிருந்து தரவிலிருந்து முந்தைய நிலைக்கு ஏற்ப. அதாவது, ஒரு எதிரியை சுடும்போது, ​​வீரர் தன்னை கடந்த காலத்தில் பார்க்கிறார். வாடிக்கையாளர் கணிப்பு பற்றி மேலும் நாங்கள் முன்பு எழுதினோம்.

இவ்வாறு, கிளையன்ட் கணிப்பு ஒரு சிக்கலைத் தீர்க்கிறது, ஆனால் இன்னொன்றை உருவாக்குகிறது: ஒரு வீரர் கடந்த காலத்தில் எதிரி இருந்த இடத்தில், அதே இடத்தில் சுடும் போது சர்வரில் சுட்டால், எதிரி அந்த இடத்தில் இருக்க முடியாது. சர்வர் லேக் இழப்பீடு இந்த சிக்கலை தீர்க்க முயற்சிக்கிறது. ஒரு ஆயுதம் சுடப்பட்டால், ஷாட் நேரத்தில் வீரர் உள்நாட்டில் பார்த்த கேம் நிலையை சர்வர் மீட்டெடுக்கிறது, மேலும் அவர் உண்மையில் எதிரியைத் தாக்கியிருக்க முடியுமா என்பதைச் சரிபார்க்கிறது. பதில் "ஆம்" எனில், அந்த நேரத்தில் எதிரி சர்வரில் இல்லாவிட்டாலும், வெற்றி கணக்கிடப்படும்.

இந்த அறிவைக் கொண்டு, டினோ ஸ்குவாடில் சர்வர் லேக் இழப்பீட்டைச் செயல்படுத்தத் தொடங்கினோம். முதலில், கிளையன்ட் பார்த்ததை சர்வரில் எவ்வாறு மீட்டெடுப்பது என்பதை நாம் புரிந்து கொள்ள வேண்டும்? மற்றும் சரியாக என்ன மீட்டெடுக்க வேண்டும்? எங்கள் விளையாட்டில், ஆயுதங்கள் மற்றும் திறன்களின் வெற்றிகள் ரேகாஸ்ட்கள் மற்றும் மேலடுக்குகள் மூலம் கணக்கிடப்படுகின்றன - அதாவது, எதிரியின் உடல் மோதல்களுடன் தொடர்புகொள்வதன் மூலம். அதன்படி, பிளேயர் உள்நாட்டில் "பார்த்த" இந்த மோதல்களின் நிலையை நாங்கள் சேவையகத்தில் மீண்டும் உருவாக்க வேண்டும். அந்த நேரத்தில் நாங்கள் யூனிட்டி பதிப்பு 2018.x ஐப் பயன்படுத்தினோம். இயற்பியல் ஏபிஐ நிலையானது, இயற்பியல் உலகம் ஒரே பிரதியில் உள்ளது. அதன் நிலையைச் சேமித்து, பெட்டியிலிருந்து மீட்டெடுக்க வழி இல்லை. அதனால் என்ன செய்வது?

தீர்வு மேற்பரப்பில் இருந்தது; அதன் அனைத்து கூறுகளும் ஏற்கனவே பிற சிக்கல்களைத் தீர்க்க எங்களால் பயன்படுத்தப்பட்டன:

  1. ஒவ்வொரு வாடிக்கையாளருக்கும், அவர் விசைகளை அழுத்தும்போது எதிரிகளை எந்த நேரத்தில் பார்த்தார் என்பதை நாம் அறிந்து கொள்ள வேண்டும். இந்த தகவலை உள்ளீட்டு தொகுப்பில் ஏற்கனவே எழுதி, கிளையன்ட் கணிப்பை சரிசெய்ய இதைப் பயன்படுத்தினோம்.
  2. விளையாட்டு நிலைகளின் வரலாற்றை நாம் சேமிக்க முடியும். அதில்தான் நமது எதிரிகளின் (எனவே அவர்கள் மோதுபவர்களின்) பதவிகளை நாங்கள் பிடிப்போம். நாங்கள் ஏற்கனவே சர்வரில் ஒரு மாநில வரலாற்றைக் கொண்டிருந்தோம், அதை உருவாக்கப் பயன்படுத்தினோம் டெல்டாக்கள். சரியான நேரத்தை அறிந்தால், வரலாற்றில் சரியான நிலையை நாம் எளிதாகக் கண்டுபிடிக்க முடியும்.
  3. இப்போது வரலாற்றிலிருந்து கேம் நிலையைக் கையில் வைத்திருப்பதால், பிளேயர் தரவை இயற்பியல் உலகின் நிலையுடன் ஒத்திசைக்க முடியும். இருக்கும் மோதல்கள் - நகர்த்தவும், காணாமல் போனவை - உருவாக்கவும், தேவையற்றவை - அழிக்கவும். இந்த தர்க்கம் ஏற்கனவே எழுதப்பட்டது மற்றும் பல ECS அமைப்புகளைக் கொண்டது. ஒரு யூனிட்டி செயல்பாட்டில் பல விளையாட்டு அறைகளை வைத்திருக்க இதைப் பயன்படுத்தினோம். இயற்பியல் உலகம் ஒரு செயல்முறைக்கு ஒன்று என்பதால், அது அறைகளுக்கு இடையில் மீண்டும் பயன்படுத்தப்பட வேண்டும். உருவகப்படுத்துதலின் ஒவ்வொரு குறிப்பிற்கும் முன், நாம் இயற்பியல் உலகின் நிலையை "ரீசெட்" செய்து, தற்போதைய அறைக்கான தரவுகளுடன் அதை மீண்டும் துவக்கி, ஒரு புத்திசாலித்தனமான பூலிங் சிஸ்டம் மூலம் முடிந்தவரை யூனிட்டி கேம் பொருட்களை மீண்டும் பயன்படுத்த முயற்சிக்கிறோம். கடந்த காலத்திலிருந்து விளையாட்டு நிலைக்கு அதே தர்க்கத்தைத் தூண்டுவது மட்டுமே எஞ்சியுள்ளது.

இந்த அனைத்து கூறுகளையும் ஒன்றாக இணைப்பதன் மூலம், இயற்பியல் உலகின் நிலையை சரியான தருணத்திற்கு மாற்றக்கூடிய "நேர இயந்திரம்" எங்களுக்கு கிடைத்தது. குறியீடு எளிமையானதாக மாறியது:

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;
     }
}

ஷாட்கள் மற்றும் திறன்களை எளிதாக ஈடுசெய்ய இந்த இயந்திரத்தை எவ்வாறு பயன்படுத்துவது என்பதைக் கண்டுபிடிப்பது மட்டுமே மீதமுள்ளது.

எளிமையான விஷயத்தில், இயக்கவியல் ஒரு ஹிட்ஸ்கானை அடிப்படையாகக் கொண்டால், எல்லாம் தெளிவாகத் தெரிகிறது: வீரர் சுடுவதற்கு முன், அவர் உடல் உலகத்தை விரும்பிய நிலைக்குத் திருப்ப வேண்டும், ஒரு ரேகாஸ்ட் செய்ய வேண்டும், வெற்றியை எண்ண வேண்டும் அல்லது தவறவிட வேண்டும். உலகத்தை ஆரம்ப நிலைக்குத் திரும்பு.

ஆனால் டினோ ஸ்குவாடில் இத்தகைய மெக்கானிக்கள் மிகக் குறைவு! விளையாட்டில் உள்ள பெரும்பாலான ஆயுதங்கள் எறிகணைகளை உருவாக்குகின்றன - பல உருவகப்படுத்துதல் உண்ணிகளுக்கு (சில சந்தர்ப்பங்களில், டஜன் கணக்கான உண்ணிகள்) பறக்கும் நீண்ட கால தோட்டாக்கள். அவர்களை என்ன செய்வது, எந்த நேரத்தில் பறக்க வேண்டும்?

В பண்டைய கட்டுரை ஹாஃப்-லைஃப் நெட்வொர்க் ஸ்டேக்கைப் பற்றி, வால்வைச் சேர்ந்த தோழர்கள் அதே கேள்வியைக் கேட்டார்கள், அவர்களின் பதில் இதுதான்: எறிபொருள் பின்னடைவு இழப்பீடு சிக்கலானது, அதைத் தவிர்ப்பது நல்லது.

எங்களிடம் இந்த விருப்பம் இல்லை: எறிகணை அடிப்படையிலான ஆயுதங்கள் விளையாட்டு வடிவமைப்பின் முக்கிய அம்சமாகும். எனவே நாங்கள் ஏதாவது கொண்டு வர வேண்டியிருந்தது. சில மூளைச்சலவைகளுக்குப் பிறகு, வேலை செய்வதாகத் தோன்றிய இரண்டு விருப்பங்களை நாங்கள் உருவாக்கினோம்:

1. எறிபொருளை உருவாக்கிய வீரரின் நேரத்துடன் இணைக்கிறோம். சேவையக உருவகப்படுத்துதலின் ஒவ்வொரு டிக், ஒவ்வொரு வீரரின் ஒவ்வொரு புல்லட்டிற்கும், இயற்பியல் உலகத்தை கிளையன்ட் நிலைக்குத் திருப்பி, தேவையான கணக்கீடுகளைச் செய்கிறோம். இந்த அணுகுமுறை சர்வரில் விநியோகிக்கப்பட்ட சுமை மற்றும் எறிகணைகளின் கணிக்கக்கூடிய விமான நேரத்தை சாத்தியமாக்கியது. எதிரி எறிகணைகள் உட்பட அனைத்து எறிகணைகளும் வாடிக்கையாளர் மீது கணிக்கப்பட்டுள்ளதால், முன்கணிப்பு எங்களுக்கு மிகவும் முக்கியமானது.

நெட்வொர்க் தாமத இழப்பீட்டு அல்காரிதம் மூலம் மொபைல் ஷூட்டருக்கான பாலிஸ்டிக் கணக்கீட்டின் இயக்கவியலை நாங்கள் எவ்வாறு உருவாக்கினோம்
படத்தில், டிக் 30 இல் உள்ள வீரர் எதிர்பார்ப்புடன் ஒரு ஏவுகணையை வீசுகிறார்: எதிரி எந்த திசையில் ஓடுகிறார் என்பதை அவர் பார்க்கிறார் மற்றும் ஏவுகணையின் தோராயமான வேகத்தை அறிவார். அவர் 33வது டிக்கில் இலக்கைத் தாக்கியதை உள்ளூரிலேயே பார்க்கிறார். தாமத இழப்பீட்டிற்கு நன்றி, இது சேவையகத்திலும் தோன்றும்

2. முதல் விருப்பத்தைப் போலவே எல்லாவற்றையும் செய்கிறோம், ஆனால், புல்லட் உருவகப்படுத்துதலின் ஒரு டிக் எண்ணைக் கணக்கிட்டால், நாங்கள் நிறுத்த மாட்டோம், ஆனால் அதே சர்வர் டிக்க்குள் அதன் விமானத்தை உருவகப்படுத்துவதைத் தொடர்கிறோம், ஒவ்வொரு முறையும் அதன் நேரத்தை சேவையகத்திற்கு நெருக்கமாகக் கொண்டுவருகிறோம். ஒன்றன் பின் ஒன்றாக டிக் மற்றும் collider நிலைகளை மேம்படுத்துகிறது. இரண்டு விஷயங்களில் ஒன்று நடக்கும் வரை நாங்கள் இதைச் செய்கிறோம்:

  • புல்லட் காலாவதியானது. இதன் பொருள் கணக்கீடுகள் முடிந்துவிட்டன, மிஸ் அல்லது ஹிட் என்று எண்ணலாம். மேலும் இது சுடப்பட்ட அதே டிக் இல் தான்! எங்களைப் பொறுத்தவரை இது பிளஸ் மற்றும் மைனஸாக இருந்தது. ஒரு பிளஸ் - ஏனெனில் ஷூட்டிங் பிளேயருக்கு இது தாக்குதலுக்கும் எதிரியின் ஆரோக்கியம் குறைவதற்கும் இடையிலான தாமதத்தை கணிசமாகக் குறைத்தது. எதிர்மறையானது என்னவென்றால், எதிராளிகள் வீரரை நோக்கி சுடும் போது அதே விளைவு காணப்பட்டது: எதிரி, மெதுவாக ராக்கெட்டை மட்டுமே சுட்டதாகத் தெரிகிறது, மேலும் சேதம் ஏற்கனவே கணக்கிடப்பட்டது.
  • புல்லட் சர்வர் நேரத்தை அடைந்துவிட்டது. இந்த வழக்கில், அதன் உருவகப்படுத்துதல் எந்த பின்னடைவு இழப்பீடு இல்லாமல் அடுத்த சர்வர் டிக் தொடரும். மெதுவான எறிகணைகளுக்கு, இது முதல் விருப்பத்துடன் ஒப்பிடும்போது இயற்பியல் பின்னடைவுகளின் எண்ணிக்கையை கோட்பாட்டளவில் குறைக்கலாம். அதே நேரத்தில், உருவகப்படுத்துதலின் சீரற்ற சுமை அதிகரித்தது: சேவையகம் செயலற்றதாக இருந்தது, அல்லது ஒரு சர்வர் டிக் பல புல்லட்டுகளுக்கு ஒரு டஜன் சிமுலேஷன் டிக்களைக் கணக்கிடுகிறது.

நெட்வொர்க் தாமத இழப்பீட்டு அல்காரிதம் மூலம் மொபைல் ஷூட்டருக்கான பாலிஸ்டிக் கணக்கீட்டின் இயக்கவியலை நாங்கள் எவ்வாறு உருவாக்கினோம்
முந்தைய படத்தில் உள்ள அதே காட்சி, ஆனால் இரண்டாவது திட்டத்தின் படி கணக்கிடப்படுகிறது. ஷாட் ஏற்பட்ட அதே டிக் நேரத்தில் ஏவுகணை சர்வர் நேரத்துடன் "பிடிபட்டது", மேலும் வெற்றியை அடுத்த டிக் என முன்கூட்டியே கணக்கிடலாம். 31 வது டிக் இல், இந்த வழக்கில், பின்னடைவு இழப்பீடு இனி பயன்படுத்தப்படாது

எங்கள் செயல்பாட்டில், இந்த இரண்டு அணுகுமுறைகளும் இரண்டு கோடுகளில் வேறுபடுகின்றன, எனவே நாங்கள் இரண்டையும் உருவாக்கினோம், நீண்ட காலமாக அவை இணையாக இருந்தன. ஆயுதத்தின் இயக்கவியல் மற்றும் புல்லட்டின் வேகத்தைப் பொறுத்து, ஒவ்வொரு டைனோசருக்கும் ஒன்று அல்லது மற்றொரு விருப்பத்தைத் தேர்ந்தெடுத்தோம். "இப்படிப்பட்ட நேரத்தில் எதிரியை பலமுறை அடித்தால், இவ்வளவு போனஸ் கிடைக்கும்" என்பது போன்ற இயக்கவியல் விளையாட்டில் தோன்றிய திருப்புமுனை. எந்த மெக்கானிக் எந்த நேரத்தில் வீரர் எதிரியை தாக்கினார் என்பது முக்கிய பங்கு வகித்தது, இரண்டாவது அணுகுமுறையுடன் வேலை செய்ய மறுத்துவிட்டார். எனவே நாங்கள் முதல் விருப்பத்துடன் சென்று முடித்தோம், இது இப்போது அனைத்து ஆயுதங்களுக்கும் விளையாட்டில் உள்ள அனைத்து செயலில் உள்ள திறன்களுக்கும் பொருந்தும்.

தனித்தனியாக, செயல்திறன் சிக்கலை எழுப்புவது மதிப்பு. இவை அனைத்தும் விஷயங்களை மெதுவாக்கும் என்று நீங்கள் நினைத்தால், நான் பதிலளிக்கிறேன்: அதுதான். மோதல்களை நகர்த்துவதற்கும் அவற்றை இயக்குவதற்கும் அணைப்பதற்கும் ஒற்றுமை மிகவும் மெதுவாக உள்ளது. டினோ ஸ்குவாடில், ஒரு "மோசமான" சூழ்நிலையில், போரில் ஒரே நேரத்தில் பல நூறு எறிகணைகள் இருக்கலாம். ஒவ்வொரு எறிபொருளையும் தனித்தனியாக எண்ணுவதற்கு மோதுபவர்களை நகர்த்துவது கட்டுப்படியாகாத ஆடம்பரமாகும். எனவே, இயற்பியல் "ரோல்பேக்குகளின்" எண்ணிக்கையைக் குறைப்பது முற்றிலும் அவசியமானது. இதைச் செய்ய, ECS இல் ஒரு தனி பாகத்தை உருவாக்கினோம், அதில் பிளேயரின் நேரத்தை பதிவு செய்கிறோம். பின்னடைவு இழப்பீடு தேவைப்படும் அனைத்து நிறுவனங்களிலும் அதைச் சேர்த்துள்ளோம் (திட்டங்கள், திறன்கள் போன்றவை). அத்தகைய நிறுவனங்களைச் செயலாக்கத் தொடங்குவதற்கு முன், இந்த நேரத்தில் அவற்றைக் கிளஸ்டர் செய்து, அவற்றை ஒன்றாகச் செயலாக்குகிறோம், ஒவ்வொரு கிளஸ்டருக்கும் ஒருமுறை இயற்பியல் உலகத்தை உருட்டுகிறோம்.

இந்த கட்டத்தில் நாம் பொதுவாக வேலை செய்யும் அமைப்பு உள்ளது. அதன் குறியீடு ஓரளவு எளிமைப்படுத்தப்பட்ட வடிவத்தில் உள்ளது:

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);
               }
          }
     }
}

விவரங்களை உள்ளமைக்க மட்டுமே எஞ்சியுள்ளது:

1. சரியான நேரத்தில் இயக்கத்தின் அதிகபட்ச தூரத்தை எவ்வளவு கட்டுப்படுத்துவது என்பதைப் புரிந்து கொள்ளுங்கள்.

மோசமான மொபைல் நெட்வொர்க்குகளின் சூழ்நிலையில் கேமை முடிந்தவரை அணுகக்கூடியதாக மாற்றுவது எங்களுக்கு முக்கியமானது, எனவே கதையை 30 டிக்களின் விளிம்புடன் (20 ஹெர்ட்ஸ் டிக் வீதத்துடன்) வரம்பிடினோம். இது வீரர்களை மிக அதிக பிங்ஸில் கூட எதிரிகளை அடிக்க அனுமதிக்கிறது.

2. எந்தெந்த பொருட்களை சரியான நேரத்தில் நகர்த்தலாம் மற்றும் எது முடியாது என்பதைத் தீர்மானிக்கவும்.

நிச்சயமாக, நாங்கள் எங்கள் எதிரிகளை நகர்த்துகிறோம். ஆனால் நிறுவக்கூடிய ஆற்றல் கவசங்கள், எடுத்துக்காட்டாக, இல்லை. ஆன்லைன் ஷூட்டர்களில் பெரும்பாலும் தற்காப்புத் திறனுக்கு முன்னுரிமை கொடுப்பது நல்லது என்று முடிவு செய்தோம். வீரர் ஏற்கனவே ஒரு கேடயத்தை நிகழ்காலத்தில் வைத்திருந்தால், கடந்த காலத்திலிருந்து தாமதமாக ஈடுசெய்யப்பட்ட தோட்டாக்கள் அதன் வழியாக பறக்கக்கூடாது.

3. டைனோசர்களின் திறன்களை ஈடுகட்டுவது அவசியமா என்பதை முடிவு செய்யுங்கள்: கடித்தல், வால் வேலைநிறுத்தம், முதலியன. நாங்கள் என்ன தேவை என்பதை முடிவு செய்து தோட்டாக்கள் போன்ற அதே விதிகளின்படி அவற்றைச் செயலாக்கினோம்.

4. பின்னடைவு இழப்பீடு செய்யப்படும் வீரரின் மோதல்களை என்ன செய்வது என்று தீர்மானிக்கவும். ஒரு நல்ல வழியில், அவர்களின் நிலை கடந்த காலத்திற்கு மாறக்கூடாது: வீரர் இப்போது சர்வரில் இருக்கும் அதே நேரத்தில் தன்னைப் பார்க்க வேண்டும். இருப்பினும், ஷூட்டிங் பிளேயரின் மோதல்களையும் நாங்கள் திருப்பி விடுகிறோம், இதற்கு பல காரணங்கள் உள்ளன.

முதலில், இது கிளஸ்டரிங்கை மேம்படுத்துகிறது: நெருக்கமான பிங்ஸ் கொண்ட அனைத்து வீரர்களுக்கும் ஒரே உடல் நிலையைப் பயன்படுத்தலாம்.

இரண்டாவதாக, அனைத்து ரேகாஸ்ட்கள் மற்றும் ஓவர்லாப்களிலும், திறன்கள் அல்லது எறிகணைகளை வைத்திருக்கும் வீரரின் மோதல்களை நாங்கள் எப்போதும் விலக்குகிறோம். டினோ ஸ்குவாடில், வீரர்கள் டைனோசர்களைக் கட்டுப்படுத்துகிறார்கள், அவை துப்பாக்கி சுடும் தரநிலைகளின்படி தரமற்ற வடிவவியலைக் கொண்டுள்ளன. வீரர் வழக்கத்திற்கு மாறான கோணத்தில் சுட்டாலும், புல்லட்டின் பாதை வீரரின் டைனோசர் மோதலின் வழியாக சென்றாலும், புல்லட் அதை புறக்கணிக்கும்.

மூன்றாவதாக, தாமத இழப்பீடு தொடங்குவதற்கு முன்பே ECS இலிருந்து தரவைப் பயன்படுத்தி டைனோசரின் ஆயுதத்தின் நிலைகள் அல்லது திறனைப் பயன்படுத்துவதற்கான புள்ளியைக் கணக்கிடுகிறோம்.

இதன் விளைவாக, பின்னடைவு ஈடுசெய்யப்பட்ட பிளேயரின் மோதல்களின் உண்மையான நிலை எங்களுக்கு முக்கியமற்றது, எனவே நாங்கள் அதிக உற்பத்தி மற்றும் அதே நேரத்தில் எளிமையான பாதையை எடுத்தோம்.

நெட்வொர்க் தாமதத்தை வெறுமனே அகற்ற முடியாது, அதை மறைக்க மட்டுமே முடியும். வேறு எந்த மாறுவேட முறையையும் போலவே, சர்வர் லேக் இழப்பீடும் அதன் பரிமாற்றங்களைக் கொண்டுள்ளது. சுடப்பட்ட வீரரின் செலவில் சுடும் வீரரின் கேமிங் அனுபவத்தை இது மேம்படுத்துகிறது. இருப்பினும், டினோ அணிக்கு, இங்கே தேர்வு தெளிவாக இருந்தது.

நிச்சயமாக, இவை அனைத்தும் ஒட்டுமொத்தமாக சர்வர் குறியீட்டின் சிக்கலான தன்மையால் செலுத்தப்பட வேண்டியிருந்தது - புரோகிராமர்கள் மற்றும் விளையாட்டு வடிவமைப்பாளர்களுக்கு. முந்தைய உருவகப்படுத்துதல் அமைப்புகளின் எளிய தொடர் அழைப்பாக இருந்தால், பின்னடைவு இழப்பீட்டுடன், உள்ளமைக்கப்பட்ட சுழல்கள் மற்றும் கிளைகள் அதில் தோன்றின. வேலை செய்வதற்கு வசதியாக நாங்கள் நிறைய முயற்சி செய்தோம்.

2019 பதிப்பில் (மற்றும் சற்று முன்னதாக இருக்கலாம்), யூனிட்டி சுதந்திரமான உடல் காட்சிகளுக்கு முழு ஆதரவைச் சேர்த்தது. எல்லா அறைகளுக்கும் பொதுவான இயற்பியல் உலகத்தை விரைவாக அகற்ற விரும்புவதால், புதுப்பித்த உடனேயே அவற்றை சர்வரில் செயல்படுத்தினோம்.

ஒவ்வொரு விளையாட்டு அறைக்கும் அதன் சொந்த இயற்பியல் காட்சியைக் கொடுத்தோம், இதனால் உருவகப்படுத்துதலைக் கணக்கிடுவதற்கு முன் பக்கத்து அறையின் தரவிலிருந்து காட்சியை "அழிக்க" வேண்டிய தேவையை நாங்கள் நீக்கினோம். முதலாவதாக, இது உற்பத்தித்திறனில் குறிப்பிடத்தக்க அதிகரிப்பைக் கொடுத்தது. இரண்டாவதாக, புதிய கேம் கூறுகளைச் சேர்க்கும்போது காட்சி தூய்மைப்படுத்தும் குறியீட்டில் புரோகிராமர் பிழை செய்தால் எழும் பிழைகளின் முழு வகுப்பிலிருந்தும் விடுபடுவதை இது சாத்தியமாக்கியது. இத்தகைய பிழைகள் பிழைத்திருத்தம் செய்ய கடினமாக இருந்தன, மேலும் அவை பெரும்பாலும் ஒரு அறையின் காட்சியில் உள்ள இயற்பியல் பொருட்களின் நிலையை மற்றொரு அறைக்குள் "பாயும்" விளைவித்தன.

கூடுதலாக, இயற்பியல் உலகின் வரலாற்றைச் சேமிக்க இயற்பியல் காட்சிகளைப் பயன்படுத்த முடியுமா என்பது குறித்தும் சில ஆராய்ச்சிகளை மேற்கொண்டோம். அதாவது, நிபந்தனையுடன், ஒவ்வொரு அறைக்கும் ஒரு காட்சியை அல்ல, ஆனால் 30 காட்சிகளை ஒதுக்கி, அவற்றில் ஒரு சுழற்சி இடையகத்தை உருவாக்கவும், அதில் கதையை சேமிக்கவும். பொதுவாக, விருப்பம் செயல்படுவதாக மாறியது, ஆனால் நாங்கள் அதைச் செயல்படுத்தவில்லை: இது உற்பத்தித்திறனில் எந்த வெறித்தனமான அதிகரிப்பையும் காட்டவில்லை, ஆனால் ஆபத்தான மாற்றங்கள் தேவைப்பட்டன. பல காட்சிகளுடன் நீண்ட நேரம் வேலை செய்யும் போது சர்வர் எப்படி செயல்படும் என்று கணிப்பது கடினமாக இருந்தது. எனவே, நாங்கள் விதியைப் பின்பற்றினோம்: "அது உடைக்கப்படவில்லை என்றால், அதை சரிசெய்ய வேண்டாம்".

ஆதாரம்: www.habr.com

கருத்தைச் சேர்