-
Notifications
You must be signed in to change notification settings - Fork 10
Console Specific Tips
When excavating the memory of these old consoles it helps to know what the original creators of the games were working with in the first place. If you familiarize yourself with the quirks of your favorite console then set making will be easier and more accurate.
When using the memory inspector to find variables for NES games, there will be 4 copies of everything you find. If you're wondering "which one do I use?" or "should I check for all of them?" it's not as complicated as it seems.
This is a feature of the NES that gave developers more ways of looking at memory. Because the NES itself only has 2KB of RAM, the first result (the one below 0x800) should be used for consistency, and applying additional conditions on the others will do nothing.
This applies to RPS and leaderboards as well.
Certain ranges of values mean different things in the context of the Game Boy hardware, so having a map of what's where can help you with eliminating useless addresses. Here's the lowdown:
- ❌ 0x0000 - 0x7FFF: ROM Data (Typically no reason to use. If you're a super-dedicated developer you could use the 16-bit value at 0x14E along with alt groups to support multiple ROM versions/regions)
- ❌ 0x8000 - 0x9FFF: Graphics Data (Some things here might correlate with what you're looking for if you're trying to find a map ID or animation, but there will always be a better way of going about what you're doing than using any of these)
- ✔️ 0xA000 - 0xBFFF: Cartridge RAM (IE. save data. Sometimes using these addresses will be unavoidable but then your set could be prone to cheating by loading 100% save files. More info on protecting against save files to come)
- ✔️ 0xC000 - 0xDFFF: Work RAM (The good stuff; almost everything you should use will fall inside this range)
- ❌ 0xE000 - 0xFDFF: ECHO RAM (Do not use, see below)
- ❌ 0xFE00 - 0xFE9F: More Graphics Data (same as Graphics Data above)
- ❌ 0xFEA0 - 0xFFFF: Miscellaneous (Do not use)
For more info see: http://gameboy.mongenel.com/dmg/asmmemmap.html
Similarly to the NES, certain variables may show up twice when searching in the Memory Inspector. The second result is in what's called the ECHO RAM, which is a mirror of the actual memory. Since some emulators tend to ignore this area or emulate it incorrectly, it's recommended to NOT use it at all and always use the first result.
The Game Boy has 4KB of RAM starting at 0xC000. ECHO RAM starts at 0xE000, so if your address begins with an E you'll want to replace the first non-zero character with a C. Remember: C is correct, E is echo!
0xD000-0xDFFF is a block of memory called the reverse echo ram. Multiple banks of memory are saved here, which will visually display as flickering. 0xFF70 (bits 0 to 2) can tell the CPU which bank of memory of memory to access. It's a "feature" used to expand the storage available to GBC ROMs while still supporting GB.
GameShark codes can be a valuable resource for finding addresses you can't or don't feel like finding. They have 12 characters per line and are fairly easy to parse.
[AA][BBBBBB] [CCCC]
[AA] is the codetype. This is a short instruction to the GameShark that defines what to do with the next value. If you understand what the GameShark code does you can use it to help with condition-making.
- 80, 88: The address is 8-bit. Sets the value [00CC] to the address [BBBBBB].
- 81, 89: The address is 16-bit. Sets the value [CCCC] to the address [BBBBBB].
- D0: The address is 8-bit. Checks if [00CC] is equal to the value at address [BBBBBB] then executes the next line if it is.
- D2: The address is 8-bit. Checks if [00CC] is DIFFERENT to the value at address [BBBBBB] then executes the next line if it is.
- D1: The address is 16-bit. Checks if [CCCC] is equal to the value at address [BBBBBB] then executes the next line if it is.
- D3: The address is 16-bit. Checks if [CCCC] is DIFFERENT to the value at address [BBBBBB] then executes the next line if it is.
Here are some examples:
- Paper Mario: Infinite HP:
[80][10F292] [0032]
Sets the 8-bit value at 0x10F292 to 0x32 (50). So this means Mario's HP is an 8-bit value at 0x10F292.
- Donkey Kong 64: Play as Rambi:
[80][74E77C] [0006]
Sets the 8-bit value at 0x74E77C to 6. So this means the character you're playing as is an 8-bit value at 0x74E77C.
- Chameleon Twist 2: Hold L to Moon Jump:
[D0][18BAB5] [0020] <- Looking at this one
[81][18B9E0] [4200]
Checks if the 8-bit value at 0x18BAB5 is equal to 0x20. This means 0x18BAB5 contains a button press variable and Bit5 (0x20) corresponds to L.
Anti-GSC and GameHacking are both good resources for finding GameShark codes.
UniBIOS allows several debugging options, and also access the database of individual cheats for every game. Therefore all achievements for Neo Geo need to be protected from abusing it. The simpliest solution here is disallowing UniBIOS usage completely, directly from the level of achievement code.
Fortunately part of UniBIOS data seems to be reflected in two address strings in the RAM: 0x00fe30
and 0x00fe50
. While UniBIOS is active 0x00fe30
in 32-bit size seems to always brings the same value (for every Neo Geo game) which is 80025632
, and it doesn't seem to change after the ROM was loaded. For any other BIOS, the value is always 0, (except for the moment the RAM is overloaded by the diagnostic program, after the ROM was loaded).
To protect achievements from using UniBIOS all we need to do is to include a simple protection which will reset when 0x00fe30
in 32-bit size is not equal to 0
. This additionally, eventually protect the achievement from unlocking during RAM diagnostic process.
Here is how the protection should look alike (selected in the Achievement Editor):
Here is how the same RAM region looks when other BIOS are used (here MSV):
- 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