멀티 플레이어 플랫 포머-일반적으로 서버의 단일 클라이언트에서 서버 수정이 필요합니까?


10

나는 현재 다소 단순한 멀티 플레이어 플랫 포머를 만들고 있습니다. 지연 시간을 숨기는 데 사용되는 기술에 대한 기사를 많이 읽었지만 여전히 특정 개념에 대해 이해하지 못했습니다. 주제가 매우 흥미롭고 아이디어를 직접 시도하는 것을 좋아하지만 gamedev stackexchange를 요청하는 것이 내 질문에 더 효율적이라고 생각합니다. 나는 현재 상황과 그 과정에서 어떤 질문이 생겼는지 설명하기 위해 최선을 다할 것입니다.

지금은 단일 플레이어 만 서버와 동기화하고 싶습니다. 이론적으로 클라이언트 측 예측을 가진 플레이어는 자신의 움직임에 영향을 미치는 외부 요인이 없기 때문에 서버 수정이 필요하지 않다고 가정했습니다. 따라서 제 프로토 타입은 현재 서버 수정없이 서버와 동기화 된 플레이어가 한 명뿐입니다.

게임 네트워킹에 익숙하다면 상황 섹션을 건너 뛸 수도 있지만 그 과정에서 잘못된 일이 있었을 수도 있습니다.

클라이언트 루프 (프레임 당 한 번, ~ 16.67ms마다 한 번씩)

단순화 된 클라이언트 루프는 다음과 같습니다.

  1. 로컬 입력 (WASD)을 확인하고 조치로 패키지하십시오 (예 :) Type=MoveLeft, Time=132.0902, ID=15. 패키지 된 작업은 나중에 보내도록 유지합니다. 또한 게임의 로컬 물리 시뮬레이션에 원하는 동작을 직접 적용합니다. 예를 들어 MoveLeft액션 이있는 경우 플레이어 속도에서 왼쪽으로 힘을가합니다.

  2. 조치를 보내려면 확인하십시오. 클라이언트 대역폭을 남용하지 않으려면 특정 간격 (예 : 30ms)으로 패키지 된 작업 만 보내십시오.

  3. 서버 수정 사항을 적용하십시오. 특정 시점에서 서버가 수신 한 델타 및 수정 사항을 처리하여 게임의 로컬 시뮬레이션에 적용합니다. 이 특정 질문에 대해서는 사용되지 않습니다.

  4. 로컬 물리를 업데이트합니다. 메인 플레이어에서 물리 루프를 실행하십시오. 기본적으로 이것은 플레이어의 움직임에 대한 클라이언트 측 예측을 수행합니다. 이것은 플레이어의 속도에 중력을 추가하고, 플레이어의 속도를 자신의 위치에 적용하고, 길을 따라 충돌을 수정합니다. .

물리학 및 기타 섹션에 대해서는 질문에 필요하지 않다고 생각하기 때문에 몇 가지 구체적인 세부 사항을 건너 뛰고 있지만 질문과 관련이 있는지 알려주십시오.

서버 루프 (15ms마다)

단순화 된 서버 루프는 다음과 같습니다.

  1. 조치를 처리하십시오. 클라이언트로부터받은 조치 패키지를 확인하여 서버 물리 시뮬레이션에 적용하십시오. 예를 들어 5 개의 MoveLeft동작을 수신 할 수 있으며 속도에 5 번 힘을가합니다 . 전체 액션 패키지는 액션이 발생하자마자 적용되는 클라이언트 에 대해 하나의 "프레임" 에서 실행된다는 점에 유의해야 합니다.

  2. 게임 로직을 업데이트하십시오. 우리는 게임 물리, 플레이어 이동 및 충돌 수정 등을 업데이트합니다. 또한 나중에 플레이어에게 전송되는 중요한 이벤트 (예 : 플레이어의 체력 저하, 플레이어 사망 등)도 패키지합니다.

  3. 수정 사항을 보내십시오. 우리는 정기적으로 (예 : 35ms마다) 최근에 다른 선수 (예 : 선수 위치, 건강 등)에 델타를 보냅니다. 이 부분은 현재 단일 플레이어의 시뮬레이션으로 클라이언트 및 서버에서 동일한 결과를 수정하지 않고 클라이언트 측 예측이 올바르게 작동하도록하기 위해 구현되지 않았습니다.

문제

현재 시스템은 간단한 상황에서 잘 작동하며 간단한 수평 이동으로 매우 유사한 결과를 얻었음을 기쁘게 생각합니다 (부정확도는 부동 소수점 정밀도 오류로 인한 것입니다).

간단한 충돌 / 움직임으로 동기화가 잘 작동합니다.

프로토 타입 그래픽은 무시하십시오. 흰색 사각형 = 플레이어, 빨간색 사각형 = 장애물, 파란색 = 배경

그러나 점프하고 고립 된 장애물에 가까이 이동하는 것과 같이 시간에 민감한 움직임을 한 후에 동기화 오류가 발생합니다.

시간에 민감한 순간에 지정된 장애물을 뛰어 넘었으므로 동기화가 작동하지 않습니다.

이론적으로, 나는 클라이언트가 자신의 입장에 영향을 미치는 외부 요인이 없기 때문에 둘 다 항상 동일한 결과로 끝날 것으로 기대합니다. 그러나 실제로는 문제를 이해한다고 생각합니다.

이와 같은 장애물을 뛰어 넘는 것은 플레이어의 타이밍에 따라 크게 달라 지므로, 속도가 위치에 적용될 의 작은 변화 는 결과에 영향을 줄 것입니다 (예 : 클라이언트가 서버는 나중에 전체 작업 패키지를 수신하고 소량의 시간 동안 장애물에 붙어있어 최종 결과를 변경하므로 서버가 수행합니다. 클라이언트와 서버가 처리하는 방법의 차이점은 주로 클라이언트가 발생하는 모든 작업을 수행하는 반면 서버는 수신하는 모든 작업을 대량으로 수행한다는 것입니다.

질문

이 긴 맥락은 마침내 내 질문에 이르게합니다 (이 글을 읽어 주셔서 감사합니다) : 서버와 동기화 된 플레이어가 하나 뿐인 경우에도 서버 수정이 필요하거나 시간에 민감한 상황에서 비 동기화를 피하기 위해 특정 기술을 사용해야합니까? ?

나는 어떤 가능한 해결책을 생각했는데, 그중 일부는 내가 덜 편안합니다.

  1. 서버 수정을 구현하십시오. 이것이 정상적인 동작이라고 가정하고 오류가 발생하면이를 수정하십시오. 어쨌든 그것을 구현하고 싶었지만 지금까지 내가 한 일이 수용 가능한지 확인하고 싶었습니다.

  2. 제공된 클라이언트 시간을 사용하여 원하는 조치를 적용하십시오. 나는 이것이 지연 보상과 유사 할 것이라고 생각한다. "시간으로 돌아가서"움직임을 점검해야한다. 서버 수정을 적용하는 것과 마찬가지로, 시간을 거슬러 올라간 후 다음 조치를 다시 적용하십시오. 나는 그 아이디어를 정말로 싫어한다. 복잡하고 비용이 많이 드는 것처럼 보이며 클라이언트가 제공 한 시간을 신뢰해야합니다 (시간이 비교적 합법적으로 보이는지 실제로 확인하려고하지만).

  3. GameDevelopment StackExchange에 내 모든 문제를 해결할 훌륭한 새로운 아이디어를 요청하십시오.

방금 게임 네트워킹의 세계에서 시작하고 있으므로 위의 개념을 수정 / 비판 / 모욕하거나 Wonderful World of Networking에서의 여정에 도움이되는 아이디어 / 자원을 자유롭게 제공하십시오. 다른 곳에서 내 대답을 찾을 수 있다면 용서하십시오.

소중한 시간 감사합니다.


서버와 클라이언트는 서로 다른 속도로 프레임을 실행합니다. 클라이언트가 연속 프레임에서 두 가지 작업을 수행하지만 서버가 두 프레임 사이에 한 프레임 간격이 있으면 어떻게됩니까?
user253751

떨어져 자신을 기반 @immibis gafferongames.com/game-physics/fix-your-timestep 것은 이 효과를 최소화합니다.
Jesse Emond

답변:


11

이러한 경우, 클라이언트가 약간 권한을 갖도록하는 것이 더 나을 수 있습니다. 이러한 정밀한 제어를 위해서는 실제로 고급 보정 및 예측을 수행해도 좋은 동작을 얻을 가능성이 거의 없습니다.

클라이언트는 단지 "I jumped"메시지를 보내는 것에서 "T 시간에 X, Y에서 jump 한"메시지를 보내는 것까지 확장해야합니다. 서버는 위치가 부정 행위로부터 보호하기 위해 플레이어가 T 시점에서 생각했던 것과 근접한 위치 (이전에는 상당히 작은 시간으로 제한 할 수 있음)에 있는지 확인한 다음 클라이언트 위치에서 점프를 시뮬레이션합니다. 보냈습니다. 서버는 클라이언트가 whack에서 멀리 떨어져있을 때만 (일반적으로 지연 등으로 인해) 클라이언트를 수정합니다.

이러한 종류의 기술은 게임을 로컬 클라이언트에서 반응 적으로 느끼고 원격 클라이언트에게 부드럽게 보이도록하기 위해 수정 및 보간과 함께 사용됩니다.


매우 흥미로운. 나는 이것을 구현하려고 노력하고 그것이 어떻게 진행되는지 볼 것이다. 시간을내어 답변 해 주셔서 감사합니다. 그건 그렇고, 당신은 "근접한 거리 안에"와 "과거에 아주 작은 시간"을 언급했습니다. 각각 일정한 거리와 시간으로 간단히 확인 하시겠습니까? 아니면 위치 기록을 유지하고 고객의 평균 왕복 시간 (또는 실제로 다른 것)을 사용하는 것과 같은보다 정교한 기술을 사용 하시겠습니까?
Jesse Emond

당신의 게임을 위해 무엇이든 작동합니다. 간단하게 시작하고 필요한 정도로만 복잡하게 만드십시오. 일부 서버는 ~max(RTT)과거 에 서버 틱에 대한 스냅 샷 기록을 유지 하지만 게임에 필요한지 여부는 구체적으로 알지 못합니다. 클라이언트에서 일정 수준의 적중 / 샷 감지를 원하고 플레이어가 46ms 전의 위치뿐만 아니라 그의 대상이 46ms 전의 위치 및 움직이는 폐색 플랫폼
Sean Middleditch

완전한. 실험하고 가장 잘 작동하는 것을 볼 것입니다. 그것을 받아 들인 대답으로 표시하십시오. 다시 감사합니다!
Jesse Emond
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.