Timestep dalam game multi pemain

8

Saya mencoba untuk membungkus otak saya dengan konsep menciptakan pengalaman multiplayer server / klien.

Masalah saya terutama terkait dengan timestep. Pertimbangkan skenario berikut:

Klien terhubung ke server. Klien mengirimkan inputnya ke server untuk menunjukkan ia ingin pindah. Server mensimulasikan input dan menentukan posisi klien itu di dunia game.

Karena klien dan server sama-sama berjalan pada waktu yang berbeda, bagaimana Anda mensimulasikan secara akurat sehingga semua klien sinkron dengan server? Server saya saat ini diset pada 30ms timestep. Saat saya memproses perpindahan klien, ada ratusan permintaan yang menunggu untuk diproses, namun tidak ada cara untuk menunjukkan berapa lama antara masing-masing permintaan.

Saya benar-benar tidak memahami cara mensimulasikan dengan benar di server berdasarkan waktu, agar semuanya tersinkronisasi.

jallan
sumber
3
Anda juga dapat mencoba tautan ini: Gaffer
Multi

Jawaban:

3

Sederhananya, Anda perlu mengirim cap waktu dengan setiap snapshot dari server, dan dengan setiap input dari klien.

Di kedua ujung Anda memerlukan proses untuk "mengisi" frame mana pun di mana paket tidak diterima.

Dalam gim saya (gim aksi cepat - milik Anda mungkin berbeda), di server, saya membuang input "lama" (rusak), dan cukup tebak bahwa jika tidak ada paket input baru yang tiba, tombol yang sama tetaplah ditahan (ada sedikit lebih banyak hal untuk memastikan penekanan tombol / rilis pendek ditangani, tapi itu premis dasar).

Pada klien saya menyimpan "lag buffer" (dijelaskan dalam artikel ini yang ditautkan Tetrad). Saya menggunakan rata-rata bergulir dari waktu kedatangan untuk memastikan bahwa buffer lag tetap panjang yang tepat - membuat permainan klien berjalan sedikit lebih lambat atau lebih cepat untuk mengejar ketinggalan. Jika snapshot tidak tiba pada waktunya maka saya melakukan ekstrapolasi pada klien. Kalau tidak, saya interpolasi antara snapshots di buffer.

Klien juga bertanggung jawab untuk melacak round-trip-time untuk input dan menggunakannya untuk prediksi (server mengirimkan kembali cap waktu input yang digunakan saat menghitung frame yang diberikan). Ini buffer input untuk jangka waktu itu, replaying mereka untuk mengambil posisi pemain dari posisi "lama" (dalam snapshot dari server) ke posisi "hadir" yang diprediksi.

Pada dasarnya server hanya terus berjalan pada frame rate yang tetap. Terserah klien tetap disinkronkan dengan server.

Tentu saja, ini hanya tinjauan tingkat tinggi. Ada banyak detail seluk beluk yang harus Anda cari tahu saat menerapkannya.

Andrew Russell
sumber
Jika server menerima 10 perintah input dari klien antara satu langkah waktu server. Server mengeksekusi 10 perintah input. Bagaimana kita tahu berapa lama untuk mensimulasikan setiap perintah input? Bagaimana jika Anda hanya menerima satu perintah input, apakah Anda mensimulasikan perintah di seluruh rentang waktu dari langkah waktu?
jgallant
1
@Jon Kebanyakan game "aksi" mengirim input sebagai tombol atas / bawah menyatakan setiap frame. Server kemudian hanya menggunakan keadaan diterima terbaru yang negara untuk yang update centang. Paket-paket yang jatuh, terlambat dan rusak diabaikan. (Setidaknya pada tingkat dasar - Anda bisa, misalnya, menambahkan informasi urutan tambahan sehingga keadaan naik atau turun yang sangat singkat tidak diabaikan, bahkan jika dijatuhkan.) Ini mungkin yang harus Anda lakukan untuk semua input yang terkait waktu . Tindakan berbasis perintah (mis: "pindah ke sini" dalam RTS) umumnya tidak memiliki durasi yang terkait - jadi Anda cukup menjalankannya secara berurutan.
Andrew Russell