ใน โมเดลอำนาจของเซิร์ฟเวอร์ เซิร์ฟเวอร์จะเป็น แหล่งข้อมูลที่แท้จริง เพียงแหล่งเดียวสำหรับสถานะเกมทั้งหมด และไคลเอนต์จะได้รับการตรวจสอบว่าเชื่อถือได้เพียงการรายงานข้อมูลนำเข้าของตนเอง สถ mim ในสถ mim นี้เป็นรากฐานโค้ดเครือข่ายของเกมที่ยุติธรรมและแข่งขันได้ เนื่องจากมันห้ามไม่ให้การโกงในรูปแบบต่างๆ เช่น flyhacks หรือ speedhacks โดยไม่เชื่อถือไคลเอนต์ในการรายงานตำแหน่งหรือสถานะของตนเอง
ข้อดี
ในระบบที่เซิร์ฟเวอร์เป็นเจ้าของที่ไร้เดียงสา ไคลเอนต์จะส่งการนำเข้าสำหรับเซิร์ฟเวอร์และแสดงผลการเล่นของเกมที่ส่งกลับโดยเซิร์ฟเวอร์ ในทางเทคนิคแล้ว แม้ว่าระบบเช่นนี้จะถูกต้อง แต่จะพบกับ การหน่วงเวลาในการนำเข้า อย่างมีนัยสำคัญ เนื่องจากการกระทำของผู้เล่นแต่ละคนจะต้องเดินทางไปยังเซิร์ฟเวอร์ ถูกประมวลผล และผลลัพธ์จะถูกส่งกลับไปยังไคลเอนต์ก่อนที่จะสามารถแสดงได้ สำหรับเกมส่วนใหญ่โดยเฉพาะเกมที่มีความเร็วสูง การหน่วงเวลาในการเดินทางกลับจะทำให้การเล่นรู้สึกมีกระตุก ไม่ตอบสนอง และไม่สามารถเล่นได้
ใน โมเดลอำนาจของเซิร์ฟเวอร์ ของ Roblox การหน่วงเวลาจะถูกชดเชยโดยการให้ไคลเอนต์พยากรณ์ผลกระทบของการนำเข้าสำหรับพวกเขาทันทีในขณะที่ส่งไปยังเซิร์ฟเวอร์ ตัวอย่างเช่น เมื่อผู้เล่นกดปุ่ม ไคลเอนต์จะไม่รอการตอบสนองจากเซิร์ฟเวอร์ แต่จะ พยากรณ์ ไปข้างหน้าไม่กี่เฟรมจากสถานะที่เซิร์ฟเวอร์รู้จักล่าสุด สิ่งนี้ช่วยให้ไคลเอนต์แสดงผลลัพธ์ของการกระทำการนำเข้าทันที ทำให้ซ่อนการหน่วงเวลาเครือข่ายและทำให้เกมรู้สึกตอบสนอง
บางครั้งไคลเอนต์จะทำพยากรณ์ผิด (การพยากรณ์ผิด) และเนื่องจากการหน่วงเวลาเครือข่าย ไคลเอนต์จะไม่รู้ว่าตนได้ทำผิดเป็นระยะเวลาหลายเฟรม ตัวอย่างเช่น:
เมื่อการพยากรณ์ผิดถูกตรวจพบ ไคลเอนต์จะต้องแก้ไขการพยากรณ์ของตนตามสถานะ ที่มีอำนาจ ของเซิร์ฟเวอร์ หากสถานะที่มีอำนาจแตกต่างจากสถานะที่ไคลเอนต์พยากรณ์ ไคลเอนต์จะต้อง ย้อนกลับและทำซ้ำ เฟรมที่พยากรณ์ สิ่งนี้ของจึงมีระบบการพยากรณ์จากฝั่งไคลเอนต์, การย้อนกลับ, และการทำซ้ำ ซึ่งเป็นที่รู้จักกันในชื่อ "การชดเชยการหน่วงเวลา" และช่วยทำให้เกมมัลติเพลเยอร์ที่มีอำนาจของเซิร์ฟเวอร์รู้สึกสมูทและตอบสนอง
การตั้งค่า
โมเดลอำนาจของเซิร์ฟเวอร์ต้องการเทคโนโลยีของเอนจินอื่นๆ เพื่อให้ทำงานได้อย่างถูกต้อง ยืนยันการตั้งค่าคุณสมบัติเหล่านี้บนวัตถุ Workspace ใน Explorer:
- Workspace.AuthorityMode ต้องเป็น Server (การตั้งค่านี้จะตั้งค่าค่าห้าค่าถัดไปโดยอัตโนมัติ)
- Workspace.NextGenerationReplication จะต้องเปิดใช้งาน
- Workspace.PlayerScriptsUseInputActionSystem จะต้องเปิดใช้งาน
- Workspace.SignalBehavior จะต้องเป็น Deferred
- Workspace.UseFixedSimulation จะต้องเปิดใช้งาน
- Workspace.StreamingEnabled จะต้องเปิดใช้งาน
แนวคิด
ระบบอำนาจของเซิร์ฟเวอร์ทำงานจากแนวคิดหลักไม่กี่ประการดังนี้
การพยากรณ์ของไคลเอนต์
ผ่าน การพยากรณ์ของไคลเอนต์ ไคลเอนต์จะจำลองเฟรมไปข้างหน้าจากสถานะเซิร์ฟเวอร์ล่าสุดเพื่อพยากรณ์ผลกระทบของข้อมูลนำเข้าของผู้เล่นทันที สิ่งนี้ช่วยซ่อนการหน่วงเวลาในการนำเข้า แต่การพยากรณ์อาจกลายเป็นไม่ถูกต้องในภายหลัง (การพยากรณ์ผิดของไคลเอนต์) และต้องการการแก้ไข ไคลเอนต์จะพยายามจำลองไปข้างหน้าจากสถานะเซิร์ฟเวอร์ที่ยืนยันล่าสุดเพียงพอเพื่อให้ข้อมูลนำเข้าของมันมาถึงเซิร์ฟเวอร์ในเฟรมที่ต้องการ จำนวนเฟรมที่ไคลเอนต์จะพยากรณ์ไปข้างหน้าจากสถานะเซิร์ฟเวอร์ที่ทราบจะขึ้นอยู่กับการหน่วงเวลาระหว่างไคลเอนต์และเซิร์ฟเวอร์
การพยากรณ์ผิดของไคลเอนต์
เมื่อไคลเอนต์ได้รับสถานะที่มีอำนาจจากเซิร์ฟเวอร์ มันจะตรวจสอบสถานะนั้นกับบันทึกทางประวัติศาสตร์ของสิ่งที่มันพยากรณ์ในท้องถิ่นสำหรับเฟรมนั้น เมื่อมีความแตกต่างระหว่างสิ่งที่ไคลเอนต์ พยากรณ์ และสิ่งที่เซิร์ฟเวอร์ทำจริงๆ สิ่งนี้จะเรียกว่า การพยากรณ์ผิด การพยากรณ์ผิดสามารถเกิดขึ้นได้หลายสาเหตุ รวมถึงการเปลี่ยนแปลงในการหน่วงเวลาเครือข่าย, การกระทำโดยผู้เล่นคนอื่นในทางที่ไคลเอนต์ไม่คาดคิด, โลกของเกมที่ทำงานลอจิกบางอย่างเฉพาะที่เซิร์ฟเวอร์ เป็นต้น
หากสถานะที่มีอำนาจแตกต่างจากสถานะที่ไคลเอนต์พยากรณ์ ไคลเอนต์จะต้อง ย้อนกลับและทำซ้ำ
การย้อนกลับและการทำซ้ำ
เมื่อไคลเอนต์ตรวจพบ การพยากรณ์ผิด มันจะต้องตั้งค่ากลับไปยังสถานะที่มีอำนาจของเซิร์ฟเวอร์แล้วทำการทำซ้ำเพื่อกระโดดกลับไปยังเฟรมที่พยากรณ์ โดยอิงจากการหน่วงเวลาในเครือข่าย ไคลเอนต์จะพยายามจำลองไปข้างหน้าเพียงพอจากสถานะที่มีอำนาจเพื่อให้ข้อมูลนำเข้ามาถึงเซิร์ฟเวอร์ที่เฟรมที่ต้องการ
สรุปได้ว่า ไคลเอนต์:
- รับ สถานะที่มีอำนาจ จากเซิร์ฟเวอร์และเปรียบเทียบกับ สถานะที่พยากรณ์ ของตน
- หากการพยากรณ์ของไคลเอนต์ไม่ถูกต้อง:
- ไคลเอนต์ย้อนกลับไปที่สถานะที่มีอำนาจล่าสุดที่ได้รับจากเซิร์ฟเวอร์
- ไคลเอนต์ทำซ้ำจากสถานะที่มีอำนาจไปยังสถานะที่พยากรณ์ โดยใช้ข้อมูลนำเข้าสถานะในท้องถิ่นใหม่อีกครั้ง
การดำเนินการ
การเป็นเจ้าของเครือข่ายและการพยากรณ์
ในโมเดลอำนาจของเซิร์ฟเวอร์ คุณสามารถเก็บวัตถุการเล่นหลักที่เป็นเจ้าของเซิร์ฟเวอร์โดยไม่ต้องจ่ายค่าธรรมเนียมจากการหน่วงเวลาในการนำเข้าสำหรับการที่เป็นเจ้าของเซิร์ฟเวอร์ วัตถุต่างๆ เช่น รถยนต์, ตัวละครผู้เล่น, หรือวัตถุอื่นๆ ที่สำคัญต่อการเล่นสามารถยังคงเป็นเจ้าของเซิร์ฟเวอร์ได้ แม้ว่าจะมีการโต้ตอบกับผู้เล่นคนอื่นก็ตาม
ตามค่าเริ่มต้น Roblox จะคาดการณ์คุณสมบัติด้วย การเข้าถึงการจำลอง ใกล้กับผู้เล่นในพื้นที่ Character แต่หากคุณต้องการการควบคุมที่ละเอียดมากขึ้น คุณสามารถบังคับการพยากรณ์ของอินสแตนซ์ได้ด้วย RunService:SetPredictionMode()
การซิงค์การจำลอง
ในโมเดลอำนาจของเซิร์ฟเวอร์ ไคลเอนต์และเซิร์ฟเวอร์ต้องทำการจำลองแกนหลัก และการจำลองของไคลเอนต์ต้องสามารถ ย้อนกลับและทำซ้ำ เมื่อเกิด การพยากรณ์ผิด ขึ้น เพื่อเปิดใช้งานสิ่งนี้ เขียนตรรกะหลักของคุณภายในฟังก์ชันที่ถูกผูกไว้ผ่าน RunService:BindToSimulation() ใน ModuleScript ที่เริ่มต้นทั้งบนไคลเอนต์และเซิร์ฟเวอร์

ในระหว่างการทำซ้ำ Roblox จะทำการเรียกใช้ฟังก์ชันที่ผูกไว้กับการจำลองผ่าน BindToSimulation() การประมวลผลข้อมูลนำเข้าสำหรับผู้เล่น, การโต้ตอบกับวัตถุฟิสิกส์ที่ถูกทำให้ซิงค์ และการอัปเดตสถานะของเกมหลักควรจะถูกเขียนอยู่ภายในฟังก์ชันที่ถูกผูกไว้เหล่านั้น
ModuleScript ที่ชื่อว่า Simulation ใน ReplicatedStorage:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Simulation = {}
Simulation.Initialize = function()
RunService:BindToSimulation(function(deltaTime)
-- อ่านข้อมูลนำเข้าสำหรับผู้เล่น
-- อัปเดตสถานะของเกม
end)
end
return Simulationการซิงค์สถานะด้วยแอตทริบิวต์
Roblox จะทำการซิงค์คุณสมบัติทั้งหมดที่มี การเข้าถึงการจำลอง กับอินสแตนซ์ที่ถูกคาดการณ์ สำหรับข้อมูลที่กำหนดเอง แอตทริบิวต์ เป็นวิธีหลักในการซิงค์อินสแตนซ์ที่ถูกทำเครื่องหมายว่าถูกคาดการณ์; ในอินสแตนซ์เหล่านั้น การไม่ตรงกันในค่าแอตทริบิวต์ระหว่างแหล่งข้อมูลที่มีอำนาจของเซิร์ฟเวอร์และการพยากรณ์ของไคลเอนต์จะทำให้เกิดการ ย้อนกลับและทำซ้ำ เต็มรูปแบบ
ข้อจำกัดของแอตทริบิวต์
เพื่อทำให้ถูกจำลอง คุณสมบัติต้องมีเงื่อนไขทั้งหมดต่อไปนี้:
- เป็นหนึ่งใน 64 แอตทริบิวต์แรกบน Instance ของมัน
- ชื่อของมันมีตัวอักษรสูงสุด 50 ตัว
- หากเป็นแอตทริบิวต์ประเภทสตริง ค่าในนั้นมีตัวอักษรสูงสุด 50 ตัว
การเข้าถึงการจำลอง
คุณสมบัติและเมธอดหลายรายการในเอกสาร API ของเอนจินจะมีฉลาก การเข้าถึงการจำลอง เช่น BasePart.CFrame คุณสมบัติที่มีฉลากนี้จะถูกคาดการณ์โดยระบบอำนาจของเซิร์ฟเวอร์ นอกจากนี้ คุณสมบัติและวิธีที่มีฉลากนี้เท่านั้นที่สามารถเข้าถึงได้ภายในฟังก์ชันที่ผูกไว้ด้วย RunService:BindToSimulation()
การดำเนินการนำเข้า
ในเกมที่มีอำนาจของเซิร์ฟเวอร์ วิธีหลักที่ไคลเอนต์จะมีผลต่อสถานะของเกมคือผ่าน ระบบการนำเข้าการกระทำ ข้อมูลนำเข้าเหล่านี้จะถูกส่งไปยังเซิร์ฟเวอร์และถูกเล่นซ้ำระหว่างการทำซ้ำบนไคลเอนต์ ด้วยเหตุนี้ InputActions จึงควรถูกใช้สำหรับ ข้อมูลนำเข้าทั้งหมดที่มีผลกระทบต่อการจำลองหลัก และควรจะถูกตรวจสอบความถูกต้องก่อนที่จะถูกประมวลผล
โปรดทราบว่า InputContexts ต้องเป็นลูกของ Player เพื่อให้เอนจินรู้ว่าผู้ใดมีอำนาจเหนือ InputContext วิธีหนึ่งคือตั้ง InputContexts ไว้ในโฟลเดอร์ภายใต้ ReplicatedStorage และใช้ Script ที่อยู่ใต้ ServerScriptService เพื่อโคลน InputContexts สำหรับผู้เล่นแต่ละคน:

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โดยใช้รูปแบบนี้ คุณสามารถอ่าน InputActions สำหรับผู้เล่นทั้งหมดใน RunService:BindToSimulation() ทั้งในไคลเอนต์และเซิร์ฟเวอร์ เพื่อรับข้อมูลเดียวกันสำหรับเฟรมใดเฟรมหนึ่งและบันทึกข้อมูลนำเข้าของเฟรมก่อนหน้าใน แอตทริบิวต์ ตัวอย่างเช่นเพื่อกระตุ้นให้ตัวละครวิ่งเมื่อมีการกระทำ RunAction ที่ถูกกระตุ้น
อีเวนต์ระยะไกล
อีเวนต์ระยะไกล ยังสามารถใช้งานได้ในโมเดลอำนาจของเซิร์ฟเวอร์เพื่อให้การสื่อสารที่แตกต่างกันระหว่างไคลเอนต์และเซิร์ฟเวอร์ ตัวอย่างเช่น เซิร์ฟเวอร์สามารถใช้อีเวนต์ระยะไกลในการกระจายข้อมูลเกี่ยวกับผู้เล่นที่ทำคะแนนได้หรือเก็บวัตถุ ไคลเอนต์สามารถใช้อีเวนต์ระยะไกลเป็น API ทางเลือกในการส่งข้อมูลนำเข้าไปยังเซิร์ฟเวอร์ เช่น สำหรับการกดปุ่มหรือการแตะวัตถุในโลก 3D
แอนิเมชั่น, เสียง และเอฟเฟค
เอฟเฟคที่ทำจากฝั่งไคลเอนต์ เช่น แอนิเมชั่นและเสียงต้องถูกเขียนโดยรู้ว่าการจำลองของไคลเอนต์เป็นเพียงการพยากรณ์สถานะที่มีอำนาจของเซิร์ฟเวอร์ BindToSimulation() จะจำกัดสิ่งที่คุณสมบัติและวิธีการที่สามารถถูกเรียกจากฟังก์ชันที่ผูกไว้นั้นเพื่อช่วยชี้นำให้คุณเขียนไปยังสถานะการจำลองที่ซิงค์เท่านั้น การแสดงผลของผลลัพธ์ของการจำลอง ทริกเกอร์เอฟเฟคและเสียง เป็นต้น ควรทำในฟังก์ชันแยกต่างหากที่เชื่อมโยงกับ RenderStepped ซึ่งอ่านผลลัพธ์ของการจำลองและทริกเกอร์เอฟเฟคที่ต้องการ
แนวทางเพิ่มเติมเกี่ยวกับการเรนเดอร์การจำลองที่พยากรณ์จะครอบคลุมในคำแนะนำ เทคนิคขั้นสูง
โครงการตัวอย่าง
นอกเหนือจากเอกสารนี้ เทมเพลตต่อไปนี้อาจช่วยให้คุณเริ่มต้นได้:


