실시간 FPS 게임에서 서버로 무엇을 보내야합니까?


23

로컬 플레이어의 위치를 ​​서버에 알리는 올바른 방법은 무엇입니까? 일부 문서는 생산 될 때마다 입력을 보내는 것이 낫다고 말합니다. 그리고 일부 문서는 클라이언트가 고정 된 간격으로 위치를 전송한다고 말합니다.

입력을 전송하는 방법 : 플레이어가 방향키를 누르고 있으면 어떻게해야합니까? 그것은 모든 프레임에서 서버로 패키지를 보내야한다는 것을 의미합니다. 너무 많지 않습니까? 그리고 마우스 입력에서 플레이어의 회전도 있습니다. 예를 들면 다음과 같습니다.

http://www.gabrielgambetta.com/fpm_live.html

고정 간격 접근 방식으로 위치를 보내는 것은 어떻습니까? 서버에 너무 적은 메시지를 보냅니다. 그러나 그것은 또한 응답 성을 감소시킵니다.

어느 쪽이 더 낫습니까?

답변:


19

간단한 대답 : 속임수이거나 정확하지 마십시오!

온라인에서 일부 슈팅 게임을 해본 적이 있다면 서버 연결 상태가 좋지 않은 경우 소위 "고무 밴딩"을 경험했을 것입니다.

고객이 때때로 위치를 수정하기 때문에 발생합니다.

기본적으로 양면에서 발생하는 일 :

  • 서버가 움직임을 추적하고 예상대로 클라이언트에 업데이트를 보냅니다. 이것들이 항상 완전한 업데이트 일 필요는 없습니다. 모든 x 프레임은 완전히 업데이트 될 수 있으며, 다른 모든 프레임은 새로운 속도 벡터 만 보냅니다 (변경 사항이있는 경우).

  • 자신의 클라이언트는 자유롭게 이동할 수 있지만 서버가 제공 한 업데이트를 사용하여 위치를 수정 / 조정합니다. 이렇게하면 프레임 단위로 위치를 업데이트하지 않더라도 게임의 반응을 느낄 수 있습니다.

그러나 입력은 어떻게 처리됩니까? 당신의 클라이언트는 당신의 위치를 ​​서버로 보내 줄 것입니다. 서버는이 업데이트를 확인합니다 (예를 들어, 빠른 속도로 이동할 수 있어야합니까?). 유효한 경우에는 업데이트를 거부하면 "고무 밴딩"이 발생합니다.

따라서 고정 간격 접근 방식이 가장 효과적이고 충분합니다.

그러나 입력을 보내고 양쪽에서 움직임을 처리하려는 경우에도 "버튼을 계속 누르십시오"라는 메시지를 보낼 필요는 없습니다. 대신, 버튼을 누르면 하나의 이벤트를 보내고 버튼을 놓으면 다른 이벤트를 보냅니다.


5
예, 버튼을 눌렀다 떼는 것을 추적 할 수 있습니다. 그러나 마우스 입력은 어떻습니까? 끊임없이 변화하고 있습니다.
syloc

6
"대신, 버튼을 누르면 하나의 이벤트를 보내고 버튼을 놓으면 다른 이벤트를 보냅니다." -사실이지만 게임 규칙에 따라 "출시 중"이벤트가 강제로 발생하는지 확인해야합니다. 예를 들어, Rainbow Six Vegas 2 멀티 플레이어에서 플레이어는 총을 발사 할 수 있으며 (불행하게도) 버그로 인해 "발사 중지"메시지가 서버에 성공적으로 도달하지 않습니다. 그 결과, 나머지 경기 동안 총소리 오디오가 무한 루프에 남아있게됩니다. 조심해야 할 한 가지 예입니다. youtu.be/GOQIbLCy7m8?t=9m10s
Mike Baxter

@syloc : 클라이언트 쪽을 처리하고 서버가 이동이 유효한지 여부를 결정하게합니다 (텔레포트 핵과 같은 것들을 막기 위해).
마리오

@syloc 마우스의 간격을 설정하기 만하면, 여분의 대역폭을 절약하기 위해 여전히 클라이언트 측 검사를 수행하여 변경되었는지 확인합니다. 마우스를 움직이지 않고 일정 시간이 있으면 메시지를 계속 보내지 않아도됩니다.
agweber

내 직업 중 하나에서 엔지니어가 전화 접속을 위해 누락 된 위치 업데이트 (13 년 전)에 대한 스프링 동작을 최적화하기 위해 실제로 자신을 미치게 만들었습니다. 이제이 문제로 많은 대역폭과 엄청나게 짧은 대기 시간을 가진 게임을 볼 수 있습니다.이 문제는 결코 사라지지 않을 것 같습니다.
Andon M. Coleman

5

아직 이해하지 못했다면 https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networkinghttp://fabiensanglard.net/quake3/network.php 라는 두 가지 깊고 이해하기 쉬운 기사를 읽으십시오. .

여기에는 '고정 간격'패킷 전송을 사용하도록 권장되는 이유가 설명되어 있습니다. 간단히 말해서, 실제로 서버에 의해 전송 된 패킷에 대해 중요합니다.

패킷 전송에는 고정 비용이 있으며 네트워크 패킷 최대 크기는 약 1.5KB입니다. 따라서 서버에 예를 들어 16 명의 플레이어가있는 경우 플레이어의 움직임을 계산할 때 각 프레임마다 순진 코드가 각 움직임 해결 후 각 플레이어에게 업데이트 패킷을 보낼 수 있으므로 16 * 16 = 256 패킷입니다. 프레임 속도가 30이면 7680 패킷입니다.

더 나은 방법은 프레임의 시작 부분마다 버퍼를 만들고 16 개의 계산 된 위치 업데이트를 연결 한 다음 16 명의 플레이어에게 보내는 것입니다.

이제 동일한 결과를 위해 초 단위로 480 개의 패킷 만 보냅니다.

플레이어 대 서버의 경우, 이는 같은 패킷에 최대 데이터를 전송해야 함을 의미합니다. 위치,이 프레임이라고하는 동작 등이 있습니다.

귀하의 질문의 두 번째 부분에 대해-지연 감각을 줄이기 위해 선택한 방법은 각 프레임의 서버 에이 정보를 보내는 것입니다.

  • 플레이어의 실제 현재 위치 (서버에서 서버 측과 플레이어 측 위치가 너무 많이 동기화되지 않았는지 확인하기 위해 사용).

  • 1 초 후 예상 플레이어 위치 : 클라이언트에서 계산 : 플레이어가 마우스 방향을 바꾸지 않고 키보드를 1 초 동안 현재 상태로두면 플레이어는 어디에 있습니까? (충돌에 대해서는 신경 쓰지 않습니다.) 플레이어가 움직이지 않으면 1 초 안에 예상 위치가 현재 위치입니다.

  • 그가 바라본 위치.

서버가이 정보를 수신 할 때마다 미래 위치와 위치를 업데이트하고 플레이어 개체는 결국 미래 위치로 이동합니다.

플레이어는 정확히 동기화되지는 않았지만 입력 응답은 즉각적 (나에게 가장 중요)이며 정확한 위치가 나에게 정확하다는 것을 알았습니다.


"플레이어가 정확히 동기화 된 적이 없다" 고 생각합니다. 여기서 정확도의 수준은 실제 게임 (플레이)에 달려 있다고 언급하는 것이 중요합니다. 예를 들어 엔터티를 클릭하고 선택하는 클래식 MMO는 거의 모든 것에 대해 완벽한 정확도가 필요하지 않지만, 슈터에서는 완벽한 동기화에 적합해야합니다.
마리오

올바른 생각에 FPS에 TCP를 사용하는 사람은 아무도 없습니다. 오히려 TCP의 오버 헤드를 발생시키는 것보다 복잡한 재 시퀀싱 및 누락 된 데이터 그램을 처리합니다.
Andon M. Coleman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.