څنګه موږ د ګرځنده شوټر لپاره د شبکې ځنډ جبران الګوریتم سره د بالیسټیک محاسبې میکانیکونه جوړ کړل

څنګه موږ د ګرځنده شوټر لپاره د شبکې ځنډ جبران الګوریتم سره د بالیسټیک محاسبې میکانیکونه جوړ کړل

سلام، زه نیکیتا برزاک یم، د Pixonic څخه سرور جوړونکی. نن زه غواړم په ګرځنده ملټي پلیر کې د ځنډ لپاره د جبران په اړه وغږیږم.

ډیری مقالې د سرور وقفې جبران په اړه لیکل شوي، په شمول په روسیه کې. دا د حیرانتیا خبره نده، ځکه چې دا ټیکنالوژي د 90 لسیزې راهیسې د ملټي پلیر FPS په جوړولو کې په فعاله توګه کارول کیږي. د مثال په توګه، تاسو کولی شئ د QuakeWorld موډ په یاد ولرئ، کوم چې د دې کارولو لپاره لومړی و.

موږ دا زموږ په ګرځنده ملټي پلیر شوټر ډینو سکواډ کې هم کاروو.

پدې مقاله کې ، زما هدف دا نه دی چې هغه څه تکرار کړئ چې دمخه یې زر ځله لیکل شوي ، مګر دا ویل چې موږ څنګه زموږ په لوبه کې د ځنډ جبران پلي کړو ، زموږ د ټیکنالوژۍ سټیک او د لوبې اصلي ځانګړتیاوې په پام کې نیولو سره.

زموږ د کورټیکس او ټیکنالوژۍ په اړه یو څو خبرې.

ډینو سکواډ د شبکې ګرځنده PvP شوټر دی. لوبغاړي په مختلفو وسلو سمبال ډیناسور کنټرولوي او په 6v6 ټیمونو کې یو له بل سره جګړه کوي.

پیرودونکي او سرور دواړه د یووالي پراساس دي. جوړښت د شوټرانو لپاره خورا کلاسیک دی: سرور مستبد دی ، او د پیرودونکي وړاندوینه په پیرودونکو کار کوي. د لوبې سمول د کور دننه ECS په کارولو سره لیکل شوی او په سرور او پیرودونکي دواړو کې کارول کیږي.

که دا لومړی ځل وي چې تاسو د ځنډ جبران په اړه اوریدلي یاست، دلته د مسلې په اړه یو لنډ سفر دی.

په ملټي پلیر FPS لوبو کې ، لوبه معمولا په ریموټ سرور کې سمول کیږي. لوبغاړي سرور ته خپل ان پټ (د فشار شوي کیلي په اړه معلومات) لیږي، او په ځواب کې سرور دوی ته د ترلاسه شوي معلوماتو په پام کې نیولو سره د لوبې تازه حالت لیږي. د دې متقابل عمل سکیم سره ، د فارورډ کیلي فشار کولو او هغه شیبې ترمینځ ځنډ چې د لوبغاړي کرکټر په سکرین کې حرکت کوي تل به د پینګ څخه ډیر وي.

پداسې حال کې چې په محلي شبکو کې دا ځنډ (په مشهوره توګه د انپټ لیګ په نوم یادیږي) ممکن د پام وړ نه وي، کله چې د انټرنیټ له لارې لوبې کول دا د "یخ پر یخ سلیډ" احساس رامینځته کوي کله چې یو کرکټر کنټرولوي. دا ستونزه د ګرځنده شبکو لپاره دوه چنده اړونده ده ، چیرې چې قضیه کله چې د لوبغاړي پینګ 200 ms وي لاهم عالي اړیکه ګڼل کیږي. ډیری وختونه پینګ 350، 500، یا 1000 ms وي. بیا د ان پټ لیګ سره د ګړندي شوټر لوبه کول نږدې ناممکن کیږي.

د دې ستونزې حل د پیرودونکي اړخ سمولو وړاندوینه ده. دلته پیرودونکی پخپله د لوبغاړي کرکټر ته ان پټ پلي کوي ، پرته لدې چې د سرور څخه ځواب ته انتظار وکړي. او کله چې ځواب ترلاسه شي، دا په ساده ډول پایلې پرتله کوي او د مخالفینو موقف تازه کوي. په دې حالت کې د کیلي فشارولو او په سکرین کې د پایلې ښودلو ترمنځ ځنډ لږ دی.

دا مهمه ده چې دلته د پام وړ پوه شئ: پیرودونکی تل د خپل وروستي ان پټ سره سم ځان راوباسي، او دښمنان - د شبکې ځنډ سره، د سرور څخه د معلوماتو څخه د تیر حالت سره سم. دا دی، کله چې په دښمن ډزې کوي، لوبغاړی هغه د خپل ځان په پرتله په تیرو وختونو کې ګوري. د پیرودونکي وړاندوینې په اړه نور موږ مخکې لیکلي.

پدې توګه ، د پیرودونکي وړاندوینه یوه ستونزه حل کوي ، مګر بله رامینځته کوي: که چیرې یو لوبغاړی په هغه ځای کې ډزې وکړي چیرې چې دښمن په تیرو وختونو کې و ، په سرور کې کله چې په ورته ځای کې ډزې کولې ، نو دښمن ممکن نور پدې ځای کې نه وي. د سرور ځنډ خساره د دې ستونزې حل کولو هڅه کوي. کله چې وسله وویشتل شي ، سرور د لوبې حالت بحالوي چې لوبغاړي د شاټ په وخت کې ځایی لیدلی ، او ګوري چې ایا هغه واقعیا دښمن ته زیان رسولی شي. که ځواب "هو" وي، هټ شمیرل کیږي، حتی که دښمن په دې وخت کې په سرور کې نه وي.

د دې پوهې سره وسله وال، موږ په ډینو سکواډ کې د سرور ځنډ جبران پلي کول پیل کړل. له هرڅه دمخه ، موږ باید پوه شو چې څنګه په سرور کې بحال کړو چې پیرودونکي څه ولیدل؟ او په حقیقت کې د بیارغونې اړتیا څه ده؟ زموږ په لوبه کې، د وسلو او وړتیاوو څخه ډزې د ریکاسټونو او پوښونو له لارې محاسبه کیږي - دا د دښمن فزیکي ټکرونو سره د تعامل له لارې. په دې اساس، موږ اړتیا درلوده چې د دې ټکرونو موقعیت بیا تولید کړو، کوم چې لوبغاړی په سرور کې په محلي توګه "ولید". په هغه وخت کې موږ د یووالي نسخه 2018.x کاروو. هلته د فزیک API جامد دی، فزیکي نړۍ په یوه کاپي کې شتون لري. هیڅ لاره نشته چې خپل دولت وژغوري او بیا یې له بکس څخه بیرته راولي. نو څه وکړي؟

د حل لاره په سطحه وه؛ د هغې ټول عناصر لا دمخه زموږ لخوا د نورو ستونزو د حل لپاره کارول شوي وو:

  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. موږ هر څه د لومړي اختیار په څیر ترسره کوو، مګر، د مرمۍ سمولو یو ټیک شمیرلو سره، موږ نه درېږو، مګر د ورته سرور ټیک کې د الوتنې سمولو ته دوام ورکوو، هر ځل چې خپل وخت سرور ته نږدې کوي. یو په یو ټیک کول او د کلاډر موقعیتونه تازه کول. موږ دا تر هغه وخته کوو چې د دوو شیانو څخه یو پیښ شي:

  • ګولۍ ختمه شوې ده. دا پدې مانا ده چې حسابونه پای ته رسیدلي، موږ کولی شو یو له لاسه ورکړو یا مات کړو. او دا په هماغه ټیک کې دی چې په کې ډزې شوې وې! زموږ لپاره دا دواړه جمع او منفي وو. یو پلس - ځکه چې د شوټینګ لوبغاړي لپاره دا د پام وړ د برید او د دښمن روغتیا کې کمښت ترمینځ ځنډ کم کړی. منفي اړخ دا دی چې ورته اغیزه لیدل شوې کله چې مخالفین په لوبغاړي ډزې کوي: دښمن، داسې ښکاري چې یوازې یو ورو راکټ توغولی، او زیان یې دمخه شمیرل شوی و.
  • بلیټ د سرور وخت ته رسیدلی. په دې حالت کې، د هغې سمول به په راتلونکي سرور ټیک کې پرته له کوم ځنډ جبران ته دوام ورکړي. د ورو پروجیکلونو لپاره، دا کولی شي په تیوریکي توګه د لومړي اختیار په پرتله د فزیک رول بیکونو شمیر کم کړي. په ورته وخت کې ، په سمولیشن کې غیر مساوي بار ډیر شوی: سرور یا بې کاره و ، یا په یو سرور ټیک کې دا د څو ګولیو لپاره د درجن سمولیشن ټیک محاسبه کوي.

څنګه موږ د ګرځنده شوټر لپاره د شبکې ځنډ جبران الګوریتم سره د بالیسټیک محاسبې میکانیکونه جوړ کړل
د تیر انځور په څیر ورته سناریو، مګر د دویم سکیم مطابق حساب شوی. توغندی د سرور وخت سره په ورته ټیک کې "کیچ اپ" شو چې ډزې وشوې، او برید د راتلونکي ټیک په څیر شمیرل کیدی شي. په 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. دا معلومه کړئ چې د لوبغاړي د ټکر کونکو سره څه وکړي د کوم لپاره چې د ځنډ جبران ترسره کیږي. په ښه توګه، د دوی موقف باید تیر وخت ته بدلون ورنکړي: لوبغاړی باید خپل ځان په ورته وخت کې وګوري چې هغه اوس په سرور کې دی. په هرصورت، موږ د شوټینګ لوبغاړي ټکرونه هم بیرته راګرځوو، او د دې لپاره ډیری دلیلونه شتون لري.

لومړی، دا کلسترینګ ته وده ورکوي: موږ کولی شو د نږدې پینګونو سره د ټولو لوبغاړو لپاره ورته فزیکي حالت وکاروو.

دوهم، په ټولو raycasts او overlaps کې موږ تل د هغه لوبغاړي ټکرونه خارج کوو څوک چې وړتیاوې یا پروجیکلونه لري. په ډینو سکواډ کې ، لوبغاړي ډیناسور کنټرولوي ، کوم چې د شوټر معیارونو سره غیر معیاري جیومیټري لري. حتی که لوبغاړی په غیر معمولي زاویه کې ډزې وکړي او د مرمۍ لاره د لوبغاړي ډیناسور له ټکر څخه تیریږي، ګولۍ به یې له پامه غورځوي.

دریم، موږ د ډیناسور د وسلو موقعیت یا د وړتیا د پلي کولو نقطه محاسبه کوو حتی د ځنډ جبران له پیل دمخه د ECS څخه ډیټا په کارولو سره.

د پایلې په توګه، د ځنډ جبران شوي لوبغاړي د ټکر اصلي موقعیت زموږ لپاره مهم نه دی، نو موږ یو ډیر ګټور او په ورته وخت کې ساده لاره غوره کړه.

د شبکې ځنډ په ساده ډول نشي لرې کیدی ، دا یوازې ماسک کیدی شي. د هرډول نورو میتودونو په څیر، د سرور ځنډ جبران خپل تجارت لري. دا د لوبغاړي لوبې تجربه ښه کوي څوک چې د لوبغاړي په مصرف کې ډزې کوي چې ډزې کیږي. د ډینو سکواډ لپاره ، په هرصورت ، دلته انتخاب څرګند و.

البته، دا ټول باید په ټوله کې د سرور کوډ د زیاتوالي پیچلتیا لخوا تادیه شي - دواړه د پروګرام کونکو او د لوبې ډیزاینرانو لپاره. که دمخه سمول د سیسټمونو ساده ترتیبي کال و ، نو د ځنډ جبران سره ، د ځړول شوي لوپونه او څانګې پکې څرګندې شوې. موږ د کار کولو لپاره د اسانتیا لپاره ډیرې هڅې هم مصرف کړې.

د 2019 نسخه کې (او شاید یو څه دمخه) ، یووالي د خپلواک فزیکي صحنو لپاره بشپړ ملاتړ اضافه کړ. موږ دا د تازه کولو وروسته سمدلاسه په سرور کې پلي کړل ، ځکه چې موږ غوښتل ژر تر ژره له فزیکي نړۍ څخه خلاص شو چې ټولو خونو ته عام دی.

موږ هرې لوبې خونې ته خپله فزیکي صحنه ورکړه او پدې توګه د سمول محاسبه کولو دمخه د ګاونډي خونې ډیټا څخه د صحنې "پاک" کولو اړتیا له مینځه وړو. لومړی، دا په تولید کې د پام وړ زیاتوالی دی. دوهم ، دا د دې امکان رامینځته کړی چې د بګونو ټول ټولګي څخه خلاصون ترلاسه کړي چې راپورته کیږي که چیرې برنامه کونکي د لوبې نوي عناصر اضافه کولو پرمهال د صحنې پاکولو کوډ کې تېروتنه وکړي. دا ډول تېروتنې له منځه وړل ستونزمن وو، او دوی ډیری وختونه د یوې خونې په صحنه کې د فزیکي شیانو حالت په بل خونه کې "بهیدنه" پایله درلوده.

سربیره پردې، موږ ځینې څیړنې ترسره کړې چې ایا فزیکي صحنې د فزیکي نړۍ تاریخ ذخیره کولو لپاره کارول کیدی شي. دا، په مشروط ډول، هرې کوټې ته یوه صحنه مه اختصاص کړئ، مګر 30 صحنې، او له دوی څخه یو سایکلیک بفر جوړ کړئ، په کوم کې چې کیسه ذخیره کړئ. په عموم کې، اختیار په کار وګرځید، مګر موږ یې پلي نه کړ: دا د تولید په برخه کې هیڅ لیونۍ زیاتوالی ندی ښودلی، مګر د خطر سره سم بدلونونو ته اړتیا لري. دا ستونزمنه وه چې وړاندوینه وکړو چې سرور به څنګه چلند وکړي کله چې د ډیری صحنو سره د اوږدې مودې لپاره کار کوي. له همدې امله، موږ دا قاعده تعقیب کړه: "که دا مات شوی نه وي ، نو مه یې سم کړئ".

سرچینه: www.habr.com

Add a comment