2012-08-24 3 views
0

저는 현재 (빠른 클라이언트 - 서버 응용 프로그램의 예로 "간단한 멀티 플레이어 게임"할당의 일부로) 간단한 빠른 진행을위한 멀티 플레이어 게임 서버를 작성하려고합니다 몇 선수를위한 게임 (20 이하 나는 생각한다). 나는 보장 된 전달 (즉, 채팅 메시지, 로그인 및 로그 아웃 요청, ping 패킷 등)을 필요로하는 패킷에 대해 TCP 소켓을 사용하고있어 마지막 패킷 만 전달 된 이후로 반드시 전달할 필요는없는 모든 것에 대해 UDP를 사용합니다. 중요 (즉, 사용자 입력, 게임 세계 및 객체 업데이트 등).멀티 플레이어 게임 서버 모델 - 세계 복제 및 개체 업데이트

내 게임 세계가 어떻게 생겼는지 여기에 언급해야합니다. 모든 객체 서버 측에는 해당 ID, 역할 및 소유자 구성원이 있습니다. Id는 기본적으로 클라이언트를위한 식별자이므로 개체 업데이트를 보내면 어떤 개체를 업데이트할지 알 수 있습니다. 소유자는 객체 소유자에 대한 정보입니다. 즉, 액터를 제어하는 ​​플레이어입니다. 플레이어가 연결/로그 아웃을 잃으면 고아 오브젝트를 제거하기 위해이 도구를 사용합니다. 그러나 대부분의 객체는이 값을 Server로 설정합니다. 마지막으로 역할은 객체가 클라이언트에게 중요한지 여부를 결정합니다. 이 값은 서버 측 게임 상태 계산에만 사용되므로 클라이언트에 복제 할 필요가없는 객체 인 경우 RelevantToOwner로 설정할 수 있습니다 (이 객체는 소유자에게만 복제됩니다. 즉, 플레이어 개인 인벤토리는 모든 사람에게 복제해야 함), RelevantToList (개체가 목록의 모든 플레이어에게 복제됩니다. 즉, 개체를 볼 수있는 플레이어 목록이 있고 해당 개체에만 복제됩니다.) RelevantToAll (모든 사람에게 복제)입니다.

사용자가 로그인 패킷을 보낼 때 사용 가능한 슬롯이 있는지 여부를 확인한 다음 그에게 세계를 복제합니다 (현재 세계 상태 - 역할이 ServerSide 또는 RelevantToList로 설정된 모든 개체를 보내십시오 - 물론 클라이언트가 아니면 해당 개체의 목록에 있음).

그런 다음 서버 게임 상태 업데이트 루프가 반복 될 때마다 나는 똑같은 것을 전 세계 국가에 보냅니다.

사용자가 로그 아웃 패킷을 보낼 때 로그인 한 클라이언트에서 그를 삭제하고 빈 슬롯을 제거하고 게임 세계 (이 사용자가 소유자 인 개체)에서 모든 고아 개체를 제거합니다.

  • 이 모델은 실시간 멀티 플레이어 게임에 적합한 아니면 내가 끔찍하게 잘못하고 있어요 :

    여기 내 질문은?

  • 초기 세계 복제 후에 패킷 양을 줄이는 방법이 있습니까 (예 : 마지막 반복 이후 상태가 변경된 개체 만 업데이트). 생각해 보았으며 지금까지 한 가지 큰 문제가 발생했습니다. 이 방법을 사용하면 이전 반복의 UDP 패킷이 손실되고 이후 반복에서 개체 상태가 변경되지 않으면 개체가 플레이어 측에서 업데이트되지 않습니다.
  • 어떻게 여러 개체 업데이트를 하나의 패킷으로 묶을 수 있습니까? (현재 하나의 객체/패킷을 비효율적이고 또한 매우 끔찍하게 보내고 있습니다.)
  • 클라이언트/서버 게임의 일부 작동 예제 (소스는 좋을 것 같습니다)를 가리킬 수 있습니까? ionals는 그것을합니까? C++ 또는 C는 좋지만 Java/C#/Python도 좋습니다.
+0

btw이게 과제물이라면 숙제 태그를 추가해야합니다. – BugFinder

답변

2

게임의 유형에 따라 크게 달라집니다. 예 : 텍스트 기반 게임에서 대략 동일한 일을합니다. 내 업데이트는 도착시 간단하며 객실 세부 정보를 전송합니다. . 변경시 사람들/객체가 왔음을 알리는 메시지를 보냅니다. 끝난.

UDP는 100k + connectios를 처리해야하기 때문에 대부분의 온라인 게임이 작동하는 방식입니다. UDP 손실은 종종 플레이어가 게임에서 왜곡되는 이유입니다. 당신이 20 명을하고 있다면, 당신은 그 사실을 알고 나서, tcp를 고수하면 도움이 될 것입니다.

전 세계로 보내려면합니까? 당신의 세계는 구역/방으로 만들어져 있지 않습니다. 일반적으로 작은 영역을 보냅니다. 또한 전송해야하는 객체의 데이터 양에 따라 달라집니다. 플레이어가 인벤토리를 가지고 있다면, 특별히 요구하지 않는 한 다른 플레이어에게 그 점을 보내지 않아야합니다. - 착용 한 아이템 (시각적 인 게임이 필요한 경우 또는 잘못했을 때)

더 빠른 연결 요즘은 우리가 어떤 사람들은 고려하지 말아야한다는 것을 의미하지 않습니다. 업데이트 만 보내고 클라이언트는 자체 상태를 유지해야하며 영역을 변경하고 영역을 다시로드하면 동기화가 이루어집니다.

패킷에 객체 변경 내용을 패키징하는 경우, 위치 변경을 추측하는 Im (예 : 좌표 및 가용성) (예 : 사람이 항목을 가져옴). 업데이트 된 구조, item_id, update_type, update_values ​​[]가 있으면 업데이트 묶음을 보낼 수 있습니다.

텍스트 기반 또는 더 많은 mmorg 유형 이후입니까? 텍스트 기반 구글 tinymuck, 또는 tinymush, tinymud 말할 수 많은, 그래픽 것들? 더 세게, 예전 EQ 코드와 와우 에뮬레이터를 찾아 볼 수도 있습니다 ..

+0

_이 게임의 종류에 따라 많이 달라집니다. 아마도 타일 기반의 단순한 머드가 될 것입니다. 아직 확실하지 않습니다 ... _ 당신의 세계는 구역/방으로 만들어지지 않았습니다. 사실, 그것은 거대한 구역입니다. _ 보통 당신은 더 작은 영역을 보냅니다. 그래서 저는 역할 멤버를 추가했습니다 - 이제는 주어진 클라이언트와 관련된 객체 만 보냅니다. – stollgrin

+0

그리고 내가 물었던 다른 모든 질문은? – BugFinder

+0

_ uped 구조체, item_id, update_type, update_values ​​[]를 사용하면 updates._의 청크를 보낼 수 있습니다. 청크에 의해 여러 개의 구조로 구성된 패킷을 의미합니다. 맞습니까? 또한, 만약 당신이 20 명을하고 있고 그 사실을 알고 있다면, tcp를 붙이면 도움이 될 것입니다. _ 불행히도 나는 프로토콜을 선택할 수 없습니다. 이것은 할당의 일부입니다. – stollgrin

관련 문제