내 슈퍼 간단한 멀티 플레이어 설정이 좋은 생각은 아니지만 왜 그럴까요?


11

나는 재미를 위해 간단한 작은 MOBA를 만들고 있습니다. 나는 모든 것을 싱글 플레이어로 만들고 있었고, "아마도 멀티 플레이어를 추가해야한다"고 깨달았습니다.

나는 전에 네트워킹으로 아무것도 한 적이 없었으므로 Lidgren 을 게임에 통합하는 방법을 배우는 것은 재미 있고 굉장했습니다. 문제는 내가하는 한 주류 게임이 충분히 강력하지 않기 때문에 내가하는 일이 잘못되었다는 것을 거의 알고 있다는 것입니다. 그러나 무엇이 잘못 되었습니까?

내가하고있는 것은 기본적으로 플레이어가 행동을 할 때마다 서버에 "이봐, 방금 했어요"라는 메시지를 보냅니다. 서버와 클라이언트 모두 동일한 시뮬레이션을 실행하고 있습니다. 그런 다음 서버는 다른 모든 클라이언트에게 그 사람이 그 일을했다는 메시지를 보냅니다.

플레이어가 어떤 일을 할 때 대부분의 경우를 제외하고는 클라이언트가 멋지다고 생각하고 스스로 진행합니다. 따라서 마우스 오른쪽 버튼을 클릭하여 해당 위치로 이동하면 해당 플레이어의 클라이언트가 그 사람을 거기로 이동하기 시작한 다음 서버에 메시지를 보냅니다.

그래서 기본적으로:

  • 1 번 선수가 주문을 시전하여 6 초 동안 100 % 더 빠르게 움직입니다.
  • Player 1의 로컬 클라이언트는 해당 버프를 Unit 객체에 추가합니다
  • 플레이어 1의 클라이언트는 "이 주문을 던졌습니다."라는 메시지를 서버에 보냅니다.
  • 서버는 자신이 그 주문을 발동 할 수있는 충분한 마나를 가지고 있는지 확인하고, 그렇다면 해당 버프를 해당 서버의 해당 유닛 오브젝트 사본에 추가합니다
  • 서버는 다른 모든 클라이언트에게 "이 사람은이 주문을 던졌습니다"라는 메시지를 보냅니다.
  • 다른 모든 클라이언트는 메시지를 수신하고 "ah okay cool"으로 가서 해당 버프를 해당 플레이어의 로컬 유닛 오브젝트에 추가합니다.

나는 큰 게임이 멀티 플레이어를 어떻게하는지 알기 위해 물건을 훑어 보았고,이 물건에 손을 대기 시작한 누군가에게는 혼란 스럽지만 소스 엔진 은 모든 변경 사항이 포함 된 패킷을 모든 진드기? 다시 말하지만,이 물건에 완전히 새로운 것이지만 실제로 그 많은 데이터를 자주 밀어 넣을 수 있습니까?

이것이 조금이라도 유감 스럽지만 미안하지만, 기본적으로 더 간단한 시스템이 왜 옳은 방법이 아닌지 궁금해하고 있습니다.


6
누락 된 한 단계는 서버가 시뮬레이션 결과를 확인하거나 거부하기 위해 서버 가이 메시지를 다른 모든 사람이 아닌 원래 클라이언트로 보내면 원래 클라이언트가 계속 진행하거나 새로운 현실에 맞춰 조정한다는 것입니다. 그 외에는이 방법이 훌륭하고 아래의 다른 답변을 통해 다른 측면을 더 깊이 이해할 수 있습니다.
Patrick Hughes

1
가장 좋은 점은 우리 중 나머지는 네트워크가 그렇게 어렵지 않다는 합리적인 희망을 가지고 있다는 것입니다. 할 수 있습니다.
ashes999

답변:


12

Byte56의 답변 외에도 고려해야 할 사항이 몇 가지 더 있습니다.

플레이어 이동에 대해 고객들 사이에서 어떻게 의사 소통을 하시겠습니까? 고립 된 이벤트이고 다소 드물게 발생하는 대부분의 다른 플레이어 동작과 달리 이동은 계속됩니다. 업데이트를 보내고받을 수있는 속도에는 제한이 있습니다. Byte56이 언급 한 클라이언트 측 예측에는 일반적으로 클라이언트 위치 및 속도에 대한 주기적 업데이트가 포함됩니다. 그런 다음 클라이언트는 Cubic Spline 과 같은 것을 사용하여 로컬로 보간합니다 .

이전 문제로 다시 연결되는 두 번째 문제는 UDP가 배달을 보장하지 않는다는 것입니다. 보내는 모든 메시지가 도착했거나 올바른 순서로 도착했는지 확신 할 수 없습니다. 패킷 1, 2 및 3을 보낼 수 있으며 서버는 2가 아닌 3을 1을 수신합니다. 종종 올바른 순서로 도착하고 항상 도착하지는 않습니다. 따라서 패킷 손실에 강한 시스템이 필요합니다. 간단한 확인 시스템이면 충분합니다. 일반적으로 다른 노드에 마지막 32 개의 메시지를 받았는지 (32 비트 int), 마지막으로받은 메시지가 무엇인지 알려주는 비트 필드가 사용됩니다. 이 방법으로 메시지를 중요 또는 비 위험으로 분류하고 중요 메시지를받지 못한 경우 다시 보낼 수 있습니다. 여기에 꽤 괜찮은 토론이 있습니다 .

또한이 작업을 수행 할 때 클라이언트가 서로 동기화되지 않는다는 점을 명심해야합니다. 최상의 시나리오에서 다음 프레임에서 작업하는 동안 각 플레이어는 이전 두 네트워크 프레임 사이에서 보간하는 다른 플레이어를 보여줍니다. 따라서 액션을 수행 할 때 플레이어가 본 액션이 게임의 실제 상태가 아님을 (공평하게) 고려하는 시스템이 필요합니다. 그는 동기화되지 않은 오래된 게임 상태에 반응하고있었습니다.

마지막으로,이 게임이 경쟁적이 되려면 부정 행위에 대해 걱정해야합니다. 따라서 가능하고 합리적인 범위 내에서 고객을 불신하고 그들의 행동이 가능한지 확인해야합니다. "아니요, 당신은 그 벽을 걸을 수 없습니다. 당신은 달리기 속도보다 더 빨리 걸을 수 없습니다. 아니, 당신은 그 목표를 쳤다고 주장 할 수 없습니다." 기타

더 많은 아이디어를 얻으려면 해당 두 번째 링크에서 다른 기사를 찾아 보는 것이 좋습니다.

행운을 빕니다!


6

당신이 설명하는 것은 본질적으로 클라이언트 측 예측 이지만 서버와 클라이언트가 동의하지 않을 때 어떤 일이 발생하는지 말하지 않습니다.

클라이언트가 단순한 터미널이었던 시절부터 서버로 입력을 보내면서 서버는 클라이언트에게 결과를 알려주었습니다. 그러나 일단 게임이 LAN을 넘어서 (그리고 종종 이전에)이 상황에서 레이턴시가 눈에 띄게 나타났습니다. 당신이 묘사하고있는, 그것을 해결하기 위해 클라이언트 측 예측이 도입되었습니다. 이제 클라이언트는 서버가 응답하기를 기다리는 동안 움직임을 시뮬레이션합니다. 그런 다음 결과에 동의합니다. 서버가 권한입니다.

다음 단계는 의견 불일치에 대응하는 방법입니다. 그 자리에 아무것도 없다면 클라이언트와 서버가 동의하지 않을 때 클라이언트 고무 밴드 또는 텔레 포팅을 받게됩니다.


5

타이밍. 다른 답변은 서버와 다른 클라이언트의 이벤트 타이밍을 언급하지 않습니다. 게임에 따라 조심해야 할 것이 있습니다. 지연 (일명 지연)은 패킷이 전송 될 때와 수신 될 때 사이에 가변 지연을 도입합니다. 시간은 까다로울 수 있지만 가능한 한 잠재적 인 문제를 설명하려고 노력할 것입니다. 이에 대해 걱정하지 않고 얻을 수있는 게임이 있지만 문제를 일으킬 수있는 간단한 예가 있습니다.

모든 사람이 도착하자마자 패킷에 대해 행동한다고 ​​가정하자.

@ Time 0 (wall time), Player 1 puts up a shield   (Message has been sent, but not received by anyone)
@ Time 1, Player 2 shoots player 1   (Message has been sent, but not received by anyone)

시간 0 (T0)과 T1이 서로 가깝다고 가정하십시오.

다음에 일어날 일은 이것을보고있는 사람과 패킷이 서버에 도착하는 순서에 따라 다릅니다. 서버는 항상 마지막 말을해야합니다. 서버가 위에서 주어진 순서대로 패킷을 수신하면, 서버는 샷과 플레이어 1 (P1)이 생존하기 전에 쉴드를 적용합니다. P1의 관점에서, 방패를 직접 착용 한 후, 그는 발사 전에 방패를보고 생존 할 것입니다. 그러나 P2는 어떻습니까? 그들은 총을 맞았 기 때문에 즉시 샷을 볼 수 있지만 방패를 먼저 볼 수 있습니까? 인 경우 (T0 + latency between P1 and the server + the latency between the server and P2) > T1, 발사 후 방패가 나타나고, P2는 그들의 발사가 P1을 죽였다고 생각할 것입니다. 서버는이 상황을 어떻게 든 수정해야합니다.

그러나 서버가 역순으로 패킷을 수신하면 (T0 <T1 인 경우에도 가능) 반대의 경우가 발생합니다. P1은 틀렸고 죽었고 P2는 정확하고 승리했습니다.

이와 같은 상황을 처리하는 몇 가지 방법이 있지만 가장 쉬운 방법은 서버가 모든 것을 수행하도록하는 것입니다. 클라이언트에서이를 시뮬레이트하려고 시도 할 수 있지만 사망과 같은 영구적 조치는 허용하지 않습니다. 플레이어는 서버에서 중요한 게임 변경 확인을 기다려야합니다.

작업과 함께 타임 스탬프를 보내는 것이 도움이 될 수 있습니다. 대부분 클라이언트를 신뢰하는 경우이 타임 스탬프를 사용하여 첫 번째 가정을 따르는 대신 먼저 어떤 작업이 발생했는지 확인할 수 있습니다. 과거로부터 메시지를 수신하면 일반적으로 시간을 되돌릴 수 있어야하므로 까다로울 수 있습니다.

시간이 재밌 니? 무슨 일을하든 이러한 시간 문제를 아는 것이 도움이됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.