서버 권한 모델

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

서버 권한 모델에서는 서버가 전체 게임 상태의 유일한 진실의 출처이며, 클라이언트는 자신의 입력을 보고하는 것만 신뢰합니다. 이 아키텍처는 클라이언트가 자신의 위치나 상태를 보고하는 것을 신뢰하지 않으므로, 플라이핵 또는 스피드핵과 같은 모든 종류의 치트를 방지하기 때문에 공정하고 경쟁적인 게임의 핵심 네트코드 기반이 됩니다.

장점

단순한 서버 소유 시스템에서는 클라이언트가 자신의 입력을 서버에 보내고 서버가 다시 전송한 게임 결과를 표시합니다. 기술적으로 올바르긴 하지만, 이런 시스템은 모든 플레이어의 행동이 서버로 전송되고 처리된 후 결과가 클라이언트로 다시 전송되어야 하기 때문에 상당한 입력 지연에 직면하게 됩니다. 대부분의 게임, 특히 빠르게 진행되는 게임에서는 이 왕복 지연으로 인해 게임플레이가 지연되고 반응이 느리며 플레이할 수 없게 됩니다.

Roblox의 서버 권한 모델에서는 클라이언트가 입력을 서버에 보냄과 동시에 즉시 예측하여 입력의 효과를 보완합니다. 예를 들어, 플레이어가 키를 누르면 클라이언트는 서버의 응답을 기다리지 않고 마지막으로 알려진 서버 상태보다 몇 프레임 앞서서 예측합니다. 이를 통해 클라이언트는 입력 행동의 결과를 즉시 표시할 수 있어 네트워크 지연을 효과적으로 숨기고 게임이 반응적인 느낌을 줍니다.

때때로 클라이언트는 예측을 잘못할 수 있으며 (잘못된 예측) 네트워크 지연으로 인해 클라이언트는 몇 프레임 동안 자신이 실수했음을 알지 못합니다. 예를 들어:

잘못된 예측이 감지되면 클라이언트는 서버의 권위 있는 상태를 기반으로 예측을 수정해야 합니다. 권위 있는 상태가 클라이언트의 예측된 상태와 다르다면 클라이언트는 롤백 및 재시뮬레이션하여 예측된 프레임을 수정해야 합니다. 클라이언트 측 예측, 롤백 및 재시뮬레이션 시스템은 "지연 보상"이라고 하며 서버 권한 멀티플레이어 게임이 부드럽고 반응적으로 느껴지도록 도와줍니다.

설정

서버 권한 모델이 제대로 작동하기 위해서는 몇 가지 엔진 기술이 필요하므로, 우선 Explorer에서 Workspace 객체에 다음 속성을 설정해야 합니다:

  1. Workspace.NextGenerationReplication이 활성화되어야 합니다.
  2. Workspace.PlayerScriptsUseInputActionSystem이 활성화되어야 합니다.
  3. Workspace.UseFixedSimulation이 활성화되어야 합니다.
  4. Workspace.StreamingEnabled이 활성화되어야 합니다.
  5. Workspace.AuthorityModeServer여야 합니다 (위의 모든 항목이 먼저 설정되어야 합니다).

개념

서버 권한 시스템은 다음과 같은 몇 가지 핵심 개념에서 작동합니다.

클라이언트 예측

클라이언트 예측을 통해 클라이언트는 마지막으로 알려진 서버 상태보다 몇 프레임 앞서서 플레이어 입력의 효과를 즉시 예측합니다. 이는 입력 지연을 숨기지만, 예측이 나중에 잘못될 수 있으며 (클라이언트 잘못된 예측) 수정이 필요할 수 있습니다. 클라이언트는 입력이 서버에 의도된 프레임에서 도착할 수 있도록 마지막으로 알려진 권위 있는 서버 상태보다 멀리 예측하지 않도록 노력합니다. 클라이언트가 알려진 서버 상태보다 예측하는 프레임 수는 클라이언트와 서버 사이의 지연에 따라 다릅니다.

클라이언트 잘못된 예측

클라이언트가 서버로부터 권위 있는 상태를 받을 때, 해당 상태를 자신이 로컬에서 예측한 과거 기록과 비교합니다. 클라이언트가 예측한 내용과 서버가 실제로 한 내용 사이에 차이가 있는 경우, 이는 잘못된 예측입니다. 잘못된 예측은 네트워크 지연의 변화, 클라이언트가 예상하지 못한 방식으로 행동하는 다른 플레이어, 서버에서만 특정 로직을 실행하는 게임 등 여러 이유로 발생할 수 있습니다.

권위 있는 상태가 클라이언트의 예측된 상태와 다를 경우 클라이언트는 롤백 및 재시뮬레이션을 수행해야 합니다.

롤백 및 재시뮬레이션

클라이언트가 잘못된 예측을 감지하면, 서버의 권위 있는 상태로 리셋한 다음 리셋된 상태에서 자신의 예측 프레임으로 점프하기 위해 재시뮬레이션해야 합니다. 네트워크 지연에 따라 클라이언트는 마지막으로 알려진 권위 있는 서버 상태보다 멀리 예측하지 않도록 노력합니다.

위의 다이어그램에서 클라이언트는 서버보다 2프레임 앞서 시뮬레이션하고 있습니다. 클라이언트는 프레임 3의 입력을 전송하고, 이는 서버에서 의도된 프레임(3)에 도착합니다. 서버는 프레임 3에 대한 권위 있는 상태를 전송하고, 클라이언트는 프레임 7에서 이를 수신합니다. 클라이언트는 프레임 3을 잘못 예측했음을 발견하므로 서버의 프레임 3으로 롤백하고 프레임 4, 5 및 6을 재시뮬레이션한 후 프레임 7을 시뮬레이션합니다. 플레이어는 갑작스러운 움직임과 같은 눈에 띄는 네트워크 인공물을 볼 수 있습니다.

요약하자면, 클라이언트는:

  1. 서버로부터 권위 있는 상태를 수신하고 이를 자신의 예측 상태와 비교합니다.
  2. 클라이언트의 예측이 잘못된 경우:
    1. 클라이언트는 서버로부터 받은 마지막 알려진 권위 있는 상태로 롤백합니다.
    2. 클라이언트는 권위 있는 상태에서 예측 상태로 재시뮬레이션하여 모든 로컬 입력을 다시 적용합니다.

구현

네트워크 소유권 및 예측

서버 권한 모델에서는 클라이언트가 서버 소유의 핵심 게임플레이 객체를 입력 지연 비용 없이 유지할 수 있습니다. 자동차, 플레이어 캐릭터 또는 기타 게임플레이에 중요한 객체들은 다른 플레이어와 상호작용할 때에도 서버 소유 상태를 유지할 수 있습니다.

기본적으로 Roblox는 로컬 플레이어의 Character 근처에서 시뮬레이션 접근 속성을 자동으로 예측합니다. 그러나 더 세밀한 제어가 필요하다면 RunService:SetPredictionMode()를 사용하여 인스턴스의 예측을 강제로 켜거나 끌 수 있습니다.

시뮬레이션 동기화

서버 권한 모델에서 클라이언트와 서버 모두 핵심 시뮬레이션을 실행해야 하며, 클라이언트의 시뮬레이션은 롤백 및 재시뮬레이션을 수행할 수 있어야 합니다. 이를 위해서는 RunService:BindToSimulation()을 통해 바인딩된 함수 안에 핵심 로직을 작성해야 하는 ModuleScript 내에서 클라이언트와 서버 모두 초기화해야 합니다.

서버 권한 설정

재시뮬레이션 중에 Roblox는 BindToSimulation()을 통해 시뮬레이션에 바인딩된 함수를 다시 실행합니다. 플레이어 입력 처리, 동기화된 물리 객체와의 상호작용 및 핵심 게임 상태 업데이트는 이러한 바인딩된 함수 내에서 실행되어야 합니다.

ModuleScript 이름이 SimulationReplicatedStorage에:

Simulation

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Simulation = {}
Simulation.Initialize = function()
RunService:BindToSimulation(function(deltaTime)
-- 플레이어 입력 읽기
-- 게임 상태 업데이트
end)
end
return Simulation

속성을 통한 상태 동기화

Roblox는 예측된 인스턴스의 시뮬레이션 접근을 가진 모든 속성을 자동으로 동기화합니다. 사용자 정의 데이터의 경우, 속성은 예측된 인스턴스를 동기화하는 기본 방법이며, 이러한 인스턴스에서 서버의 진실의 출처와 클라이언트의 예측 값 간의 속성 값 불일치가 발생하면 전체 롤백 및 재시뮬레이션이 발생합니다.

속성 제한

속성이 복제되기 위해서는 다음 모든 기준을 충족해야 합니다:

  • 해당 Instance의 첫 64개 속성 중 하나여야 합니다.
  • 이름이 최대 50자여야 합니다.
  • 문자열 유형 속성인 경우 값이 최대 50자여야 합니다.

시뮬레이션 접근

엔진 API 참조의 많은 속성과 메서드에는 시뮬레이션 접근 레이블이 포함되어 있으며, 예를 들어 BasePart.CFrame이 있습니다. 이 레이블이 있는 속성은 서버 권한 시스템에 의해 예측됩니다. 또한, 이 레이블이 있는 속성과 메서드만 RunService:BindToSimulation()을 통해 바인딩된 함수 내에서 액세스할 수 있습니다.

입력 동작

서버 권한 게임에서 클라이언트가 게임 상태에 영향을 미치는 주요 방법은 입력 작업 시스템을 통한 것입니다. 이러한 입력은 서버로 전송되며 클라이언트에서 재시뮬레이션 중에 재생됩니다. 따라서 InputActions핵심 시뮬레이션에 영향을 미치는 모든 입력에 사용되어야 하며, 처리되기 전에 건전성 검사를 수행해야 합니다.

InputContexts는 엔진이 InputContext에 대한 소유권이 누구에게 있는지 알 수 있도록 Player의 자손이어야 합니다. 한 가지 접근 방식은 ReplicatedStorage의 하위 폴더에 InputContexts를 추가하고 ServerScriptService 하위에 Script를 사용하여 플레이어마다 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

이 패턴을 사용하면 클라이언트와 서버의 RunService:BindToSimulation()에서 모든 플레이어에 대해 InputActions를 읽어 동일한 프레임에 대한 데이터를 수신하고 이전 프레임의 입력을 속성에 기록할 수 있습니다. 예를 들어 RunAction 입력 작업이 트리거될 때 캐릭터 실행을 트리거할 수 있습니다.

사용자 정의 데이터를 입력 작업 시스템에 기록해야 할 경우, RunService.RenderStepped 또는 RunService:BindToRenderStep()에 연결된 기능을 사용해야 하며, RunService:BindToSimulation()을 사용해서는 안 됩니다. RunService:BindToSimulation()에서 InputAction을 발생시키면 클라이언트가 재시뮬레이션 중에 잘못된 결과를 출력할 수 있습니다.


local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
RunService:BindToRenderStep("CameraInput", Enum.RenderPriority.Last.Value, function()
-- 클라이언트 카메라의 전방 벡터를 입력 작업을 통해 서버에 보냄
local cameraForwardInputAction = Players.LocalPlayer.PlayContext.CameraForward
local cameraForwardVector = Workspace.CurrentCamera.CFrame.LookVector
cameraForwardInputAction:Fire(cameraForwardVector)
end)

원격 이벤트

원격 이벤트는 서버 권한 모델 내에서 클라이언트와 서버 간의 개별적인 통신을 facilitate하기 위해 여전히 사용할 수 있습니다. 예를 들어 서버는 원격 이벤트를 사용하여 플레이어가 점수를 얻거나 물체를 수집하는 데이터에 대해 방송할 수 있으며, 클라이언트는 원격 이벤트를 서버에 입력을 보내기 위한 대체 API로 사용할 수 있습니다. 예를 들어 버튼 클릭이나 3D 세계에서 물체를 두드릴 때 사용할 수 있습니다.

애니메이션, 소리 및 효과

클라이언트 측 효과인 애니메이션과 소리는 클라이언트 시뮬레이션이 권위 있는 서버 상태의 단순한 예측일 뿐임을 인지한 상태로 작성되어야 합니다. BindToSimulation()은 바인딩된 함수 내에서 호출할 수 있는 속성 및 메서드를 제한하여 동기화된 시뮬레이션 상태에만 작성하도록 안내합니다. 이 시뮬레이션의 결과를 표시하고 효과 및 소리를 트리거하는 등의 작업은 시뮬레이션 결과를 읽고 원하는 효과를 트리거하는 RenderStepped에 연결된 별도의 함수에서 수행해야 합니다.

예측된 시뮬레이션을 렌더링하는 데 대한 추가 지침은 고급 기술 가이드에서 다룹니다.

예제 프로젝트

이 문서 외에도 다음 템플릿이 시작하는 데 도움이 될 수 있습니다:

레이싱
축구
레이저 태그
©2026 Roblox Corporation. Roblox 및 Roblox 로고, 'Powering Imagination'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.