Come funzionano le patch nei giochi?


37

I giochi per console e PC hanno patch a volte per correggere bug che gli sviluppatori hanno perso / non hanno avuto il tempo di correggere.

La mia domanda è: come funzionano?

A volte i file di patch hanno dimensioni di alcuni megabyte. Non capisco come un piccolo file possa alterare un programma rispettato.


Desideri modificare un gioco compilato che hai creato usando una piccola patch?
Wolfdawn,

No, sono solo interessato alla teoria alla base. I miei giochi sono abbastanza piccoli da ricompilarli e distribuire di nuovo l'intero gioco :)
MulletDevil

4
Questa è una domanda interessante. Non si basa su un problema con il design del gioco. Esistono anche molti modi per gestire le patch dal modo più ingenuo, sostituendo tutti i file che sono stati modificati in quelli più complessi, ottenendo istruzioni per modificare elementi specifici nei file esistenti. Non sono sicuro che questa domanda sia adatta a questo sito.
Wolfdawn,

3
Alcuni megabyte non sono "piccoli". Supponiamo di avere un file da tre megabyte che è sei megabyte di codice eseguibile, compresso. Supponiamo che le istruzioni siano lunghe in media sei byte, quindi sono circa un milione di istruzioni. (Ignoriamo i dati statici come valori letterali di stringa e quant'altro.) Se una riga di C corrisponde a una decina di istruzioni della macchina, sono 100.000 righe di codice. Sembra abbastanza per il motore principale di un gioco. La maggior parte delle dimensioni dell'installazione saranno elementi come mappe di trama, schermate, sequenze video.

2
alcuni megabyte potrebbero essere piccoli, tutto dipende da cosa c'è dentro e da quale percentuale della base di codice totale è. Se si dice che un'intera mappa di livello 3D deve essere sostituita a causa dei formati di file scelti, ecc., Comprese tutte le trame e cosa no, alcuni megabyte possono essere davvero molto piccoli.
jwenting

Risposte:


30

Esistono diversi modi per farlo, il più semplice sarebbe XOR i due file e comprimerli (GZIP o così via). La teoria dietro questo è che si spera che tu possa ottenere una grande sequenza di zeri (lunghe sequenze degli stessi valori si comprimono bene).

Puoi approfondire questo concetto e provare a trovare aree dei due file in cui i dati sono identici e ometterli del tutto.

Infine, è possibile utilizzare la struttura di ciascun tipo di file a proprio vantaggio. Ad esempio, in un EXE è possibile impacchettare singolarmente ciascun metodo (solo quelli che sono stati modificati) e ricostituire l'utente stesso durante l'applicazione della patch; tieni presente, tuttavia, che questo è molto probabile nel regno dell'eccesso e potrebbe non valere la pena (il guadagno su un semplice bdiff potrebbe non giustificare la complessità aggiuntiva che potrebbe rompersi in natura). Come altro esempio potresti usare i file diff per gli script.

Tuttavia, la maggior parte dei sistemi di patching in natura prende la strada più semplice: impacchettano solo i file che sono cambiati - non tentano solo di impacchettare le modifiche all'interno di quei file (probabilmente per una buona ragione, la maggior parte del contenuto di gioco è già compresso e crea patch con valori elevati entropia o dati compressi non funzioneranno affatto ).


Cosa intendi per pacchetto ogni metodo in un exe individualmente. È pratico?
Wolfdawn,

@ArthurWulfWhite sì. Per una casa indipendente probabilmente non vale la pena il tempo in quanto richiederebbe un'estrema quantità di tempo e fatica (essenzialmente è necessario scrivere il proprio linker) - poiché un'azienda che si occupa esclusivamente di "tecnologia di patching" varrebbe la pena. Tutto dipende da quanto è grande il codice eseguibile - ho dato una rapida occhiata a Sacred 2 ed era 26mb (8mb per il file EXE principale). Un diff binario potrebbe essere in grado di avvicinarsi ad esso - comunque è un'idea che vale la pena mettere in campo (so che i CAB ottengono una buona compressione su EXE perché sfruttano la struttura).
Jonathan Dickinson,

È molto interessante. Suppongo che la larghezza di banda sia quella che è oggi, ridurre al minimo le dimensioni della patch di gioco non è un grosso problema. +1 un'interessante risposta ben ponderata.
Wolfdawn,

Nella maggior parte dei giochi non è possibile applicare patch nei singoli metodi. Il compilatore può avere output piuttosto drasticamente diversi con anche semplici modifiche al codice. Le decisioni di allineamento automatico possono cambiare, il layout della tabella dei simboli può cambiare, ecc. Le modifiche al codice spesso cambiano anche la struttura dell'API interna. Le ottimizzazioni già sfocano la linea tra i limiti delle funzioni rispetto a ciò che vedi nell'editor di codice. Anche i sistemi DRM fangano notevolmente l'acqua. I sistemi patch utilizzano la sostituzione all'ingrosso o le differenze binarie e le comprimono. Qualunque cosa tu suggerisca è semplicemente troppo fragile per essere spedita nel mondo reale, imo.
Sean Middleditch,

2
@SeanMiddleditch Ho intenzione di farlo solo per dimostrare che è possibile :).
Jonathan Dickinson,

15

Il codice eseguibile di un gioco non risiede sempre solo nell'eseguibile, spesso è diviso in diverse librerie dinamiche (ad esempio il gioco, la grafica e i motori audio), l'eseguibile effettivo e possibilmente molti script per vari scopi.

Una patch potrebbe risolvere i problemi in ciascuna di queste parti senza giustificare il cambiamento in tutte.

Un approccio diverso rispetto alla sostituzione di tutti i file modificati potrebbe consistere semplicemente nel fare un diff binario su di essi e comprimere solo le differenze effettive da ridistribuire.

(Ovviamente funzionerà solo su file che puoi garantire che non verranno modificati dall'utente.)


2
Potresti menzionarlo come esempio: daemonology.net/bsdiff
wolfdawn

2
Buona risposta pratica +1
wolfdawn,

2

Normalmente usano un sistema diff binario di terze parti per distribuire patch ai dati di gioco. Gli eseguibili sono in genere abbastanza piccoli da essere interamente banalmente distribuiti.

La maggior parte dei giochi moderni ha centinaia di mega dati di gioco (principalmente trame, modelli, livelli di livello ecc.). Questi richiedono patch abbastanza spesso. Per quanto ne so, gli editori hanno normalmente un modo proprietario standard per farlo.

Inutile dire che ci sono esempi open source. Alcune distribuzioni Linux (Fedora?) Usano diff binari per le loro patch. Puoi esaminarli e leggere il loro codice sorgente o documentazione.


-1

I moderni diffalgoritmi possono trovare in modo efficiente sequenze di byte comuni tra due binari. Non sorprende, se ci pensate. La compressione dei file si basa anche sulla ricerca di sequenze di byte identiche.

Una volta che hai l'elenco di sequenze di byte identici, devi solo inviare gli offset vecchi e nuovi, la lunghezza e ovviamente tutto ciò che è completamente nuovo. Sul lato ricevente, è quindi un assemblaggio semplice. Copia i bit che devi conservare dal vecchio file, compila i nuovi bit.

La creazione della patch diventa ancora più semplice se il tuo linker può sputare un file MAP che elenca gli offset di ogni funzione nel file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.