네트워크 게임을 작성하는 방법? [닫은]


73

바탕으로 왜이 MMO를 개발하기 너무 어렵다? :

네트워크 게임 개발은 사소한 것이 아닙니다. 대기 시간뿐만 아니라 치트 방지, 상태 관리 및로드 밸런싱에서 극복해야 할 큰 장애물이 있습니다. 네트워크 게임 작성 경험이 없으면 학습하기가 어렵습니다.

소켓, 서버, 클라이언트, 프로토콜, 연결 등에 대한 이론을 알고 있습니다.

이제 어떻게 네트워크 게임 작성법을 배울 수 있을지 궁금합니다.

  • 로드 문제의 균형을 맞추는 방법?
  • 게임 상태를 관리하는 방법?
  • 동기화 된 상태를 유지하는 방법?
  • 리버스 엔지니어링으로부터 커뮤니케이션과 클라이언트를 보호하는 방법은 무엇입니까?
  • 대기 시간 문제를 해결하는 방법?
  • 어떤 것을 로컬에서 계산해야하고 어떤 것을 서버에서 계산해야합니까?
  • ...

좋은 책, 튜토리얼, 사이트, 흥미로운 기사 또는 이것에 관한 다른 질문이 있습니까?

나는 광범위한 답변을 찾고 있지만 특정 답변은 차이를 배우기에도 좋습니다.


4
그렇습니다. 이에 관한 책, 튜토리얼, 사이트, 흥미로운 기사 및 기타 질문이 있습니다.
Ricket

2
나는 질문을 수정하지 않고 밀어 넣는 현상금을 추가 하고이 질문에 대한 답변을받을 자격이 있기 때문에 사용자에게 대답 할 이유를주었습니다. 따라서 가장 좋은 답변자는 자신의 작업으로 명성을 얻지 만 질문에 대답하는 단일 답변은 없습니다.
Tamara Wijsman

답변:


61

다른 답변에 연결된 기사 외에도 Arianne Project 의 경험에 대해 조금 이야기 할 수 있습니다 .

동기화 된 상태를 유지하는 방법?

우리는 행동과 인식의 개념을 중심으로 “ Marauroa ” 프레임 워크를 구축했습니다 . 액션은 클라이언트에서 서버로 보내져 (왼쪽 도보, 공격 몬스터 # 47, '안녕하세요'와 같은) 사용자 입력을 전달합니다. 그리고 인식은 서버에서 클라이언트로 전송되어 주변의 세계 상태에 대해 알려줍니다. 이러한 인식은 매 차례마다 전송됩니다. 게임에 따라 30ms에서 300ms의 턴 타임을 사용합니다.

우리는 두 가지 유형의 인식을 가지고 있습니다 : 로그인과 플레이어가 새로운 영역 (구역)에 들어갈 때 완전한 인식이 전송됩니다. 그 후, 수정 된 객체의 수정 된 속성 (예를 들어 위치) 및 물론 신규 및 제거 된 객체만을 포함하는 차등 인식이 전송된다.

대기 시간 문제를 해결하는 방법?

우리는 "서버가 항상 옳다"고 확신합니다. 클라이언트는 부드러운 보행, 충돌 확인 등과 같은 일부 예측을 수행합니다. 그러나 클라이언트와 서버가 무언가에 대해 동의하지 않으면 서버가 승리합니다. 하위 프로젝트 Stendhal (2D RPG)는 기본적으로 300ms의 회전 시간을 사용합니다 (클라이언트 측에서 많은 스무딩이 수행됨). 이로 인해 Stendhal은 지연에 대해 매우 저항력이 있습니다.

참고 : 일부 다른 게임은 클라이언트를 네트워크 지연의 영향을 최소화하기 위해 확장하는 것으로 신뢰합니다. WoW에서는 종종 "Warsong Gulch"라는 전장 중 하나에서 악용되었습니다. 깃발을 가진 플레이어가 선택할 수있는 두 가지 방법이 있습니다. 따라서 부정 행위의 플레이어가 터널을 향해 달려가 자신을 위해 지연을 일으 킵니다. 서버와 다른 클라이언트는 계속해서 그를 향해 달려갑니다. 그러나 잠시 후이 클라이언트는 서버에게 언덕쪽으로 갔다고 말할 수 있습니다. WoW는 마지막 전송 좌표와 현재 좌표 사이의 거리가 시간 세그먼트 내에 맞는지 확인하고 수락합니다.

UDP 대 TCP 사용

초기 버전에서는 UDP를 사용하여 TCP의 오버 헤드를 줄였습니다. 우리는 손실 된 패킷을 스스로 처리했습니다. 이것은 프로젝트 초기에 완벽하게 작동했습니다. 그러나 몇 년 전에 서버가 가정용 DSL 연결에서 실제 데이터 센터로 이동했을 때 큰 문제가 발생했습니다. UDP는 방화벽 하드웨어의 CPU 성능을 극도로 요구합니다 (또는 적어도 5 년 전). 규칙 세트는 모든 단일 UDP 패킷에 적용되어야합니다. 그러나 TCP의 경우 규칙 세트는 처음 3 개의 패킷에만 적용됩니다. 그 후 연결이 설정됩니다. 다음의 모든 패킷은 연결 추적 테이블에 있거나 SYN 플래그가 없기 때문에 일반 규칙 세트를 무시합니다.

리버스 엔지니어링으로부터 커뮤니케이션과 클라이언트를 보호하는 방법은 무엇입니까?

Arianne은 완전히 오픈 소스이며 여기에는 클라이언트, 서버, 그래픽, 음악이 포함됩니다. 물론 여기에는 프로토콜 문서 와 디버깅에 사용되는 분석기도 포함됩니다.

SSL을 사용하는 타사의 무단 스니핑으로부터 통신을 쉽게 보호 할 수 있습니다.

그러나 리버스 엔지니어링으로부터 보호하는 것은 불가능합니다. 물론 난독 화하고 안티 디버깅 기술을 사용할 수 있습니다. 그러나 결국에는 사용자에게 제공하는 소프트웨어의 리버스 엔지니어링을 막을 수 없습니다. 개발자가 안티 디버깅 기술에 많은 노력을 기울이고 있음에도 불구하고 Skype가 리버스 엔지니어링 된 방법에 대한 흥미로운 프레젠테이션이 있습니다 . http://recon.cx/en/f/vskype-part1.pdf

참고 : 리버스 엔지니어링이 불법이거나 리버스 엔지니어링을 금지하는 라이센스 또는 ToS에 단락을 넣을 수있는 국가가 있습니다. 그러나 호환 가능한 데이터 스토리지 형식 또는 전송 프로토콜, 라이센스의 단락 또는 무효화하려는 ToS를 개발하는 맥락에서 리버스 엔지니어링을 명시 적으로 허용하는 다른 국가 (예 : 내가 살고있는 국가)가 있습니다. (이 섹션의 모든 내용은 내가 아는 한 변호사가 아닙니다)

어떤 것을 로컬에서 계산해야하고 어떤 것을 서버에서 계산해야합니까?

우리는 서버의 게임 로직과 관련된 모든 것을 계산합니다. 클라이언트는 게임이 원활하게 진행되도록 특정 이벤트를 예측합니다. 그러나 결국 서버는 항상 옳습니다.

예측 된 이벤트는 예를 들어 충돌이 발생했을 때 움직임이 중지되는 것입니다. Stendhal은 그리드를 사용하여 요소를 배치합니다. 그리고 서버 관점에서 모든 엔티티의 왼쪽 상단 모서리는 정확히 하나의 사각형에 있습니다. 그러나 클라이언트는 타일 사이를 부드럽게 이동합니다. 의사 3d 효과도 그립니다. 따라서 클라이언트에서 기본이 1x1 인 엔터티가 더 높을 수 있습니다.

로드 문제의 균형을 맞추는 방법?

유지 보수를 쉽게하기 위해 가능한 한 간단하게 유지하십시오.

정적 컨텐츠의로드 밸런싱은 http 서버 클러스터 및 컨텐츠 분배 네트워크 영역에서 잘 알려져 있습니다.

게임 서비스의로드 밸런싱에 대한 다소 간단한 개념은 여러 지역 / 지역으로 서버를 분할하는 것입니다. 따라서 영역 AC는 한 서버에 있고 영역 DF는 다른 서버에 있습니다. 한 세트의 구역에서 다른 세트의 구역으로 볼 수없는 경우 특히 쉽습니다. 클라이언트가 플레이어가있는 영역을 담당하는 영역 서버에만 연결할 수 있도록 몇 가지 점검을해야합니다.

한 서버에서 다른 서버로 플레이어를 전송하는 가장 쉬운 방법은 데이터베이스에 기록하고 클라이언트에게 다른 영역 서버에 연결하도록 지시하고 현재 서버에서 연결을 끊는 것입니다. 그런 다음 클라이언트는 새 영역 서버에 연결하여 데이터베이스에서로드합니다. (어쨌든 / 상점에서 데이터베이스 코드로의로드가 필요하므로 핸드 오버를 위해 서버 간의 직접 통신을 나중에 구현할 수 있습니다).

일부 추가 글로벌 서비스는 다음을 통해 필요합니다. 로그인시 클라이언트에게 올바른 영역 서버에 연결하도록 지시해야합니다. 그리고 당신은 세계적인 대화 시스템을 원할 것입니다.

MMO에서로드 밸런싱은 어떻게 수행됩니까? 에서이 주제에 대해 자세히 설명했습니다 .


1
UDP에는 약간 더 많은 CPU가 필요하다고 언급했지만 패킷이 처리되기 전에 TCP가 클라이언트와 서버 사이에서 3 회 이상 트립해야한다고 언급하지 않았으며, 이전의 모든 패킷이 수신 될 때까지 패킷이 버퍼링되므로 어리석게 경험할 수 있습니다. 더 이상 관련이없는 패킷을 기다리는 지연 시간. 언급해야 할 중요한 것 같습니다.
BlueRaja-대니 Pflughoeft

2
@Danny, 새 TCP 연결을 시작하는 데 필요한 세 가지 패킷이 있습니다. 클라이언트와 서버 : SYN, 서버와 클라이언트 : SYN ACK, 클라이언트와 서버 : ACK + 데이터. 이는 UDP보다 한 번의 왕복 여행이지만 클라이언트가 서버에 처음 연결할 때 처음에만 발생합니다. 설정된 연결에서 모든 패킷은 추가 왕복없이 즉시 처리됩니다. ACK- 응답이 있지만 ACK 패킷이 다시 이동하는 동안 수신 된 데이터는 이미 처리되었습니다.
Hendrik Brummermann 2016 년

1
@Danny, TCP는 패킷 손실을 자동으로 매우 효율적으로 처리합니다. UDP를 사용하여 자신을 다시 구현하는 것은 어렵습니다. 무작위로 전달되지 않은 패킷으로 프로토콜이 제대로되지 않는 한. 다음 문제는 TCP가 패킷 순서를 확인하는 반면 UDP 패킷이 잘못된 순서로 수신 될 수 있다는 것입니다. 다시 말해, 예를 들어 패킷 카운터를 기반으로하는 오래된 패킷을 무시할 수 없다면 스스로 구현하는 것은 어렵습니다. TCP에 매우 짧은 응답 시간이 필요한 경우 Nagle 알고리즘 을 비활성화해야합니다.
Hendrik Brummermann 2016 년

매우 실제적인 TCP 지연 문제를 해결하지 않고 자신의 입장을 강력하게 방어 한 것 같습니다. 아마도 진정한 문제는 DDoS 방지 프로토콜 대신 하드웨어 방화벽을 선택하는
것일 수

27

http://gafferongames.com/networking-for-game-programmers/

게임 네트워킹을 다루는 다양한 문제 및 솔루션에 대한 훌륭한 기사입니다.


1
+1이지만 맹목적으로 믿지 마십시오. 예를 들어 내 경험에 따르면 UDP를 사용하고 TCP 기능을 다시 발명하는 것은 좋지 않습니다. UPD는 손실 된 패키지가 전혀 영향을 미치지 않는 경우에만 유용합니다. 즉, 모든 UDP 패키지에는 세계의 완전한 관련 상태가 포함됩니다. WoW는 TCP를 사용하고 SL은 UDP에서 TCP (정적 내용의 경우 HTTP)로 이동하는 중이며 이러한 변경으로 성능이 크게 향상되었습니다.
Hendrik Brummermann

7
TCP 기능을 재발 명하지는 않지만 적어도 모든 기능은 아닙니다. 낮은 지연 시간 연결이 필요한 게임에는 TCP 흐름 제어 및 패킷 손실 의미가 끔찍합니다. TCP는 대기 시간을 신경 쓰지 않거나 필요한 대역폭을 최소화하지 않는 경우에만 유용합니다.
jsimmons

2
: TCP를 통한 HTTP에 UDP에서 이동하여 세컨드 라이프 (Second Life) 대규모 성능 향상 blogs.secondlife.com/community/technology/blog/2010/08/13/...
헨드릭 Brummermann

5
실제로는 작동 방식을 변경하여 자산 스트리밍 성능을 개선했습니다. 해당 인스턴스에서 HTTP / TCP를 사용하면 더 빨리 구현하는 것이 더 쉬워졌습니다. 또한 zeromq는 흥미로운 프로젝트이며 게임 네트워킹에 매우 적합하게 확장 될 수 있습니다. zeromq.org
jsimmons

8

작성중인 게임 유형에 따라 일부 저수준 네트워크 프로그래밍을 피할 수 있습니다. 일부 유형의 게임에는 클라이언트와 서버 간의 많은 통신이 필요하지 않습니다. 그러한 경우에는 더 높은 수준의 프레임 워크를 사용하도록 선택할 수 있습니다. 예를 들어, C # /. NET에서 턴제 전략 게임을 개발 중입니다. 턴제 전략 게임은 클라이언트 / 서버 커뮤니케이션의 대부분이 턴의 시작과 끝에서 발생하며, 그 사이에는 비교적 적은 점이 있다는 점에서 다소 독특합니다. 따라서 필자는 주로 웹 서비스 용으로 설계된 고급 통신 프레임 워크 인 WCF (Windows Communication Foundation)를 사용하기로 결정했습니다. 소켓과 모든 저수준 네트워킹 군과 직접 작업하는 대신 표준 메소드 호출로 보이는 것을 만들 수 있습니다. WCF가 프로토콜 및 전송 계층을 처리하도록하겠습니다. 저수준 네트워크를 다루어야 할 유일한 시간은 엔드 포인트를 구성 할 때뿐이었습니다. 이는 구성 파일에서 거의 일회성입니다. 여전히 일부 사용자 지정 직렬화 논리를 구현해야 할 수도 있지만 관계없이 이러한 종류의 작업을 수행해야합니다.


8

질문이 너무 광범위합니다. 답변은 웹 사이트를 모두 채울 수 있습니다. 그러나 이것에 대해 주로 다루는 책이 있습니다.

이 책들조차도 완전한 안내서는 아니지만 대신 사용할 수있는 아이디어와 접근 방식의 모음이며 일부는 함께 작동하지 않거나 모순되기도합니다. 일반적으로 게임, 네트워크 응용 프로그램 또는 둘 다를 개발 한 경험이 있다고 가정합니다.

(원래 질문에서 MMO에 대해 더 많이 이야기하고 있습니다. '네트워크 게임'은 PHP 기반 텍스트 게임에서 MMO에 이르기까지 모든 종류의 것을 의미 할 수 있으며 위의 하위 질문 모두가 아닙니다 각 유형에 적용하십시오.)


7

로드 문제의 균형을 맞추는 방법?

고정 지리적 크기 + 다중 인스턴스가 가장 쉬운 솔루션입니다. SWG에서 일하는 사람들은 역동적 인 크기를 시도하고 후회했습니다.

게임 상태를 관리하는 방법?

서버는 권한이 있습니다.

동기화 된 상태를 유지하는 방법?

서버에서 주기적 동기화 업데이트. (여기에 우려 사항이 무엇인지 확실하지 않음)

리버스 엔지니어링으로부터 커뮤니케이션과 클라이언트를 보호하는 방법은 무엇입니까?

불가능한. 클라이언트로부터받는 것을 신뢰하지 말고 서버가 신뢰할 수 있는지 확인하십시오.

대기 시간 문제를 해결하는 방법?

이 과정은 수년이 걸리지 만 표면적으로 서버와 동일한 시뮬레이션을 실행하고 동기화가 발생하면 문제를 해결하십시오. 클라이언트에 대한 모든 결정은 서버에서도 시뮬레이트되므로 잘못된 결정이있을 수 있지만 일반적으로 문제가 해결됩니다.

어떤 것을 로컬에서 계산해야하고 어떤 것을 서버에서 계산해야합니까?

클라이언트가 서버에서 무슨 일이 일어나고 있는지에 대한 비 권위적인 시뮬레이션을 실행하는 것으로 생각하십시오. 응답 성은 플레이어 경험의 핵심 요소이므로 , 플레이어가 바를 막 시작하더라도 결정을 내릴 때마다 무언가 를해야 합니다.

사실, 이러한 많은 문제는 직교 적이며 나중에 솔루션을 적용 할 수 있습니다. 게임을 시작하고 이러한 일에 대해 너무 걱정하지 마십시오.


4

이 질문은 매우 광범위합니다. 또한 마스터하기에는 매우 까다로운 영역이며 네트워크 프로그래머는 업계에서 꽤 많은 돈을 지불해야합니다. 이는 '해결되지 않은'영역임을 나타냅니다. 저기 책이 많습니까? 의심 할 여지없이 좋은 책이 있습니까? 귀하의 질문에 대답 할 책이 ​​있습니까? ... 그렇지 않습니다. 그들은 어떤 상황에서 작동하는 솔루션이나 찾고있는 것에 대한 포인터를 가지고 있지만 거의 모든 질문은 게임에 달려 있습니다. 사소하고 너무 많은 (제어되지 않은) 방식으로 잘못 될 수 있습니다.

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