Model otoritas server

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Dalam model otoritas server, server adalah satu-satunya sumber kebenaran untuk seluruh keadaan permainan, dan klien hanya dipercaya untuk melaporkan input mereka sendiri. Arsitektur ini adalah dasar netcode inti dari permainan yang adil dan kompetitif karena mencegah seluruh kelas kecurangan seperti flyhacks atau speedhacks dengan tidak pernah mempercayai klien untuk melaporkan posisinya atau keadaan sendiri.

Keuntungan

Dalam sistem yang dimiliki server secara naif, klien hanya akan mengirimkan input mereka ke server dan menampilkan hasil permainan yang dikirim kembali oleh server. Meskipun secara teknis benar, sistem semacam itu akan menghadapi latensi input yang signifikan karena setiap tindakan pemain harus melakukan perjalanan ke server, diproses, dan hasilnya dikirim kembali ke klien sebelum dapat ditampilkan. Untuk sebagian besar permainan, terutama yang cepat, penundaan perjalanan tersebut akan membuat permainan terasa lambat, tidak responsif, dan tidak dapat dimainkan.

Dalam model otoritas server Roblox, latensi dikompensasi dengan membuat klien segera memprediksi efek dari input mereka selain mengirimkannya ke server. Misalnya, ketika seorang pemain menekan tombol, klien tidak menunggu server untuk merespons; sebaliknya, ia memprediksi beberapa frame ke depan dari keadaan server yang terakhir diketahui. Ini memungkinkan klien untuk menunjukkan hasil dari tindakan input secara instan, secara efektif menyembunyikan latensi jaringan dan membuat permainan terasa responsif.

Terkadang klien akan salah dalam prediksinya (misprediction) dan, karena latensi jaringan, klien tidak akan tahu bahwa ia telah melakukan kesalahan selama beberapa frame. Misalnya:

Ketika sebuah misprediksi terdeteksi, klien harus memperbaiki prediksinya berdasarkan keadaan otoritatif server. Jika keadaan otoritatif berbeda dari keadaan yang diprediksi klien, klien harus mengembalikan dan mensimulasikan ulang frame yang diprediksinya. Sistem prediksi sisi klien, pengembalian, dan simulasi ulang ini dikenal sebagai "kompensasi latensi" dan membantu membuat permainan multiplayer yang berotoritas server terasa halus dan responsif.

Pengaturan

Model otoritas server memerlukan teknologi mesin tertentu untuk berfungsi dengan benar. Konfirmasikan pengaturan properti berikut pada objek Workspace di Explorer:

  1. Workspace.AuthorityMode harus Server (mengatur ini secara otomatis mengatur lima berikutnya).
  2. Workspace.StreamingEnabled harus diaktifkan.

Konsep

Sistem otoritas server berjalan pada beberapa konsep inti sebagai berikut.

Prediksi klien

Melalui prediksi klien, klien mensimulasikan beberapa frame ke depan dari keadaan server yang terakhir diketahui untuk memprediksi efek dari input pemain secara langsung. Ini menyembunyikan latensi input, tetapi prediksi tersebut mungkin kemudian terbukti salah (misprediksi klien) dan karenanya memerlukan koreksi. Klien berusaha untuk mensimulasikan cukup jauh ke depan dari keadaan server otoritatif terakhir yang diketahui sehingga inputnya tiba di server pada frame yang dimaksud. Jumlah frame yang akan diprediksi klien ke depan dari keadaan server yang diketahui didasarkan pada latensi antara klien dan server.

Misprediksi klien

Ketika klien menerima keadaan otoritatif dari server, ia memeriksa keadaan itu terhadap catatan historis dari apa yang diprediksinya secara lokal untuk frame tersebut. Ketika ada perbedaan antara apa yang diprediksi klien prediksi dan apa yang sebenarnya dilakukan server, ini adalah misprediksi. Misprediksi dapat terjadi karena beberapa alasan, termasuk pergeseran dalam latensi jaringan, pemain lain bertindak dengan cara yang tidak diperkirakan klien, permainan menjalankan logika tertentu secara eksklusif di server, dll.

Jika keadaan otoritatif berbeda dari keadaan yang diprediksi klien, klien harus mengembalikan dan mensimulasikan ulang.

Pengembalian dan simulasi ulang

Ketika klien mendeteksi misprediksi, ia harus mengatur ulang ke keadaan otoritatif server dan kemudian mensimulasikan ulang untuk melompat kembali ke frame yang diprediksinya. Berdasarkan latensi jaringan, klien berusaha untuk mensimulasikan cukup jauh ke depan dari keadaan server otoritatif terakhir yang diketahui sehingga inputnya tiba di server pada frame yang dimaksud.

Dalam diagram di atas, klien mensimulasikan 2 frame ke depan dari server. Ia mengirimkan inputnya untuk frame 3 yang tiba pada frame yang dimaksud (3) di server. Server mengirimkan keadaan otoritatif untuk frame 3 dan klien menerimanya pada frame 7. Klien menemukan bahwa ia salah memprediksi frame 3 sehingga ia mengatur ulang ke frame 3 server dan mensimulasikan ulang frame 4, 5, dan 6 sebelum ia mensimulasikan frame 7. Pemain mungkin melihat artefak jaringan yang mencolok seperti gerakan tiba-tiba.

Singkatnya, klien:

  1. Menerima keadaan otoritatif dari server dan membandingkannya dengan keadaan yang diprediksi sendiri.
  2. Jika prediksi klien salah:
    1. Klien mengembalikan ke keadaan otoritatif terakhir yang diketahui yang diterima dari server.
    2. Klien mensimulasikan ulang dari keadaan otoritatif ke keadaan yang diprediksi, menerapkan kembali input lokal apa pun.

Implementasi

Kepemilikan jaringan dan prediksi

Dalam model otoritas server, Anda dapat menjaga objek gameplay inti tetap dimiliki server tanpa menanggung biaya latensi input yang biasanya terkait dengan kepemilikan server. Hal-hal seperti mobil, karakter pemain, atau objek kritis gameplay lainnya dapat tetap dimiliki server, bahkan saat berinteraksi dengan pemain lain.

Secara default, Roblox akan secara otomatis memprediksi properti dengan akses simulasi dekat pemain lokal Character, tetapi jika Anda ingin kontrol yang lebih terperinci, Anda dapat secara eksplisit memaksa prediksi sebuah instance dihidupkan atau dimatikan dengan RunService:SetPredictionMode().

Prediksi otomatis berlaku untuk seluruh perakitan fisika, bukan instance individu. Ketika klien memprediksi sebuah bagian, ia juga memprediksi setiap bagian yang terhubung secara fisik dengannya melalui pengelasan, sambungan, atau batasan, bersama dengan induk Model dari bagian-bagian tersebut dan setiap Humanoid di dalam model tersebut. Misalnya:

  • Model pedang yang dilas ke karakter yang diprediksi menjadi bagian dari perakitan karakter, sehingga diprediksi secara otomatis.
  • Model yang diparentkan ke karakter tetapi tidak terhubung secara fisik dengannya adalah perakitan terpisah. Itu hanya diprediksi jika berada dalam radius simulasi klien atau jika Anda memaksa prediksi dihidupkan dengan RunService:SetPredictionMode().

Untuk memeriksa apakah sebuah instance tertentu saat ini diprediksi, panggil RunService:GetPredictionStatus() dari klien.

Sinkronisasi simulasi

Dalam model otoritas server, klien dan server harus menjalankan simulasi inti, dan simulasi klien perlu dapat mengembalikan dan mensimulasikan ulang ketika terjadi misprediksi. Untuk mengaktifkan ini, tulis logika inti Anda di dalam fungsi yang terikat melalui RunService:BindToSimulation() dalam ModuleScript yang diinisialisasi di klien dan server.

Pengaturan otoritas server

Selama simulasi ulang, Roblox akan menjalankan kembali fungsi-fungsi yang terikat ke simulasi melalui BindToSimulation(). Memproses input pemain, berinteraksi dengan objek fisika yang disinkronkan, dan memperbarui keadaan permainan inti harus dilakukan di dalam fungsi-fungsi yang terikat tersebut.

Gunakan time() untuk logika berbasis waktu di dalam fungsi simulasi yang terikat, seperti menggerakkan kecepatan animasi atau mengubah nilai seiring waktu. Ketika Workspace.AuthorityMode adalah Enum.AuthorityMode.Server, time() disinkronkan antara klien dan server dan menggunakan waktu simulasi langkah tetap. Selama simulasi ulang, ia mundur ke frame otoritatif dan maju saat klien memutar ulang frame, sehingga mengembalikan nilai yang konsisten setiap kali sebuah frame disimulasikan.

ModuleScript bernama Simulation di ReplicatedStorage:

Simulasi
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Simulation = {}
Simulation.Initialize = function()
RunService:BindToSimulation(function(deltaTime)
-- Baca input pemain
-- Perbarui keadaan permainan
end)
end
return Simulation

Sinkronisasi keadaan dengan atribut

Roblox secara otomatis menyinkronkan semua properti dengan akses simulasi pada instance yang diprediksi. Untuk data kustom, atribut adalah cara utama untuk menyinkronkan instance yang ditandai sebagai diprediksi; pada instance semacam itu, setiap ketidaksesuaian dalam nilai atribut antara sumber kebenaran server dan prediksi klien akan memicu pengembalian dan simulasi ulang secara penuh.

Batasan atribut

Agar dapat direplikasi, sebuah atribut harus memenuhi semua kriteria berikut:

  • Itu termasuk di antara 64 atribut pertama pada Instance-nya.
  • Namanya mengandung paling banyak 50 karakter.
  • Jika atribut tipe string, nilainya mengandung paling banyak 50 karakter.

Akses simulasi

Banyak properti dan metode dalam referensi API mesin mencakup label Akses Simulasi, misalnya BasePart.CFrame. Properti dengan label ini akan diprediksi oleh sistem otoritas server. Selain itu, hanya properti dan metode dengan label ini yang dapat diakses di dalam fungsi yang terikat dengan RunService:BindToSimulation().

Membuat dan menghapus instance

Di dalam fungsi yang terikat melalui BindToSimulation(), Anda dapat membuat instance dengan Instance.new(), Instance:Clone(), atau Instance.fromExisting(). Klien membuat instance segera, dan Roblox menggabungkannya dengan salinan otoritatif server ketika salinan itu tiba. Untuk detail, lihat pembuatan instance prediktif.

Menghapus instance bekerja dengan cara yang berbeda. Instance:Destroy() tidak memiliki akses simulasi, dan Anda tidak dapat mengubah Parent dari sebuah instance yang sudah ada di DataModel, jadi memanggil salah satu di dalam fungsi yang terikat menyebabkan kesalahan. Sebagai gantinya, catat niat untuk menghapus sebuah instance dalam atribut di dalam simulasi, lalu hapus instance tersebut di luar simulasi, seperti dalam koneksi PostSimulation di server.

Script Server - Hapus Instance di Luar Simulasi
local RunService = game:GetService("RunService")
local character = script.Parent
RunService.PostSimulation:Connect(function()
-- "SwordEquipped" ditulis oleh simulasi ketika pemain melepas pedang
local sword = character:FindFirstChild("Sword")
if sword and not character:GetAttribute("SwordEquipped") then
sword:Destroy()
end
end)

Aksi input

Dalam permainan yang berotoritas server, cara utama bagi klien untuk mempengaruhi keadaan permainan adalah melalui Sistem Aksi Input. Input ini dikirim ke server dan diputar ulang selama simulasi ulang di klien. Akibatnya, InputActions harus digunakan untuk semua input yang mempengaruhi simulasi inti dan harus diperiksa untuk validitas sebelum diproses.

Perhatikan bahwa InputContexts harus menjadi keturunan dari Player sehingga mesin tahu siapa yang memiliki InputContext. Salah satu pendekatan adalah menambahkan InputContexts Anda ke folder di bawah ReplicatedStorage dan menggunakan Script di bawah ServerScriptService untuk mengklon InputContexts per pemain:

InputSetup
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local InputsFolder = ReplicatedStorage:WaitForChild("Inputs")
local function onPlayerAdded(player)
local clone = InputsFolder:Clone()
clone.Parent = player
end
Players.PlayerAdded:Connect(onPlayerAdded)
for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end

Dengan pola ini, Anda dapat membaca InputActions untuk semua pemain di RunService:BindToSimulation() di klien dan server untuk menerima data yang sama untuk frame tertentu dan mencatat input frame sebelumnya dalam atribut, misalnya untuk memicu karakter berlari ketika aksi input RunAction dipicu.

Acara jarak jauh

Acara jarak jauh masih dapat digunakan dalam model otoritas server untuk memfasilitasi komunikasi diskrit antara klien dan server. Misalnya, server dapat menggunakan acara jarak jauh untuk menyiarkan data tentang pemain yang mencetak poin atau mengambil objek, dan klien dapat menggunakan acara jarak jauh sebagai API alternatif untuk mengirim input ke server, seperti untuk penekanan tombol atau mengetuk objek di dunia 3D.

Animasi

Animasi yang mempengaruhi gameplay, seperti gerakan karakter atau animasi serangan, harus dikendalikan di dalam fungsi yang terikat melalui BindToSimulation() dalam ModuleScript yang sama yang berjalan di klien dan server. Anggota inti Animator dan AnimationTrack seperti LoadAnimation(), Play(), Stop(), AdjustSpeed(), dan TimePosition memiliki akses simulasi.

Status animasi adalah bagian dari simulasi yang diprediksi. Ketika terjadi pengembalian selama animasi, klien memutar ulang animasi ke keadaan otoritatif dan memutarnya kembali bersama dengan sisa simulasi, sehingga animasi klien dan server tetap sinkron. Karena klien mungkin mengganti trek animasi selama pengembalian, jangan simpan referensi AnimationTrack di antara frame. Sebagai gantinya, cari trek langsung setiap frame dengan Animator:GetTrackByAnimationId(). Untuk contoh lengkap, lihat menulis kode animasi.

Suara dan efek

Efek sisi klien seperti suara dan partikel harus ditulis dengan mengetahui bahwa simulasi klien hanyalah prediksi dari keadaan otoritatif server. BindToSimulation() membatasi properti dan metode apa yang dapat dipanggil dari dalam fungsi yang terikat untuk membantu membimbing Anda dalam menulis hanya ke keadaan simulasi yang disinkronkan. Menampilkan hasil dari simulasi ini, memicu efek dan suara, dll. harus dilakukan dalam fungsi terpisah yang terhubung ke RenderStepped yang membaca hasil simulasi dan memicu efek yang diinginkan.

Karena klien mungkin memprediksi sebuah peristiwa yang tidak pernah terjadi di server, kode rendering Anda harus dapat membatalkan atau menyembunyikan efek yang salah diprediksi. Panduan lebih lanjut tentang merender simulasi yang diprediksi dibahas dalam memutar suara dan efek visual.

Proyek contoh

Selain dokumentasi ini, template berikut dapat membantu Anda memulai:

Balapan
Sepak Bola
Laser Tag
©2026 Roblox Corporation. Roblox, logo Roblox, dan Powering Imagination termasuk dalam merek dagang kami yang terdaftar dan tidak terdaftar di AS dan negara lainnya.