โมเดลอำนาจของเซิร์ฟเวอร์

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

ใน โมเดลอำนาจของเซิร์ฟเวอร์ เซิร์ฟเวอร์เป็น แหล่งที่มาของความจริง เพียงแหล่งเดียวสำหรับสถานะของเกมทั้งหมด และไคลเอนต์จะได้รับการไว้วางใจเพียงแค่รายงานการป้อนข้อมูลของตนเองเท่านั้น สถาปัตยกรรมนี้เป็นพื้นฐานของเน็ตโค้ดที่เล็งไปที่เกมแข่งขันที่ยุติธรรม เนื่องจากมันป้องกันไม่ให้เกิดการโกงรูปแบบต่างๆ เช่น flyhacks หรือ speedhacks โดยไม่ไว้วางใจให้ไคลเอนต์รายงานตำแหน่งหรือลักษณะของตนเอง

ข้อดี

ในระบบที่มีเจ้าของเซิร์ฟเวอร์อย่างหยาบๆ ไคลเอนต์จะส่งการป้อนข้อมูลไปยังเซิร์ฟเวอร์และแสดงผลลัพธ์ของเกมที่ส่งกลับโดยเซิร์ฟเวอร์ ในขณะที่ถูกต้องในทางเทคนิค แต่ระบบเช่นนี้จะเผชิญกับ การหน่วงเวลาในการป้อนข้อมูล อย่างมากเนื่องจากการกระทำของผู้เล่นทุกคนจะต้องเดินทางไปยังเซิร์ฟเวอร์ ถูกประมวลผล และส่งกลับไปยังไคลเอนต์ก่อนที่จะสามารถแสดงผลได้ สำหรับเกมส่วนใหญ่ โดยเฉพาะเกมที่มีความเร็วสูง การหน่วงเวลาในการเดินทางนี้อาจทำให้การเล่นรู้สึกช้า ไม่ตอบสนอง และไม่สามารถเล่นได้

ใน โมเดลอำนาจของเซิร์ฟเวอร์ ของ Roblox การหน่วงเวลาจะถูกชดเชยโดยการทำให้ไคลเอนต์คาดการณ์ผลของการป้อนข้อมูลของพวกเขาในทันที predict พร้อมกับส่งไปยังเซิร์ฟเวอร์ ตัวอย่างเช่น เมื่อผู้เล่นกดปุ่ม ไคลเอนต์จะไม่รอให้เซิร์ฟเวอร์ตอบกลับ แต่จะ คาดการณ์ ไปข้างหน้าหลายเฟรมจากสถานะของเซิร์ฟเวอร์ที่ทราบล่าสุด สิ่งนี้ช่วยให้ไคลเอนต์แสดงผลของการกระทำการป้อนข้อมูลได้ทันที ช่วยซ่อนการหน่วงเวลาของเครือข่ายและทำให้เกมรู้สึกตอบสนอง

บางครั้งไคลเอนต์อาจคาดการณ์ผิด (misprediction) และเนื่องจากการหน่วงเวลาในเครือข่าย ไคลเอนต์จะไม่รู้ว่ามันทำผิดพลาดจนกว่าจะผ่านไปหลายเฟรม ตัวอย่างเช่น:

เมื่อตรวจพบการคาดการณ์ผิด ไคลเอนต์จะต้องแก้ไขการคาดการณ์ตาม สถานะที่มีอำนาจ ของเซิร์ฟเวอร์ หากสถานะที่มีอำนาจแตกต่างจากสถานะที่ไคลเอนต์คาดการณ์ไว้ ไคลเอนต์จะต้อง rollback and resimulate เฟรมที่คาดการณ์ของตน ระบบของการคาดการณ์โดยไคลเอนต์ การรีเซ็ต และการจำลองใหม่นี้เรียกว่า "การชดเชยการหน่วงเวลา" และช่วยให้เกมหลายผู้เล่นที่มีอำนาจจากเซิร์ฟเวอร์รู้สึกเรียบและตอบสนอง

การตั้งค่า

เมื่อโมเดลอำนาจของเซิร์ฟเวอร์ต้องการเทคโนโลยีอื่นๆ ของเอนจินบางอย่างให้ทำงานอย่างถูกต้อง คุณต้องตั้งค่าคุณสมบัติดังต่อไปนี้บนวัตถุ Workspace ใน Explorer:

  1. Workspace.NextGenerationReplication จะต้องถูกเปิดใช้งาน
  2. Workspace.PlayerScriptsUseInputActionSystem จะต้องถูกเปิดใช้งาน
  3. Workspace.SignalBehavior จะต้องเป็น Deferred
  4. Workspace.UseFixedSimulation จะต้องถูกเปิดใช้งาน
  5. Workspace.StreamingEnabled จะต้องถูกเปิดใช้งาน
  6. Workspace.AuthorityMode จะต้องเป็น Server (จำเป็นต้องตั้งค่าทั้งหมดข้างต้นก่อน)

แนวคิด

ระบบอำนาจของเซิร์ฟเวอร์ดำเนินการตามแนวคิดหลักไม่กี่ข้อดังนี้

การคาดการณ์ของไคลเอนต์

ผ่าน การคาดการณ์ของไคลเอนต์ ไคลเอนต์จะจำลองไปข้างหน้าหลายเฟรมจากสถานะเซิร์ฟเวอร์ที่ทราบล่าสุดเพื่อตอบสนองต่อผลของการป้อนข้อมูลของผู้เล่นในทันที สิ่งนี้จะซ่อนการหน่วงเวลาในการป้อนข้อมูล แต่การคาดการณ์อาจถูกค้นพบว่าผิดในภายหลัง (client misprediction) และดังนั้นจึงเรียกร้องให้มีการแก้ไข ไคลเอนต์พยายามจำลองไปข้างหน้าพอสมควรจากสถานะเซิร์ฟเวอร์ที่มีอำนาจล่าสุดเพื่อให้การป้อนข้อมูลของมันส่งถึงเซิร์ฟเวอร์ที่เฟรมที่ตั้งใจไว้ จำนวนเฟรมที่จะถูกคาดการณ์โดยไคลเอนต์จะขึ้นอยู่กับความหน่วงเวลาที่ย้อนหลังระหว่างไคลเอนต์และเซิร์ฟเวอร์

การคาดการณ์ผิดของไคลเอนต์

เมื่อไคลเอนต์ได้รับสถานะที่มีอำนาจจากเซิร์ฟเวอร์ มันจะตรวจสอบสถานะนั้นกับบันทึกประวัติว่ามันได้คาดการณ์ไว้ในท้องถิ่นสำหรับเฟรมนั้น เมื่อมีความแตกต่างระหว่างสิ่งที่ไคลเอนต์ คาดการณ์ กับสิ่งที่เซิร์ฟเวอร์ทำจริงๆ สิ่งนี้ถือเป็น การคาดการณ์ผิด การคาดการณ์ผิดอาจเกิดขึ้นจากหลายสาเหตุรวมถึงการเปลี่ยนแปลงในความหน่วงเวลาในเครือข่าย ผู้เล่นคนอื่นทำในลักษณะที่ไคลเอนต์ไม่คาดคิด เกมที่เรียกใช้ลอจิกเฉพาะบนเซิร์ฟเวอร์ ฯลฯ

หากสถานะที่มีอำนาจแตกต่างจากสถานะที่คาดการณ์ของไคลเอนต์ ไคลเอนต์จะต้อง rollback and resimulate.

การรีเซ็ตและการจำลองใหม่

เมื่อไคลเอนต์ตรวจพบ การคาดการณ์ผิด มันจะต้องรีเซ็ตให้ตรงกับสถานะที่มีอำนาจของเซิร์ฟเวอร์และจากนั้นจำลองใหม่เพื่อตั้งกลับไปยังเฟรมที่คาดการณ์ของตน ขึ้นอยู่กับความหน่วงเวลาในเครือข่าย ไคลเอนต์จะพยายามจำลองไปข้างหน้าให้พอดีจากสถานะเซิร์ฟเวอร์ที่มีอำนาจล่าสุดเพื่อให้การป้อนข้อมูลของมันส่งถึงเซิร์ฟเวอร์ที่เฟรมที่ตั้งใจไว้

ในแผนภาพด้านบน ไคลเอนต์กำลังจำลองไปข้างหน้า 2 เฟรมจากเซิร์ฟเวอร์ มันส่งการป้อนข้อมูลสำหรับเฟรม 3 ซึ่งมาถึงที่เฟรมที่ตั้งใจ (3) บนเซิร์ฟเวอร์ เซิร์ฟเวอร์ส่งสถานะที่มีอำนาจสำหรับเฟรม 3 และไคลเอนต์ได้รับมันที่เฟรม 7 ไคลเอนต์พบว่ามันคาดการณ์เฟรม 3 ผิด ดังนั้นมันจึงรีเซ็ตไปยังเฟรม 3 ของเซิร์ฟเวอร์และจำลองใหม่เฟรมที่ 4, 5 และ 6 ก่อนที่มันจะจำลองเฟรม 7 นักเล่นอาจเห็นอาร์ติแฟกต์เครือข่ายที่สังเกตเห็นได้ เช่น การเคลื่อนไหวที่เกิดขึ้นทันที

โดยสรุป ไคลเอนต์:

  1. รับ สถานะที่มีอำนาจ จากเซิร์ฟเวอร์และเปรียบเทียบกับ สถานะที่คาดการณ์ ของตนเอง
  2. หากการคาดการณ์ของไคลเอนต์ไม่ถูกต้อง:
    1. ไคลเอนต์จะรีเซ็ตไปยังสถานะที่มีอำนาจล่าสุดที่ได้รับจากเซิร์ฟเวอร์
    2. ไคลเอนต์จะจำลองใหม่จากสถานะที่มีอำนาจไปยังสถานะที่คาดการณ์ โดยการนำการป้อนข้อมูลในพื้นที่ใดๆ ที่นำกลับมาใช้ใหม่

การดำเนินการ

ความเป็นเจ้าของและการคาดการณ์เครือข่าย

ในโมเดลอำนาจของเซิร์ฟเวอร์ คุณสามารถเก็บวัตถุเกมหลักที่มีเจ้าของเซิร์ฟเวอร์โดยไม่ต้องใช้ต้นทุนการหน่วงเวลาในการป้อนข้อมูลซึ่งมักเกี่ยวข้องกับการมีเจ้าของเซิร์ฟเวอร์ สิ่งต่างๆ เช่น รถยนต์ ตัวละครของผู้เล่น หรือวัตถุที่มีความสำคัญต่อการเล่นสามารถคงอยู่ได้โดยมีเจ้าของเซิร์ฟเวอร์ แม้ว่าจะมีการโต้ตอบกับผู้เล่นคนอื่น

โดยค่าเริ่มต้น Roblox จะคาดการณ์คุณสมบัติด้วย การเข้าถึงการจำลอง โดยอยู่ใกล้กับผู้เล่นในท้องถิ่น Character แต่หากคุณต้องการควบคุมที่มีความละเอียดมากขึ้น คุณสามารถบังคับการคาดการณ์ของอินสแตนซ์โดยการเปิดหรือปิดด้วย RunService:SetPredictionMode().

การซิงค์การจำลอง

ในโมเดลอำนาจของเซิร์ฟเวอร์ ไคลเอนต์และเซิร์ฟเวอร์จะต้องดำเนินการจำลองหลัก และการจำลองของไคลเอนต์ต้องสามารถ rollback and resimulate ได้เมื่อเกิด การคาดการณ์ผิด เพื่อเปิดใช้งานสิ่งนี้ เขียนลอจิกพื้นฐานของคุณภายในฟังก์ชันที่ผูกผ่าน 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 จะซิงค์คุณสมบัติทั้งหมดที่มี การเข้าถึงการจำลอง บนอินสแตนซ์ที่คาดการณ์ได้โดยอัตโนมัติ สำหรับข้อมูลที่กำหนดเอง แอตทริบิวต์ เป็นวิธีหลักในการซิงค์อินสแตนซ์ที่ถูกทำเครื่องหมายว่าเป็นคาดการณ์ได้; บนอินสแตนซ์ดังกล่าว ทุกความไม่ตรงกันในค่าแอตทริบิวต์ระหว่างแหล่งที่มาของความจริงของเซิร์ฟเวอร์และการคาดการณ์ของไคลเอนต์จะก่อให้เกิด rollback and resimulation.

ข้อจำกัดของแอตทริบิวต์

เพื่อให้ถูกจำลอง บทแอตทริบิวต์ต้องตรงตามข้อกำหนดทั้งหมดต่อไปนี้:

  • ต้องอยู่ในบรรดาแอตทริบิวต์ 64 แรกใน Instance ของมัน
  • ชื่อของมันต้องมีความยาวไม่เกิน 50 ตัวอักษร
  • หากเป็นแอตทริบิวต์ประเภทสตริง ค่าของมันต้องมีความยาวไม่เกิน 50 ตัวอักษร

การเข้าถึงการจำลอง

คุณสมบัติและวิธีการหลายอย่างในเอนจิน API อ้างถึงป้าย การเข้าถึงการจำลอง ตัวอย่างเช่น BasePart.CFrame คุณสมบัติที่มีป้ายนี้จะถูกคาดการณ์โดยระบบอำนาจของเซิร์ฟเวอร์ นอกจากนี้เพียงแต่คุณสมบัติและวิธีที่มีป้ายนี้เท่านั้นที่สามารถเข้าถึงได้ภายในฟังก์ชันที่ผูกด้วย RunService:BindToSimulation().

การกระทำการป้อนข้อมูล

ในเกมที่มีอำนาจจากเซิร์ฟเวอร์ วิธีหลักที่ไคลเอนต์สามารถทำให้สถานะของเกมเปลี่ยนแปลงได้คือผ่าน ระบบการกระทำการป้อนข้อมูล การป้อนข้อมูลเหล่านี้จะถูกส่งไปยังเซิร์ฟเวอร์และถูกเล่นซ้ำระหว่างการจำลองใหม่บนไคลเอนต์ ดังนั้น InputActions ควรใช้สำหรับ การป้อนข้อมูลทั้งหมดที่มีผลกระทบต่อการจำลองหลัก และควรตรวจสอบให้แน่ใจว่าเป็นค่าใช้จ่ายก่อนที่จะถูกประมวลผล

โปรดทราบว่า InputContexts จะต้องเป็นลูกของ Player เพื่อให้เอนจินทราบว่าผู้ใดเป็นเจ้าของ InputContext หนึ่งในวิธีการคือการเพิ่ม InputContexts ของคุณไปยังโฟลเดอร์ใต้ ReplicatedStorage และใช้ Script ภายใต้ ServerScriptService เพื่อทำสำเนาของ InputContexts ต่อผู้เล่น:

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

โดยใช้รูปแบบนี้ คุณสามารถอ่าน InputActions สำหรับผู้เล่นทั้งหมดใน RunService:BindToSimulation() ทั้งในไคลเอนต์และเซิร์ฟเวอร์เพื่อลงบันทึกข้อมูลเดียวกันสำหรับเฟรมเดียวกัน และบันทึกป้อนข้อมูลของเฟรมก่อนหน้าใน แอตทริบิวต์ เช่นเพื่อกระตุ้นให้ตัวละครวิ่งเมื่อการกระทำ RunAction ถูกสร้างขึ้น

โปรดทราบว่าหากคุณต้องการเขียนข้อมูลกำหนดเองลงใน ระบบการกระทำการป้อนข้อมูล คุณควรใช้ฟังก์ชันที่เชื่อมต่อกับ RunService.RenderStepped หรือ RunService:BindToRenderStep() ไม่ใช่ RunService:BindToSimulation() การยิง InputAction ใน BindToSimulation() อาจทำให้ไคลเอนต์ผลิตผลลัพธ์ที่ไม่ถูกต้องในระหว่างการจำลองใหม่


local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
RunService:BindToRenderStep("CameraInput", Enum.RenderPriority.Last.Value, function()
-- ส่งเวกเตอร์ไปข้างหน้าของกล้องของไคลเอนต์ไปยังเซิร์ฟเวอร์ผ่าน InputAction
local cameraForwardInputAction = Players.LocalPlayer.PlayContext.CameraForward
local cameraForwardVector = Workspace.CurrentCamera.CFrame.LookVector
cameraForwardInputAction:Fire(cameraForwardVector)
end)

เหตุการณ์รีโมท

เหตุการณ์รีโมท ยังสามารถถูกใช้ภายในโมเดลอำนาจของเซิร์ฟเวอร์เพื่อช่วยให้การสื่อสารอย่างเลือกสรรระหว่างไคลเอนต์และเซิร์ฟเวอร์ ตัวอย่างเช่น เซิร์ฟเวอร์สามารถใช้เหตุการณ์รีโมทเพื่อกระจายข้อมูลเกี่ยวกับผู้เล่นที่ทำคะแนนหรือเก็บวัตถุ และไคลเอนต์สามารถใช้เหตุการณ์รีโมทเป็น API ทางเลือกในการส่งการป้อนข้อมูลไปยังเซิร์ฟเวอร์ เช่น สำหรับการกดปุ่มหรือการแตะวัตถุในโลก 3D

การเคลื่อนไหว เสียง และเอฟเฟกต์

เอฟเฟกต์ที่อยู่ด้านไคลเอนต์ เช่น การเคลื่อนไหวและเสียง จะต้องเขียนโดยรู้ว่าการจำลองของไคลเอนต์เป็นเพียงการคาดการณ์ของสถานะที่มีอำนาจจากเซิร์ฟเวอร์ BindToSimulation() จะจำกัดสิ่งที่คุณสมบัติและวิธีการสามารถเรียกใช้งานจากภายในฟังก์ชันที่ผูกไว้เพื่อช่วยแนะแนวให้คุณเขียนเฉพาะไปยังสถานะการจำลองที่ซิงค์ การแสดงผลลัพธ์ของการจำลองนี้ การกระตุ้นเอฟเฟกต์และเสียง ฯลฯ ควรทำในฟังก์ชันแยกที่เชื่อมต่อกับ RenderStepped ที่อ่านผลลัพธ์ของการจำลองและกระตุ้นเอฟเฟกต์ที่ต้องการ

คำแนะนำเพิ่มเติมเกี่ยวกับการแสดงการจำลองที่คาดการณ์ไว้นั้นอยู่ในคู่มือ เทคนิคขั้นสูง.

โครงการตัวอย่าง

นอกเหนือจากเอกสารนี้แล้ว เทมเพลตต่อไปนี้สามารถช่วยให้คุณเริ่มต้นได้:

การแข่งรถ
ฟุตบอล
เลเซอร์แท็ก
©2026 Roblox Corporation. Roblox, โลโก้ Roblox และ Powering Imagination เป็นส่วนหนึ่งของเครื่องหมายการค้าที่จดทะเบียน และไม่ได้จดทะเบียนของเราในสหรัฐฯ และประเทศอื่นๆ