¿Cómo funcionan los parches en los juegos?

37

Los juegos de consola y PC tienen parches a veces para corregir errores que los desarrolladores se perdieron / no tuvieron tiempo de arreglar.

Mi pregunta es ¿cómo funcionan estos?

A veces, los archivos de parche tienen unos pocos megabytes de tamaño. No entiendo cómo un archivo pequeño puede alterar un programa cumplido.

MulletDevil
fuente
¿Deseas alterar un juego compilado que hiciste usando un pequeño parche?
wolfdawn
No, solo estoy interesado en la teoría detrás de esto. Mis juegos son lo suficientemente pequeños como para recompilarlos y distribuir todo el juego nuevamente :)
MulletDevil
44
Esta es una pregunta interesante. No se basa en un problema con el diseño del juego. También hay muchas formas de manejar los parches de la manera más ingenua, reemplazando todos los archivos que se modificaron por los más complejos, obteniendo instrucciones para cambiar cosas específicas en los archivos existentes. No estoy seguro de que esta pregunta sea adecuada para este sitio.
wolfdawn
3
Unos pocos megabytes no son "pequeños". Supongamos que tenemos un archivo de tres megabytes que es seis megabytes de código ejecutable, comprimido. Suponga que las instrucciones tienen una longitud promedio de seis bytes, por lo que se trata de un millón de instrucciones. (Ignoremos los datos estáticos como los literales de cadena y otras cosas). Si una línea de C corresponde a unas diez instrucciones de máquina, eso es 100.000 líneas de código. Eso parece suficiente para el motor central de un juego. La mayor parte del tamaño de la instalación será como mapas de textura, pantallas, secuencias de video.
2
unos pocos megabytes pueden ser pequeños, todo depende de lo que contenga y del porcentaje del código base total que sea. Si, por ejemplo, es necesario reemplazar un mapa de nivel 3D completo debido a los formatos de archivo elegidos, etc., incluidas todas las texturas y demás, unos pocos megabytes pueden ser muy pequeños.
Jwenting

Respuestas:

30

Hay varias formas de hacer esto, la más simple sería XOR los dos archivos y comprimirlos (GZIP, etc.). La teoría detrás de esto es que con suerte puede obtener una gran secuencia de ceros (las secuencias largas de los mismos valores se comprimen bien).

Puede llevar ese concepto más allá e intentar encontrar áreas de los dos archivos donde los datos son idénticos y omitirlos por completo.

Finalmente, puede utilizar la estructura de cada tipo de archivo para su ventaja. Por ejemplo, en un EXE, puede empaquetar cada método individualmente (solo los que han cambiado) y reconstituir el EXE usted mismo durante la aplicación del parche; tenga en cuenta, sin embargo, que esto es muy probable en el ámbito de la exageración y puede que no valga la pena el esfuerzo (la ganancia sobre un bdiff simple puede no justificar la complejidad adicional que podría romperse en la naturaleza). Como otro ejemplo, podría usar archivos diff para scripts.

Sin embargo, la mayoría de los sistemas de parches en la naturaleza toman la ruta más simple: simplemente empaquetan los archivos que han cambiado, no intentan empaquetar solo los cambios dentro de esos archivos (probablemente por una buena razón, la mayoría del contenido del juego ya está comprimido y crea parches contra altos niveles). la entropía o los datos comprimidos no funcionarán en absoluto ).

Jonathan Dickinson
fuente
¿Qué quieres decir con empaquetar cada método en un exe individualmente? ¿Es eso práctico?
wolfdawn
@ArthurWulfWhite sí. Para una casa independiente probablemente no valga la pena el tiempo, ya que tomaría una cantidad extrema de tiempo y esfuerzo (esencialmente necesita escribir su propio enlazador); como una empresa que se ocupa exclusivamente de la 'tecnología de parcheo', valdría la pena el esfuerzo. Todo depende de qué tan grande sea el código ejecutable: eché un vistazo rápido a Sacred 2 y tenía 26 mb (8 mb para el EXE principal). Sin embargo, un diferencial binario podría acercarse a él, aunque es una idea que vale la pena presentar (sé que los CAB obtienen una buena compresión en los EXE porque aprovechan la estructura).
Jonathan Dickinson el
Eso es muy interesante. Supongo que siendo el ancho de banda lo que es hoy, minimizar el tamaño del parche del juego no es un problema importante. +1 una respuesta interesante y bien pensada.
wolfdawn
No es tan factible aplicar parches en métodos individuales en la mayoría de los juegos. El compilador puede tener resultados bastante diferentes con incluso cambios de código simples. Las decisiones de alineación automática pueden cambiar, el diseño de la tabla de símbolos puede cambiar, etc. Los cambios en el código a menudo también cambian la estructura interna de la API. Las optimizaciones ya difuminan la línea entre los límites de la función en comparación con lo que ve en su editor de código. Los sistemas DRM también enturbian mucho el agua. Los sistemas de parches usan reemplazos al por mayor o diferencias binarias, y los comprimen. Cualquier cosa que sugieras es simplemente demasiado frágil para enviar en el mundo real, en mi opinión.
Sean Middleditch
2
@SeanMiddleditch Voy a hacerlo solo para demostrar que es posible :).
Jonathan Dickinson
15

El código ejecutable de un juego no siempre reside solo en el ejecutable, a menudo se divide en varias bibliotecas dinámicas (por ejemplo, el juego, los gráficos y los motores de sonido), el ejecutable real y posiblemente muchos scripts para diversos fines.

Un parche podría solucionar problemas en cualquiera de estas partes sin garantizar un cambio en todas ellas.

Un enfoque diferente al reemplazo de todos los archivos modificados podría ser simplemente hacer una diferencia binaria en ellos, y solo empacar las diferencias reales para redistribuirlas.

(Eso, por supuesto, solo funcionará en archivos que puede garantizar que el usuario no cambiará).


fuente
2
Podría mencionar esto como un ejemplo: daemonology.net/bsdiff
wolfdawn el
2
Buena respuesta práctica. +1
wolfdawn
2

Normalmente usan un sistema de diferencias binario de terceros para distribuir parches a los datos del juego. Los ejecutables suelen ser lo suficientemente pequeños como para ser distribuidos trivialmente por completo.

La mayoría de los juegos modernos tienen cientos de megas de datos del juego (principalmente texturas, modelos, datos de niveles, etc.). Estos requieren parches con bastante frecuencia. Hasta donde sé, los editores normalmente tienen una forma patentada de hacer esto.

No hace falta decir que hay ejemplos de código abierto. Algunas distribuciones de Linux (¿Fedora?) Usan diferencias binarias para sus parches. Puede investigarlos y leer su código fuente o documentación.

MarkR
fuente
-1

Los diffalgoritmos modernos pueden encontrar eficientemente secuencias de bytes que son comunes entre dos binarios. No es sorprendente, si lo piensas. La compresión de archivos también se basa en encontrar secuencias de bytes idénticas.

Una vez que tenga la lista de secuencias de bytes idénticas, solo necesita enviar las compensaciones antiguas y nuevas, la longitud y, por supuesto, cualquier cosa que sea completamente nueva. En el lado receptor, se trata de un montaje sencillo. Copie los bits que necesita conservar del archivo anterior, complete los nuevos bits.

Crear el parche se vuelve aún más fácil si su enlazador puede escupir un archivo MAP que enumera las compensaciones de cada función en el archivo.

MSalters
fuente