-
Notifications
You must be signed in to change notification settings - Fork 10
Game Identification
This page details the hashing method used for each supported system. First, systems where the entire game file is hashed are listed, and later systems where the RA hash may differ from the file MD5.
NOTE: As saving and other manipulations can mutate disk data, local copies of loaded images are required to ensure that their hashes do not change across sessions.
NOTE: As saving mutates disk data, local copies of loaded images are required to ensure that their hashes do not change across sessions. We do not believe this is working, but have yet to find a game where saving to disk actually works.
NOTE: As saving and other manipulations can mutate disk data, local copies of loaded images are required to ensure that their hashes do not change across sessions.
The volume header (first 132 bytes of sector 0) and the contents of the LaunchMe file are hashed.
The filename string without the extension (path/galaga.zip -> galaga) is hashed. It is case-sensitive.
If the ROM starts with \1ATARI7800, the first 128 bytes are ignored and the remaining file contents are hashed. If the ROM does not start with \1ATARI7800, the entire file is hashed.
If the ROM starts with LYNX\0, the first 64 bytes are ignored and the remaining file contents are hashed. If the ROM does not start with LYNX\0, the entire file is hashed.
If the ROM starts with FDS\1a, the first 16 bytes are ignored and the remaining file contents are hashed. If the ROM does not start with FDS\1a, the entire file is hashed.
NOTE: As saving mutates disk data, local copies of loaded images are required to ensure that their hashes do not change across sessions.
An NDS ROM has a 0x160 byte header. In this header are pointers to icon/title information and to the boot code for both processors. The hash method combines the header, the two pieces of boot code, and the icon/title information and hashes the result.
- The icon/title information is 0xA00 bytes starting at the address stored in the header at $68
- The arm9 code address is stored at $20 in the header, and the size is stored at $2C in the header
- The arm7 code address is stored at $30 in the header, and the size is stored at $3C in the header
If the ROM starts with NES\1a, the first 16 bytes are ignored and the remaining file contents are hashed. If the ROM does not start with NES\1a, the entire file is hashed.
If the size of the file is 512 bytes more than a multiple of 128KB, the first 512 bytes are ignored and the remaining file contents are hashed. If the size of the file is not 512 bytes more than a multiple of 128KB, the entire file is hashed.
The boot code and disc title are hashed as follows:
- Read 128 bytes from sector 1 of the data track (PCE predates ISO-9660, so there's no file system to read).
- If "PC Engine CD-ROM SYSTEM" does not exist at 32 bytes into the data, discard as invalid.
- Copy the last 22 bytes of the data into a buffer. This is the disc title, and usually identifies the game.
- The first three bytes of the data are a little-endian sector index for the boot code.
- The fourth byte is the number of sectors that the boot code occupies.
- The boot code is appended to the buffer (N sectors, starting at sector X)
- The buffer is hashed.
The boot code and disc title are hashed as follows:
- Read 32 bytes from sector 0 of the data track (PC-FX predates ISO-9660, so there's no file system to read).
- If "PC-FX:Hu_CD-ROM" was not read, discard as invalid.
- Read 128 bytes from sector 1 of the data track into a buffer. This is the volume header and includes the disc title.
- The 32-bit value at 32-bytes into the buffer is the first sector of the boot code.
- The 32-bit value at 36-bytes into the buffer is the number of sectors that the boot code occupies.
- The boot code is appended to the buffer (N sectors, starting at sector X)
- The buffer is hashed.
The primary executable and its name are hashed as follows:
- The SYSTEM.CNF file is loaded and parsed. The primary executable is identified by the BOOT= line within.
- The primary executable name (and its path) are extracted from SYSTEM.CNF and written to a buffer.
- The contents of the primary executable are appended to the buffer.
- The buffer is hashed.
The primary executable and its name are hashed as follows:
- The SYSTEM.CNF file is loaded and parsed. The primary executable is identified by the BOOT2= line within.
- The primary executable name (and its path) are extracted from SYSTEM.CNF and written to a buffer.
- The contents of the primary executable are appended to the buffer.
- The buffer is hashed.
The disc metadata and primary executable are hashed as follows:
- The contents of the PSP_GAME\PARAMS.SFO file are written to a buffer. This contains the game attributes displayed in the menu, including the name and serial.
- The contents of the primary executable (PSP_GAME\SYSDIR\EBOOT.BIN) are appended to the buffer.
- The buffer is hashed.
- The first 512 bytes of sector 0 are hashed. This contains the volume header and ROM header. The first 16 bytes must be "SEGADISCSYSTEM " for Sega CD or "SEGA SEGASATURN " for Sega Saturn. If not, discard as invalid.
- Immediately following those 512 bytes are an arbitrary amount of code that validates the region and loads the primary executable. Without processing the code, we cannot determine what additional file(s) to hash, so this was determined to be sufficient as an alternative to hashing the entire CD.
The disc metadata and primary executable are hashed as follows:
- The first 512 bytes of sector 0 are appended to the buffer. This contains the volume header and ROM header. The first 16 bytes must be "SEGA SEGAKATANA ". If not, discard as invalid.
- The contents of the primary executable (as identified by the volume header) are appended to the buffer.
- The buffer is hashed.
If the size of the file is 512 bytes more than a multiple of 8KB, the first 512 bytes are ignored and the remaining file contents are hashed. If the size of the file is not 512 bytes more than a multiple of 8KB, the entire file is hashed.
- User Guidelines
- Developer Guidelines
- Content Guidelines
- FAQ
- Setup Guide
- Emulator Support and Issues
- Ways to Contribute
- RABot, the RA Discord Robot
- Events
- Overlay Themes
- Useful Links
- Contributing with the docs
- About Us
- Tutorials
- Developer Docs
- How to Become an Achievement Developer
- Getting Started as an Achievement Developer
- Game Identification
- Achievement Design
- Achievement Scoring
- Difficulty Scale and Balance
- Progression and Win Condition Typing
- Badge and Icon Creation
- Achievement Development Overview
- Flags
- BitCount Size
- Alt Groups
- Hit Counts
- Delta Values
- Prior Values
- Value Definition
- Condition Syntax
- Minimum Required Versions for Logic Features
- Memory Inspector
- Real Examples
- Set Development Roadmap
- Achievement Templates
- Tips and Tricks
- Leaderboards
- Rich Presence
- RATools
- Console Specific Tips
- Emulator Hotkeys for Developers
- libretro core support
- Docs To Do List
- WIP User Code of Conduct
- WIP CoC FAQ
- WIP Content Guidelines
- WIP-Jr
- WIP---Dev-Tips---Code-Notes-En-Masse
- WIP-‐-Reauthorship-Policy
- Manifesto RetroAchievements
- Código de Conduta do Usuário
- FAQ - Perguntas Frequentes
- Como contribuir se você não é um desenvolvedor
- Tutorial para Jogos Multi-Discos
- Introdução
- Primeiros Passos como um Desenvolvedor de Conquistas
- Recursos de Lógica para Achievements
- Exemplos Reais
- Dicas e Truques
- Dicas Específicas de Console
- Modelos de Achievement
- Escala de Dificuldade e Equilíbrio
- Roteiro de Desenvolvimento de um Set de Conquistas
- Criação de Ícones e Emblemas
- Leaderboards
- Rich Presence
- Design de Conquistas
- Manifesto RetroAchievements
- Código de Conducta del Usuario
- FAQ - Preguntas Frecuentes
- Tablas Globales y Reglas para la Casería de Logros
- Mi juego no esta cargando los logros
- Como contribuir si no eres un desarrollador
- Por que no deberías utilizar la función de cargar estado
- Contribuyendo con los documentos
- Como funciona la Documentación de RA
- Descargas
- Intro
- Código de Conducta del Desarrollador
- Como convertirme en un Desarrollador de Logros
- Primeros pasos como un Desarrollador de Logros
- Un vistazo al Inspector de Memoria
- Características en la Logica de un Logro
- Ejemplos Reales
- Intro
- Utilizando Hit Counts como un Temporizador
- Utilizando Valores Delta y Hit Counts para Detectar un Incremento
- Un Ejemplo Simple en como evitar el Abuso de Estados de Guardado
- Evitar el Problema de que un Contador se Incremente Dos Veces en el Mismo Frame
- Creando un Temporizador con un ResetIf Hits basándote en la Velocidad de un Juego
- Plantillas para Logros
- Tips y Trucos
- Escala de Dificultad y Balance
- Diseño de Logros
- Mapa de Desarrollo de Set
- Revisiones en Set de Logros
- Creación de Iconos y Badges
- Tablas de Clasificación
- Rich Presence
- Trabajando con el ROM apropiado
- Identificación del Juego
- Guía para Sets Bonus
- Logros para ROM hacks
- Tips Específicos por Consola