コンソールとPCゲームには、開発者が見逃した/修正する時間がなかったバグを修正するためのパッチが時々あります。
私の質問は、これらがどのように機能するのですか?
場合によっては、パッチファイルのサイズは数メガバイトです。小さなファイルがコンパイルされたプログラムをどのように変更できるか理解していません。
コンソールとPCゲームには、開発者が見逃した/修正する時間がなかったバグを修正するためのパッチが時々あります。
私の質問は、これらがどのように機能するのですか?
場合によっては、パッチファイルのサイズは数メガバイトです。小さなファイルがコンパイルされたプログラムをどのように変更できるか理解していません。
回答:
これを行う方法は複数ありますが、最も簡単なのは、2つのファイルをXORして圧縮することです(GZIPなど)。この背後にある理論は、願わくばゼロの大きなシーケンスを取得できることです(同じ値の長いシーケンスがうまく圧縮されます)。
その概念をさらに理解して、データが同一である2つのファイルの領域を見つけて、それを完全に省略することができます。
最後に、各タイプのファイルの構造を有利に使用できます。たとえば、EXEでは、各メソッドを個別にパッケージ化し(変更されたメソッドのみ)、パッチの適用中に自分でEXEを再構成できます。ただし、これはやり過ぎの領域である可能性が高く、努力する価値がない可能性があることに留意してください(単純なbdiffを超える利得は、野生で壊れる可能性のある余分な複雑さを正当化できない場合があります)。別の例として、スクリプトにdiffファイルを使用できます。
しかし、野生の中で最もパッチシステムは、最も簡単なルートを取る:彼らはちょうど変更されたファイルをパッケージ化-彼らはおそらく正当な理由のために、ほとんどのゲームコンテンツが既に圧縮されたファイル内のみのパッケージの変更(にしようとしていない高に対するパッチを作成しますエントロピーまたは圧縮データはまったく機能しません)。
ゲームの実行可能コードは常に実行可能ファイルだけに存在するわけではなく、多くの場合、いくつかの動的ライブラリ(ゲーム、グラフィックス、サウンドエンジンなど)、実際の実行可能ファイル、およびさまざまな目的のスクリプトに分割されます。
パッチは、これらのすべての変更を保証することなく、これらのパーツのいずれか1つの問題を修正できます。
すべての変更されたファイルを置き換えることとは異なるアプローチは、単にそれらに対してバイナリ差分を行い、再配布される実際の差分のみをパックすることです。
(もちろん、ユーザーが変更しないことを保証できるファイルでのみ機能します。)
通常、サードパーティのバイナリdiffシステムを使用して、ゲームデータにパッチを配布します。実行可能ファイルは通常、十分に小さく、完全に分散されます。
最近のほとんどのゲームには、数百メガのゲームデータ(主にテクスチャ、モデル、レベルデータなど)があります。これらには頻繁にパッチを適用する必要があります。私の知る限り、出版社は通常これを行うための標準的な独自の方法を持っています。
言うまでもなく、オープンソースの例があります。一部のLinuxディストリビューション(Fedora?)は、パッチにバイナリdiffを使用しています。それらを調査し、ソースコードまたはドキュメントを読むことができます。
最新のdiff
アルゴリズムでは、2つのバイナリに共通するバイトシーケンスを効率的に見つけることができます。驚くことではありませんが、考えてみてください。ファイル圧縮も、同一のバイトシーケンスを見つけることに依存しています。
同一のバイトシーケンスのリストを取得したら、古いオフセットと新しいオフセット、長さ、そしてもちろんまったく新しいものを送信するだけです。受信側では、簡単なアセンブリになります。古いファイルから保持する必要があるビットをコピーし、新しいビットを入力します。
リンカがファイル内のすべての関数のオフセットをリストするMAPファイルを吐き出すことができる場合、パッチの作成はさらに簡単になります。