Loop permainan sisi server

8

Banyak game java menggunakan thread.sleep () untuk mengontrol fps. Karena server tidak menampilkan grafik, haruskah loop permainan server tetap berjalan hanya menghitung waktu delta? Seperti contoh ini:

long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;   

while (gameRunning)
{
   long now = System.nanoTime();
   long updateLength = now - lastLoopTime;
   lastLoopTime = now;
   double delta = updateLength / ((double)OPTIMAL_TIME);

   doGameUpdates(delta);
}
Wolfrevo Kcats
sumber
11
"Banyak game java menggunakan thread.sleep () untuk mengontrol fps" Man, saya harap tidak.
MichaelHouse
1
@ Byte56 Saya tidak akan mengatakan banyak, tetapi beberapa mungkin melakukan hal seperti itu. Meskipun sleepig adalah sesuatu yang umum, mekanismenya tidak ditentukan sebelumnya. Thread.Sleepadalah cara paling sederhana, beberapa mungkin menunggu interupsi OS. Anda bahkan dapat menghitung vSync sebagai mekanisme tidur.
Ali1S232

Jawaban:

6

Ada banyak alasan yang tidak saya sarankan:

  1. Sumber daya komputer sangat berharga. bahkan jika mereka gratis, Anda tidak harus menyia-nyiakannya. pertimbangkan kasus di mana dua atau lebih server berjalan secara bersamaan di satu komputer. Jika satu instance server mengkonsumsi semua siklus CPU, instance lain hanya akan gagal. Tentunya OS akan mencoba untuk menangani perilaku agak serakah ini tetapi itu akan datang dengan biaya. Anda tidak akan tahu di mana OS akan menjeda proses Anda dan memberikan siklus CPU ke yang lain. Anda juga mungkin ingin melepaskan server Anda di samping permainan yang sebenarnya, sehingga pemain dapat memulai permainan LAN mereka sendiri. Agak menyebalkan jika saya mendedikasikan salah satu core CPU saya hanya untuk menjalankan server game!

  2. Sebagian besar game, game yang disinkronkan secara jaringan khusus, menggunakan langkah waktu yang tetap. hanya karena mereka ingin dapat memprediksi apa yang akan terjadi di sisi klien. Langkah waktu dinamis sangat bagus untuk banyak alasan selama Anda menjalankan satu instance dari game Anda dan itu tidak akan disinkronkan dengan tempat lain. Ini akan memberi Anda kekuatan sistem yang menjalankan permainan sejauh itu sepenuhnya. Tetapi sekali lagi ada harga untuk itu. Anda tidak akan dapat memprediksi apa yang akan terjadi jika Anda menjalankan game lagi. pertimbangkan tabrakan fisika sederhana, di mana kotak memukul kotak lain. Bahkan sedikit perubahan dalam langkah waktu akan menghasilkan perbedaan besar dalam resolusi tabrakan yang dihasilkan.

  3. Ada alasan sederhana mengapa orang menggunakan Thread. Tidur seperti yang Anda sarankan, karena menambahkan lebih banyak presisi tidak akan menghasilkan permainan yang lebih baik. Saat Anda bermain gim, Anda biasanya tidak akan melihat apakah suatu benda mati satu atau dua piksel. Jadi Anda tidak akan mendapatkan apa pun dengan meningkatkan akurasi. Juga ada batas lebar pita jaringan, baik sisi server dan sisi klien. Berarti Anda biasanya tidak akan dapat mengirim lebih dari 30-60 pembaruan per detik. Jadi saya bisa bertanya mengapa Anda menghitung negara yang hanya akan Anda buang?

  4. Ada banyak kasus di mana peningkatan presisi dapat menyebabkan masalah. Misalnya, orang cenderung menggunakan "Sinkronisasi vertikal" sehingga buffer grafis tidak diperbarui saat mengirim data ke monitor (yang dapat menyebabkan kehancuran). Juga sebagian besar gim menggunakan pelampung sebagai wadah nomor utama mereka tetapi tidak tepat. Anda mungkin tidak melihat ketika angka berada di antara 2 ^ -20 dan 2 ^ 20 tetapi di luar rentang itu Anda akan melihat perilaku yang tidak akurat. Misalnya, jika Anda mencoba menambahkan 10 ^ -5 ke 10 ^ 5 itu hanya mengabaikan penambahan Anda. Kesalahan ini biasanya tidak terlihat, tetapi ketika Anda tidak memiliki kontrol penuh atas langkah waktu Anda, hal-hal mungkin menjadi jelek. Dalam kasus Anda, karena tidak ada rendering yang terlibat, saya akan menganggap waktu pembaruan Anda seharusnya sekitar 10 ^ -4 paling banyak, artinya semua perubahan untuk angka di atas 100 akan kacau!

  5. Dalam beberapa game, hanya perintah pemain yang akan membuat perbedaan yang tidak terduga. jadi Anda mungkin hanya ingin menggunakan server Anda untuk menyiarkan perintah masing-masing pemain ke pemain lain. Dalam kasus ini, Anda bisa menunggu hingga klien mengirim pembaruan kepada server. Tidak ada yang bisa dihitung di antara pembaruan tersebut, artinya klien dapat melakukan segalanya (selain casting luas) jadi biarkan server hanya melakukan pekerjaannya dan menyerahkan yang lain kepada klien.

Ali1S232
sumber
Terima kasih, Anda membuat poin bagus di sana. Saya pikir saya tidak perlu cap waktu variabel. Satu hal lagi, apa yang Anda sarankan sebagai mekanisme tidur?
Wolfrevo Kcats
@WlofrevoKcast Ini sepenuhnya didasarkan pada kebutuhan gim Anda, tetapi untuk sebagian besar gim, pengatur waktu bahasa internal (atau interupsi waktu OS) adalah pilihan yang cukup baik.
Ali1S232
4

Anda harus membaca ini (stempel waktu Semi-tetap atau Sepenuhnya-tetap?) Dan ini (Gaffer pada Game - Perbaiki Stempel waktu Anda) .

Saya tidak yakin mengapa Anda memasukkan target FPS dalam logika server Anda. Temukan langkah waktu tetap yang sesuai untuk Anda dan perbarui sesuai dengan itu.

Pada dasarnya Anda akan memiliki loop sementara lain di dalam loop Anda while (gameRunning)yang akan mengumpulkan waktu sampai siap untuk melakukan pembaruan. Kemudian Anda melakukan pembaruan pada interval tetap.

MichaelHouse
sumber