2011-08-24 1 views
3

저는 멀티 플레이어 fps로 작업 중이며 게임 상태 개체에서 델타 압축을 수행하는 방법에 대해 생각하고 있습니다.프로토콜 버퍼를 사용한 델타 압축

Q3가 네트워킹을 수행 한 방법에 대한 읽기에서 개체를 이진 상태로 직렬화 한 다음 마지막으로 알려진받은 개체와 현재 개체 사이에 이진 차이 만 보내는 것으로 델타 압축을 구현할 수 있다고 생각합니다. 델타 압축을 처리하는 올바른 방법입니까?

+0

항상 여러 가지 방법과 일부 중요하지 않은 요소가 있지만 ... 기본적으로 어떻게 할 것인가? - 예 :-) – Yahia

답변

1

두 가지 선택 사항이 있습니다.

  • 상태 A와 상태 B를 직렬화하고 결과에 대해 diff를 실행할 수 있습니다. (당신이 설명하는대로).

또는

  • 당신은 상태 A와 상태 B 사이의 차이를 발견하고 구조적인 차이를 직렬화하는 구조의 지식을 사용할 수 있습니다.

델타를 사용하는 것이 일반적인 목적의 diff를 실행하는 것보다 빠르다는 것과 같은 방식으로 정의 된 데이터 구조입니까?

나는 그것이 종종 있다고 생각합니다. 간단한 예를 들어 보겠습니다. 우리 게임 세계는 게임 상태가 P1 (x, y, z)와 P2 (x, y, z)로 정의 된 모든 시점에서 두 항목 P1과 P2를 정의합니다. 따라서 구조적 델타는 6 명의 변수 (두 선수의 경우 x, y, z)의 차이입니다. 이것을 계산하는 것은 빠르고 - 3 수학 연산입니다. 그러나 이들이 어떻게 직렬화되는지 알고 있으며, diff 루틴은 결과의 델타를 찾기 위해 많은 작업 (최소한 하나의 루프)을 수행해야합니다.

하지만 그보다 더 좋아집니다. 게임 엔진은 일들이 변화함에 따라 델타에 관심이 있다는 것을 알고 있기 때문에 델타를 목록에 저장하고 계산없이 델타를 보낼 준비가되어 있습니다 (예를 들어 P가 움직이면 변경 사항이 저장됩니다).

+1

두 번째 예가 더 빠를 수도 있지만 훨씬 더 빠를 것이라고 생각합니다. 복잡한. Q3가 전체 대상에 대한 델타를 만든 이유 중 하나는 게임 상태의 복잡성 때문이었습니다. 복잡한 데이터 구조의 관점에서 물건에 대해 생각할 때, 그 중 일부는 복잡한 구조이기 때문에 선택의 폭이 넓어지기 쉽습니다. –

+1

누락 된 부분은 Protobuf를 통해 어떻게 직렬화하는지입니다. 널 (또는 기본값) 필드와 정의되지 않은 필드가 있습니다. 델타 압축 후에는 변경되지 않은 필드를 직렬화해서는 안됩니다. 'ShouldSerialize ... '는 기본값과 동일하게 serialize합니다 (아무 것도 아님). deserialization이 값이 null로 변경되거나 쉽게 변경 될 수 없거나 동일하게 유지되어야한다는 것을 의미합니다. – Wernight