2010-02-17 4 views
4

나는 퀘이크 2에서 느슨하게 내려온 게임 엔진에서 스크립트 효과와 같은 몇 가지를 추가하고 있습니다 (서버가 특수 클라이언트가 할 수있는 하드 코딩 된 효과의 수가 제한적이 아니라 클라이언트에 세부적으로 영향을줍니다.) 이는 유연성을위한 네트워크 효율성의 균형입니다.매우 작은 양의 데이터 (3-4 키브)에 가장 적합한 압축 라이브러리는 무엇입니까

나는 흥미로운 장벽을 맞았습니다. 최대 패킷 크기는 2800 바이트이며 하나의 프레임 당 클라이언트 당 하나 밖에 나갈 수 없습니다.

다음은 "불꽃"효과 (불꽃 충돌, 전기 충격 등)에 유용한 스크립트입니다. http://pastebin.com/m7acdf519 (이해가되지 않으면 땀을 흘리지 말고 사용자 정의 구문은 내가 만든 질문과 관련이 없습니다.)

해당 스크립트의 크기를 줄이기 위해 가능한 모든 작업을 수행했습니다. 변수 이름을 한 글자로 줄였습니다. 그러나 결과는 정확히 405 바이트입니다. 이것은 프레임 당 최대 6 개에 맞출 수 있음을 의미합니다. 또 다른 서버 측 변경 사항을 고려하여 서버 측 변경 사항을 12 가지로 줄일 수 있었고 프로토콜 변경으로 인해 다른 6 가지를 줄일 수있었습니다. 절약 효과는 어떤 스크립트를 사용하는지에 따라 달라질 수 있습니다.

그러나 387 바이트 중 41 개만 효과의 여러 용도간에 고유 할 것으로 추산됩니다. 다시 말해 압축에 가장 적합한 후보입니다.

R1Q2 (확장 네트워크 프로토콜이있는 이전 버전과 호환되는 Quake 2 엔진)에는 Zlib 압축 코드가 있습니다. 나는이 코드를 들어 올리거나 적어도 그것을 참조로 따라갈 수있다.

하지만 Zlib이 가장 좋은 선택일까요? 나는 적어도 하나의 대안 인 LZMA를 생각할 수 있으며, 더 쉽게 될 수 있습니다.

요구 사항 :

  1. 가 매우 빠른이어야합니다
  2. 2800 바이트
  3. 소형에 가능한 한 많은 데이터를 벼락 공부를해야합니다 (100 회 두 번째를 실행하면 매우 작은 성능 저하가 있어야합니다.) 메타 데이터 공간
  4. GPL Zlib의 좋은 찾고 있지만, 거기에 더 나은 아무것도입니다

호환? 이 코드는 아직 병합되지 않으므로 실험을위한 충분한 공간이 있습니다.

감사합니다, - 최대

편집 : 바이트 코드로 스크립트를 컴파일 제안 사람들에게 감사합니다. 나는 이것을 분명히해야했다. 예, 나는 이것을하고 있습니다. 내 웹 사이트에서 관련 소스 코드를 탐색 할 수 있습니다. 여전히 "유용"하지는 않습니다.
루아 구성 요소 : http://meliaserlow.dyndns.tv:8000/alienarena/lua_source/lua/scriptedfx.lua
C 성분 : 나는 게시 된 특정 스크립트 예를 들어 http://meliaserlow.dyndns.tv:8000/alienarena/lua_source/game/g_scriptedfx.c
, 이것은 아래 여전히 405 bytes-- 충분히 작은하지에 1172 바이트 소스 가져
이 서버 측 코드입니다. (가능한 한 많은 수를 2800 바이트에 맞춰야한다는 것을 명심하십시오.)

EDIT2 : 주어진 패킷이 도착할 것이라는 보장은 없습니다.각 패킷은 이전 패킷에서 전달 된 정보에 의존하지 않고 "세계의 상태"를 포함해야합니다. 일반적으로이 스크립트는 "눈 사탕"을 전달하는 데 사용됩니다. 하나를위한 여지가 없다면, 그것은 패킷에서 떨어지면 큰 문제가 아닙니다. 그러나 너무 많은 것이 떨어지면, 일들이 시각적으로 이상하게 보이기 시작하며 바람직하지 않습니다.

+0

압축면에서 빠르거나 압축 해제시에만 필요합니까? –

+0

압축 속도가 더 중요하다고 말할 수 있습니다. 클라이언트마다 프레임 당 각 클라이언트에 대해 서로 다른 패킷이 압축되기 때문에 (클라이언트가 프레임 당 하나의 패킷을 압축 해제해야합니다.) –

+0

이것은 오래되었지만 궁금합니다. 왜 전체 스크립트를 보내야합니까? 플레이어가 연결될 때 (또는 게임 중간에 게임을 추가해도 각 게임을 한 번만 보내면) 한 번에 프레임 단위로 처리 한 다음 스크립트 ID와 매개 변수를 보내면됩니까? – Leushenko

답변

2

FINAL UPDATE의 개념처럼 그들이 거기에 사용하는 기술 중 일부를 적용해야합니다 두 라이브러리는 해당에 대한 보인다. LZO의 디코딩 속도는 약 2 배 빠르지 만 Zlib는 약 ​​20 % 향상된 압축률을 제공하지만, 성능에 미치는 영향은 무시할 수 없을 정도로 작습니다. 그것이 나의 마지막 대답이다. 다른 모든 답변과 의견에 감사드립니다.

UPDATE : LZO 압축을 구현 만 전망이 좋은 더 나은 성능을 본 후, 그것은, 내 자신의 코드가 성능 저하 (패킷 당 가능한 스크립트 효과의 대규모 증가 수를 비난하는 것입니다 따라서 내 효과가 분명하다 "통역") 나는 겸손하게 비난을 옮기기 위해 뒤죽박죽으로 사과하고 싶다. 나는 힘든 감정이 없기를 바란다. 나는 프로파일 링을하고 나서 다른 누군가에게 더 유용 할 숫자를 얻을 수있을 것입니다.

ORIGINAL POST :

OK, 나는 마침내이 몇 가지 코드를 작성 주위 얻었다. 나는 Zlib와 함께 시작했는데, 여기 내 발견의 첫 번째입니다.

Zlib의 압축은 굉장히입니다. 그것은 Z_BEST_SPEED (Z_DEFAULT_COMPRESSION 대신에)로 압축 할 때에도, 8.5 바이트의 패킷을, 말하자면, 750 바이트 이하로 확실하게 줄입니다. 압축 시간 또한 꽤 좋습니다.

그러나, 의 압축 해제 속도에 대해서는 전혀 알지 못했습니다.도 이런 나쁜 것일 수 있습니다. 나는 실제 숫자가 없지만 적어도 패킷 당 1/8 초가 걸릴 것입니다! (Core2Duo T550 @ 1.83 Ghz.) 완전히 받아 들일 수 없습니다.

내가 듣기로는 LZMA가 Zlib와 비교할 때 성능이 떨어지는 것과 성능이 떨어지는 것이 있습니다. Zlib의 압축은 이미 과잉이며 그 성능은 이미 믿을 수 없을 정도로 나쁘기 때문에 LZMA는 지금은 볼 수없는 탁자에서 벗어납니다.

LZO의 압축 해제 시간이 주장한 것만 큼 좋다면, 그게 내가 사용할 것입니다. 나는 결국 서버가 여전히 극단적 인 경우에 Zlib 패킷을 보낼 수있을 것이라고 생각하지만 클라이언트가 무시하도록 구성 할 수 있으며 기본값이됩니다.

+0

와우, 1/8 초? 그건 끔찍한 짓이야. 나는 그게 심한 것을 모른다고 생각하지 못했습니다 ... –

+0

글쎄, 그것은 * 나쁘지 않을지도 모르지만, 실제로 시간을 정하지 않았습니다. 내가하는 일이 아닌 일종의 튜닝이 가능할 수도 있습니다. 다른 코드베이스와 문서를 살펴볼 것입니다. 어쨌든 결과는 꽤 생기있어 보입니다. gzip 및 일부 테스트 데이터로 인해 실제로 속도가 느려지는지 알아볼 수 있습니다. 저는 이것이 단지 오버 헤드라고 생각합니다. 만약 내가 100 배 더 큰 압축을 풀면, 거의 같은 시간이 걸릴 것입니다. 또는 * something *, 나는 gzip을 작동시키는 알고리즘이 너무 느리다는 것을 믿을 수 없다. –

4

LZO이 경우에 적합 할 수 있습니다.

+0

와우, 잘 생겼어! 감사! –

+0

+1, LZO는이 작업에 적합한 도구 일뿐입니다. –

1

zlib 좋은 후보가 될 수 있습니다 - 라이센스는 매우 좋으며 작업이 빠르며 작성자는 매우 적은 오버 헤드와 오버 헤드가 문제가되는 소량의 데이터를 사용하는 것이라고 말합니다.

0

9 바이트의 그룹을 왼쪽으로 이동하면 현재 낭비되는 각 문자의 최상위 비트를 사용하도록 규정되어 있으므로 8 바이트가 적합합니다.

문자를 작은 공백으로 매핑 할 수 있습니다. 예를 들어, 대문자를 허용하지 않고 각 문자에서 0x20을 뺄 때 (즉, 유효한 문자가 64 개인 경우에만) 6 비트까지 가져올 수 있습니까? 그 공간은 값 0이됩니다.

각 문자의 빈도를 매핑하고 각 문자의 평균 열 수를 줄이기 위해 허프만 형식 압축을 만들 수 있습니다.

변경 사항을 적용한 후에도 메시지에 중복이 거의 없으므로 일반적인 경우에는 데이터를 저장하는 알고리즘이 없다고 생각합니다.

+0

이것은 서버 측을 매우 컴팩트 한 바이트 코드 형식으로 "컴파일"하고 있습니다 (아니면 "조립"이라고해야합니까?). 이 예제에서, plaintext의 크기는 1172 바이트로 엄청나게 큽니다. 답변을 주셔서 감사합니다. :) –

0

스크립트의 바이너리 표현을 보내려면 어떨까요?

그래서 각 구문에 식별자가있는 추상 구문 트리의 줄을 생각하고 있습니다.

이것은 한 번 구문 분석으로 인해 클라이언트에서 성능이 향상되고 메서드 이름이 제거되어 크기가 줄어든다는 것을 의미합니다.

+0

나는 이것을 분명히해야했다. 예, 나는 이것을하고있다. 내 웹 사이트에서 관련 소스 코드를 탐색 할 수 있습니다. 여전히 "유용"하지는 않습니다. 다음은 서버 측 코드입니다. 루아 구성 요소 : http://meliaserlow.dyndns.tv:8000/alienarena/lua_source/lua/scriptedfx.lua C 구성 요소 : http://meliaserlow.dyndns.tv:8000 /alienarena/lua_source/game/g_scriptedfx.c 이것은 405 바이트까지 1172 바이트 소스를 가져옵니다. 여전히 충분히 작지는 않습니다. 멋진 아이디어. 내가 생각했던 것만 큼 좋았어! ;) –

+0

괜찮습니까? 질문에 추가하십시오 ;-) –

1

당신은 OpenTNL을보고 네트워크 문자열

+0

흥미로운 내용입니다. 감사! –

관련 문제