게임의 패치는 어떻게 작동합니까?


37

콘솔 및 PC 게임에는 개발자가 놓칠 수없는 버그를 수정하기위한 패치가 있습니다.

내 질문은 어떻게 작동합니까?

때때로 패치 파일의 크기는 몇 메가 바이트입니다. 작은 파일이 어떻게 호환 프로그램을 변경할 수 있는지 이해가 안됩니다.


작은 패치를 사용하여 만든 컴파일 된 게임을 변경 하시겠습니까?
wolfdawn

아니요, 나는 그 배후의 이론에 관심이 있습니다. 내 게임은 재 컴파일하고 전체 게임을 다시 배포하기에 충분히 작습니다. :)
MulletDevil

4
이것은 흥미로운 질문입니다. 게임 디자인이 직면 한 문제를 기반으로하지 않습니다. 가장 순진한 방식으로 패치를 처리하고 수정 된 모든 파일을 가장 복잡한 파일로 교체하고 기존 파일의 특정 사항을 변경하라는 지시를받는 방법도 많이 있습니다. 이 질문이이 사이트에 적합한 지 잘 모르겠습니다.
wolfdawn

3
몇 메가 바이트는 "작은"것이 아닙니다. 압축 된 6MB의 실행 코드 인 3MB 파일이 있다고 가정합니다. 명령어의 평균 길이가 6 바이트라고 가정하면 약 백만 개의 명령어입니다. (문자열 리터럴과 같은 정적 데이터는 무시하고 그렇지 않습니다.) C 행이 약 10 개의 기계 명령에 해당하면 100,000 행의 코드입니다. 그것은 게임의 핵심 엔진에 충분한 것 같습니다. 대부분의 설치 크기는 텍스처 맵, 스크린, 비디오 시퀀스와 같은 것입니다.

2
몇 메가 바이트는 작을 수 있으며, 그 크기는 전체 내용과 전체 코드베이스의 백분율에 따라 다릅니다. 모든 텍스처를 포함하여 선택한 파일 형식 등으로 인해 전체 3D 레벨 맵을 교체해야하는 경우 실제로는 몇 메가 바이트가 매우 작을 수 있습니다.
jwenting

답변:


30

이를 수행하는 방법은 여러 가지가 있지만 가장 간단한 방법은 두 파일을 XOR하고 압축하는 것입니다 (GZIP 등). 이것의 배후의 이론은 큰 숫자의 0을 얻을 수 있다는 것입니다 (같은 값의 긴 시퀀스는 잘 압축됩니다).

이 개념을 더 발전시키고 데이터가 동일한 두 파일의 영역을 찾아서 완전히 생략 할 수 있습니다.

마지막으로 각 유형의 파일 구조를 유리하게 사용할 수 있습니다. 예를 들어, EXE에서 각 메소드를 개별적으로 (변경된 것만) 패키지하고 패치 적용 중에 EXE를 직접 재구성 할 수 있습니다. 그러나 이것은 과잉의 영역에있을 가능성이 높으며 노력할 가치가 없을 수 있음을 명심하십시오 (단순한 bdiff를 통한 이득은 야생에서 깨질 수있는 추가 복잡성을 정당화하지 못할 수 있음). 다른 예로 스크립트에 diff 파일을 사용할 수 있습니다.

그러나 야생에서 대부분의 패치 시스템은 단순한 경로를 가지고 : 그들은 단지 변경된 파일을 패키지 - 그들은 아마도 좋은 이유, 대부분의 게임 콘텐츠가 이미 압축되어 그 파일 내에서만 패키지 변경 (를 시도하지 않으며, 높은에 대한 패치를 만드는 엔트로피 또는 압축 데이터는 전혀 작동하지 않습니다 ).


exe의 각 방법을 개별적으로 패키지한다는 것은 무엇을 의미합니까? 실용적입니까?
wolfdawn

@ArthurWulfWhite 예. 인디 하우스의 경우 시간과 노력이 많이 들기 때문에 아마도 시간이 가치가 없을 것입니다 (기본적으로 자신의 링커를 작성해야 함)- '패치 기술'을 독점적으로 다루는 회사는 노력할 가치가 있습니다. 그것은 모두 실행 코드의 크기에 달려 있습니다. Sacred 2를 간단히 살펴 보았고 26MB였습니다 (주 EXE의 경우 8mb). 바이너리 diff는 그것에 가깝게 접근 할 수 있습니다. 여전히 그것을 넣을 가치가 있습니다 (CAB은 구조를 이용하기 때문에 EXE에 대한 압축이 우수하다는 것을 알고 있습니다).
Jonathan Dickinson

매우 흥미 롭습니다. 나는 오늘날의 대역폭이 게임 패치 크기를 최소화하는 것이 큰 문제가 아니라고 생각합니다. 잘 짜여진 흥미로운 답변 +1.
wolfdawn

대부분의 게임에서 개별 방법으로 패치하는 것은 불가능합니다. 컴파일러는 간단한 코드 변경만으로도 상당히 다른 출력을 가질 수 있습니다. 자동 인라인 결정은 변경 될 수 있고 심볼 테이블 레이아웃은 변경 될 수 있습니다. 코드 변경은 종종 내부 API 구조를 변경합니다. 최적화는 이미 코드 편집기에 표시되는 것과 비교하여 함수 경계 사이의 경계를 흐리게합니다. DRM 시스템은 또한 물을 크게 흐릿하게합니다. 패치 시스템은 도매 대체 또는 이진 diff를 사용하여 압축합니다. 당신이 제안하는 것은 현실 세계 에선 너무 깨지기 쉽습니다.
Sean Middleditch 2012 년

2
@SeanMiddleditch 나는 그것이 가능하다는 것을 증명하기 위해 그것을 할 것입니다 :).
Jonathan Dickinson

15

게임의 실행 코드는 항상 실행 파일에만 상주하는 것은 아니며 종종 여러 동적 라이브러리 (예 : 게임, 그래픽 및 사운드 엔진), 실제 실행 파일 및 다양한 목적을위한 많은 스크립트로 나뉩니다.

패치는 모든 부분에 대한 변경을 보증하지 않고 이러한 부분 중 하나에서 문제를 해결하고있을 수 있습니다.

변경된 모든 파일을 바꾸는 것과 다른 접근 방식은 단순히 이진 차이 를 수행하고 재배포 될 실제 차이점 만 묶는 것입니다.

(물론 사용자가 변경하지 않을 것이라고 보장 할 수있는 파일에서만 작동합니다.)


2
이를 예로들 수 있습니다 : daemonology.net/bsdiff
wolfdawn

2
좋은 실제 답변. +1
wolfdawn

2

일반적으로 타사 바이너리 diff 시스템을 사용하여 게임 데이터에 패치를 배포합니다. 실행 파일은 일반적으로 사소하게 배포 될 수있을 정도로 작습니다.

대부분의 현대 게임에는 수백 메가의 게임 데이터 (주로 텍스처, 모델, 레벨 데이터 등)가 있습니다. 이것들은 꽤 자주 패치를 요구합니다. 내가 아는 한, 게시자는 일반적으로 표준 독점 방법으로이 작업을 수행합니다.

말할 것도없이, 오픈 소스 예제가 있습니다. 일부 Linux 배포판 (Fedora?)은 패치에 바이너리 diff를 사용합니다. 그것들을 조사하고 소스 코드 나 문서를 읽을 수 있습니다.


-1

최신 diff알고리즘은 두 바이너리간에 공통적 인 바이트 시퀀스를 효율적으로 찾을 수 있습니다. 당신이 그것에 대해 생각한다면 놀랍지 않습니다. 파일 압축은 동일한 바이트 시퀀스를 찾는 데 의존합니다.

동일한 바이트 시퀀스 목록이 있으면 이전 및 새 오프셋, 길이 및 물론 완전히 새로운 것을 보내면됩니다. 수신 측에서는 간단한 조립품입니다. 이전 파일에서 유지해야 할 비트를 복사하고 새 비트를 채우십시오.

링커가 파일에있는 모든 함수의 오프셋을 나열하는 MAP 파일을 추출 할 수 있으면 패치 작성이 훨씬 쉬워집니다.

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