In einem Server-Autoritätsmodell ist der Server die einzige Wahrheitsquelle für den gesamten Spielzustand, und Clients werden nur vertraut, ihre eigenen Eingaben zu melden. Diese Architektur ist das Kern-Netzcodefundament eines fairen, wettbewerbsorientierten Spiels, da sie ganze Klassen von Betrug wie Flyhacks oder Speedhacks verhindert, indem sie niemals einem Client vertraut, seine eigene Position oder seinen Zustand zu melden.
Vorteile
In einem naiven serverbesessenen System würden Clients einfach ihre Eingaben an den Server senden und die Ergebnisse des Spiels anzeigen, die vom Server zurückgesendet werden. Während dies technisch korrekt ist, würde ein solches System erhebliche Eingabeverzögerungen aufweisen, da jede Spieleraktion zum Server reisen, verarbeitet werden und das Ergebnis an den Client zurückgesendet werden müsste, bevor es angezeigt werden kann. Für die meisten Spiele, insbesondere für solche mit schnellem Tempo, würde diese Hin- und Rückreiseverzögerung dazu führen, dass das Gameplay träge, unresponsive und unspielbar erscheint.
Im Server-Autoritätsmodell von Roblox wird die Latenz kompensiert, indem Clients sofort die Auswirkungen ihrer Eingaben vorhersagen, zusätzlich zu dem, was sie an den Server senden. Wenn ein Spieler beispielsweise eine Taste drückt, wartet der Client nicht auf die Antwort des Servers; stattdessen vorhersagt er einige Frames vor dem letzten bekannten Serverzustand. Dies ermöglicht es dem Client, das Ergebnis der Eingabeaktion sofort anzuzeigen, wodurch die Netzwerkverzögerung effektiv verborgen wird und das Spiel reaktionsschnell erscheint.
Manchmal wird die Vorhersage des Clients falsch sein (Fehlvorhersage), und aufgrund der Netzwerkverzögerung wird der Client nicht wissen, dass er einen Fehler gemacht hat, bis einige Frames vergangen sind. Zum Beispiel:
Wenn eine Fehlvorhersage erkannt wird, muss der Client seine Vorhersage basierend auf dem autoritiven Zustand des Servers korrigieren. Wenn der autoritative Zustand sich vom vorhergesagten Zustand des Clients unterscheidet, muss der Client zurückrollen und neu simulieren. Dieses System der clientseitigen Vorhersage, des Zurückrollens und der Neusimulation wird als "Latenzkompensation" bezeichnet und hilft, serverautorisierte Mehrspieler-Spiele reibungslos und reaktionsschnell zu gestalten.
Einrichtung
Das Server-Autoritätsmodell erfordert bestimmte andere Engine-Technologien, um korrekt zu funktionieren. Bestätigen Sie die folgenden Eigenschaften auf dem Workspace-Objekt im Explorer:
- Workspace.AuthorityMode muss Server sein (dieses Setting setzt automatisch die folgenden fünf).
- Workspace.NextGenerationReplication muss aktiviert sein.
- Workspace.PlayerScriptsUseInputActionSystem muss aktiviert sein.
- Workspace.SignalBehavior muss Deferred sein.
- Workspace.UseFixedSimulation muss aktiviert sein.
- Workspace.StreamingEnabled muss aktiviert sein.
Konzepte
Das Server-Autoritätssystem basiert auf einigen Kernkonzepten, wie folgt.
Client-Vorhersage
Durch Client-Vorhersage simuliert der Client einige Frames vor dem letzten bekannten Serverzustand, um die Auswirkungen der Eingaben der Spieler sofort vorherzusagen. Dies verbirgt die Eingabeverzögerung, aber die Vorhersage kann sich später als falsch herausstellen (Client-Fehlvorhersage) und muss daher korrigiert werden. Der Client versucht, nur so weit vor dem letzten bekannten autoritativen Serverzustand zu simulieren, dass seine Eingaben zum beabsichtigten Frame auf dem Server ankommen. Die Anzahl der Frames, die der Client vor dem bekannten Serverzustand vorhersagt, basiert auf der Latenz zwischen Client und Server.
Client-Fehlvorhersage
Wenn der Client den autoritativen Zustand vom Server erhält, überprüft er diesen Zustand gegen einen historischen Datensatz dessen, was er lokal für diesen Frame vorhergesagt hat. Wenn es einen Unterschied zwischen dem gibt, was der Client vorhergesagt hat und was der Server tatsächlich getan hat, handelt es sich um eine Fehlvorhersage. Fehlvorhersagen können aus verschiedenen Gründen auftreten, einschließlich Änderungen in der Netzwerkverzögerung, andere Spieler, die sich auf Weisen verhalten, die der Client nicht vorhergesehen hat, das Spiel, das bestimmte Logik ausschließlich auf dem Server ausführt, usw.
Wenn der autoritative Zustand sich vom vorhergesagten Zustand des Clients unterscheidet, muss der Client zurückrollen und neu simulieren.
Zurückrollen und neu simulieren
Wenn ein Client eine Fehlvorhersage erkennt, muss er auf den autoritativen Zustand des Servers zurücksetzen und dann neu simulieren, um zum vorhergesagten Frame zurückzuspringen. Basierend auf der Netzwerkverzögerung versucht der Client, nur so weit vor dem letzten bekannten autoritativen Serverzustand zu simulieren, dass seine Eingaben zum beabsichtigten Frame auf dem Server ankommen.
Zusammenfassend:
- Der Client:
- Empfängt den autoritiven Zustand vom Server und vergleicht ihn mit seinem eigenen vorhergesagten Zustand.
- Wenn die Vorhersage des Clients falsch war:
- Der Client rollt auf den letzten bekannten autoritativen Zustand zurück, der vom Server empfangen wurde.
- Der Client simuliert vom autoritativen Zustand zu seinem vorhergesagten Zustand neu und wendet alle lokalen Eingaben erneut an.
Implementierung
Netzwerkbesitz und Vorhersage
Im Server-Autoritätsmodell können Sie die Kernspielobjekte serverbesessen halten, ohne die normalerweise mit dem Serverbesitz verbundenen Eingabeverzögerungen zu erleiden. Dinge wie Autos, Spielercharaktere oder andere spielkritische Objekte können serverbesessen bleiben, selbst wenn sie mit anderen Spielern interagieren.
Standardmäßig wird Roblox automatisch Eigenschaften mit Simulationszugriff in der Nähe des lokalen Spielers Character vorhersagen, aber wenn Sie mehr Kontrolle wünschen, können Sie die Vorhersage eines Instanz explizit mit RunService:SetPredictionMode() aktivieren oder deaktivieren.
Die automatische Vorhersage gilt für ganze Physikbaugruppen, nicht für einzelne Instanzen. Wenn der Client ein Teil vorhersagt, sagt er auch jedes Teil voraus, das physisch über Schweißnähte, Gelenke oder Einschränkungen mit ihm verbunden ist, zusammen mit dem übergeordneten Model dieser Teile und jedem Humanoid innerhalb dieses Modells. Zum Beispiel:
- Ein Schwertmodell, das an einen vorhergesagten Charakter geschweißt ist, wird Teil der Baugruppe des Charakters, sodass es automatisch vorhergesagt wird.
- Ein Modell, das dem Charakter zugeordnet ist, aber nicht physisch mit ihm verbunden ist, ist eine separate Baugruppe. Es wird nur vorhergesagt, wenn es sich innerhalb des Simulationsradius des Clients befindet oder wenn Sie die Vorhersage mit RunService:SetPredictionMode() aktivieren.
Um zu überprüfen, ob eine bestimmte Instanz derzeit vorhergesagt wird, rufen Sie RunService:GetPredictionStatus() vom Client aus auf.
Simulationssynchronisation
Im Server-Autoritätsmodell müssen sowohl der Client als auch der Server die Kernsimulation ausführen, und die Simulation des Clients muss in der Lage sein, zurückzurollen und neu zu simulieren, wenn eine Fehlvorhersage auftritt. Um dies zu ermöglichen, schreiben Sie Ihre Kernlogik in Funktionen, die über RunService:BindToSimulation() in einem ModuleScript gebunden sind, das sowohl auf dem Client als auch auf dem Server initialisiert wird.

Während einer Neusimulation wird Roblox die an die Simulation gebundenen Funktionen über BindToSimulation() erneut ausführen. Die Verarbeitung von Spieler-Eingaben, die Interaktion mit synchronisierten Physikobjekten und die Aktualisierung des Kernspielzustands sollten innerhalb dieser gebundenen Funktionen erfolgen.
Verwenden Sie time() für zeitbasierte Logik innerhalb einer gebundenen Simulationsfunktion, wie das Steuern einer Animationsgeschwindigkeit oder das Oszillieren eines Wertes über die Zeit. Wenn Workspace.AuthorityMode Enum.AuthorityMode.Server ist, wird time() zwischen Client und Server synchronisiert und verwendet eine feste Simulationszeit. Während der Neusimulation wird auf den autoritativen Frame zurückgespult und vorangetrieben, während der Client Frames erneut abspielt, sodass bei jeder simulierten Frame ein konsistenter Wert zurückgegeben wird.
ModuleScript mit dem Namen Simulation in ReplicatedStorage:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Simulation = {}
Simulation.Initialize = function()
RunService:BindToSimulation(function(deltaTime)
-- Spieler-Eingaben lesen
-- Spielzustand aktualisieren
end)
end
return SimulationZustandsynchronisation mit Attributen
Roblox synchronisiert automatisch alle Eigenschaften mit Simulationszugriff auf vorhergesagten Instanzen. Für benutzerdefinierte Daten sind Attribute der primäre Weg, um Instanzen zu synchronisieren, die als vorhergesagt markiert sind; bei solchen Instanzen wird jede Abweichung in den Attributwerten zwischen der autoritativen Quelle des Servers und der Vorhersage des Clients eine vollständige Rückkehr und Neusimulation auslösen.
Attributgrenzen
Um repliziert zu werden, muss ein Attribut alle folgenden Kriterien erfüllen:
- Es gehört zu den ersten 64 Attributen auf seiner Instance.
- Sein Name enthält höchstens 50 Zeichen.
- Wenn es sich um ein Attribut vom Typ String handelt, enthält sein Wert höchstens 50 Zeichen.
Simulationszugriff
Viele Eigenschaften und Methoden in der Engine-API-Referenz enthalten das Simulationszugriff-Label, zum Beispiel BasePart.CFrame. Eigenschaften mit diesem Label werden vom Server-Autoritätssystem vorhergesagt. Darüber hinaus können nur Eigenschaften und Methoden mit diesem Label innerhalb von Funktionen aufgerufen werden, die mit RunService:BindToSimulation() gebunden sind.
Instanzen erstellen und entfernen
Innerhalb von Funktionen, die über BindToSimulation() gebunden sind, können Sie Instanzen mit Instance.new(), Instance:Clone() oder Instance.fromExisting() erstellen. Der Client erstellt die Instanz sofort, und Roblox fügt sie mit der autoritativen Kopie des Servers zusammen, wenn diese Kopie ankommt. Für Details siehe vorhersagende Instanzenerstellung.
Das Entfernen von Instanzen funktioniert anders. Instance:Destroy() hat keinen Simulationszugriff, und Sie können die Parent einer Instanz, die sich bereits im DataModel befindet, nicht ändern, sodass das Aufrufen von entweder innerhalb einer gebundenen Funktion einen Fehler verursacht. Stattdessen zeichnen Sie die Absicht auf, eine Instanz in einem Attribut innerhalb der Simulation zu entfernen, und entfernen Sie die Instanz außerhalb der Simulation, z. B. in einer PostSimulation-Verbindung auf dem Server.
local RunService = game:GetService("RunService")
local character = script.Parent
RunService.PostSimulation:Connect(function()
-- "SwordEquipped" wird von der Simulation geschrieben, wenn der Spieler das Schwert ablegt
local sword = character:FindFirstChild("Sword")
if sword and not character:GetAttribute("SwordEquipped") then
sword:Destroy()
end
end)Eingabeaktionen
In einem serverautoritiven Spiel ist der primäre Weg für einen Client, den Zustand des Spiels zu beeinflussen, über das Input Action System. Diese Eingaben werden an den Server gesendet und während der Neusimulation auf dem Client wiederholt. Daher sollten InputActions für alle Eingaben, die die Kernsimulation beeinflussen, verwendet werden, und sie sollten vor der Verarbeitung auf ihre Gültigkeit überprüft werden.
Beachten Sie, dass InputContexts ein Nachkomme von Player sein muss, damit die Engine weiß, wer das Eigentum über den InputContext hat. Ein Ansatz besteht darin, Ihre InputContexts in einen Ordner unter ReplicatedStorage hinzuzufügen und ein Script unter ServerScriptService zu verwenden, um die InputContexts pro Spieler zu klonen:

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)
endMit diesem Muster können Sie InputActions für alle Spieler in RunService:BindToSimulation() sowohl auf dem Client als auch auf dem Server lesen, um die gleichen Daten für einen bestimmten Frame zu erhalten und die Eingaben des vorherigen Frames in einem Attribut aufzuzeichnen, um beispielsweise einen Charakterlauf auszulösen, wenn eine RunAction-Eingabeaktion ausgelöst wird.
Remote-Events
Remote-Events können weiterhin innerhalb des Server-Autoritätsmodells verwendet werden, um diskrete Kommunikation zwischen Client und Server zu erleichtern. Zum Beispiel können Server Remote-Events verwenden, um Daten über Spieler zu übertragen, die Punkte erzielen oder Objekte aufheben, und Clients können Remote-Events als alternative API verwenden, um Eingaben an den Server zu senden, z. B. für Tastendrucke oder das Antippen von Objekten in der 3D-Welt.
Animationen
Animationen, die das Gameplay beeinflussen, wie Charakterbewegungen oder Angriffsanimationen, sollten innerhalb von Funktionen gesteuert werden, die über BindToSimulation() in demselben ModuleScript gebunden sind, das sowohl auf dem Client als auch auf dem Server ausgeführt wird. Kernmitglieder von Animator und AnimationTrack, wie LoadAnimation(), Play(), Stop(), AdjustSpeed() und TimePosition haben Simulationszugriff.
Der Animationszustand ist Teil der vorhergesagten Simulation. Wenn während einer Rückkehr eine Animation auftritt, spult der Client die Animation auf den autoritativen Zustand zurück und spielt sie zusammen mit dem Rest der Simulation erneut ab, sodass die Animationen von Client und Server synchron bleiben. Da der Client während einer Rückkehr Animationsspuren ersetzen kann, cachen Sie keine AnimationTrack-Referenzen über Frames hinweg. Suchen Sie stattdessen bei jedem Frame die aktuelle Spur mit Animator:GetTrackByAnimationId(). Für ein vollständiges Beispiel siehe Animationscode schreiben.
Geräusche und Effekte
Clientseitige Effekte wie Geräusche und Partikel müssen so geschrieben werden, dass der Client-Simulation lediglich eine Vorhersage des autoritativen Serverzustands ist. BindToSimulation() beschränkt, welche Eigenschaften und Methoden innerhalb gebundener Funktionen aufgerufen werden können, um Ihnen zu helfen, nur auf den synchronisierten Simulationszustand zu schreiben. Die Ergebnisse dieser Simulation anzuzeigen, Effekte und Geräusche auszulösen usw. sollten in einer separaten Funktion erfolgen, die mit RenderStepped verbunden ist und die Ergebnisse der Simulation liest und die gewünschten Effekte auslöst.
Da der Client möglicherweise ein Ereignis vorhersagt, das auf dem Server niemals eintritt, sollte Ihr Rendering-Code in der Lage sein, fehlvorhergesagte Effekte rückgängig zu machen oder zu verbergen. Weitere Hinweise zur Darstellung einer vorhergesagten Simulation finden Sie in Geräusche und visuelle Effekte abspielen.
Beispielprojekte
Neben dieser Dokumentation können die folgenden Vorlagen Ihnen helfen, den Einstieg zu erleichtern:


