-
Notifications
You must be signed in to change notification settings - Fork 10
WIP ‐ How Does RetroAchievements Work
RetroAchievements (RA) provides users the ability to earn achievements in retro games from an RA achievement set. It awards achievements by comparing a game’s memory, henceforth referred to as RAM, to achievement code written by an RA developer. Achievement code, also known as logic, is a list of memory conditions chosen by the developer, that when all are simultaneously true on a single frame, will award an achievement.
An achievement set is the compilation of individual achievements, rich presence and leaderboards for a particular game. Achievements are comprised of achievement logic, a title, a description, a point value and a badge. Additionally, a set must contain a Rich Presence script which provides site users information on where active players are in a game. Sets may have leaderboards that track how well players perform in certain things in a game such as how quickly they can beat stages, how many points they can score and many other things. RA users interface with all these components and subcomponents. Each one is a vital part of the player experience.
RA code is a custom text based language that is interpreted by RA supporting emulators. Developers write code using either the Achievement Editor in the RAIntegration toolkit or by using RATools, a standalone executable that provides a scripting language for achievement development. Both the achievement editor and RATools produce code that is used for all achievements, leaderboards and Rich Presence.
A game’s RAM is its most basic form. RAM is simply the game's memory addresses and their respective values at any given time. When processed by a console or emulator, the RAM can be used to recognize what is happening within the game. Games are processed in a series of frames, generally 60, 50, 30 or 25 per second depending on console and format. RA processes all unearned achievement logic in a set every frame. Because of this, developers can create logic such that when all of its conditions are simultaneously true, identify something uniquely precise happening in a game and award an achievement, activate a leaderboard and provide accurate Rich Presence. It is an achievement developer’s job to understand enough of a game's RAM to be able to construct this logic.
Understanding how the RAM works that a developer intends to use in their logic is essential to creating a stable set that awards achievements, submits leaderboard scores and accurately displays Rich Presence only as intended. RA developers use developer emulator tools to inspect a game's RAM and determine which addresses are responsible for things they intend to use for logic. Developers have many ways to precisely define exactly which memory conditions must be true in order to construct logic, including retaining knowledge that something occurred previously in memory, but may no longer be true.
As a simple example, to award an achievement for obtaining the hammer in Zelda II: The Adventure of Link, a developer would need to figure out which memory addresses within the game were associated with a few unique things about obtaining the hammer. There are often many ways to do this. One way a developer might approach this achievement is to find the addresses for the room ID to ensure the player is in the room with the hammer, also perhaps an area ID to ensure the player is in the right section of the game and lastly an address that indicates whether the player actually gets the hammer. The reason a room and area ID are important is because when a player loads a save file that has collected the hammer, the memory would indicate that possessed of the hammer goes from untrue to true, but this isn't where the achievement should award. The room and area ID conditions would ensure that a player was actually obtaining the hammer in game and not just loading a save file that already possessed it. A solid achievement could be constructed to award when the following is true simultaneously:
Room ID = room the hammer is in
Area ID = area of game the hammer is in
Possesion of hammer changes from not possessed to possessed
Here is what this achievement would look like in the Achievement Editor
In this example, address 0x0561 is the room ID and its value is 0x15 when the player is in the room with the hammer, address 0x076e is the area ID and its value is 0x02 when in Death Mountain where the hammer is located and Bit0 of address 0x078b indicates if the player has the hammer. This bit changes from 0 to 1 when the player acquires the hammer, so the achievement checks for a frame where this bit is greater than it was the previous frame which is precisely when the hammer is obtained since bits can only be either 1 or 0. If all three conditions are true on the same frame, the achievement is awarded. This can only happen when the player obtains the hammer while in the hammer room in Death Mountain, not at some other time such as loading a save file.
Every frame the player is playing the game, the RAM is being compared to the achievement logic to check if all conditions are true on that frame. For this example achievement, all conditions can only be true on the same frame when a player is in the room and area where the hammer is obtained and the player obtains the hammer. When that happens, all of the conditions defined in the logic will be true and the achievement will be immediately awarded.
Leaderboards function quite similarly to achievements in terms of logic, but need a list of conditions to tell the leaderboard when to activate, when to cancel itself, and when and what value to submit to the leaderboard. Creating a leaderboard is essentially like creating a few small achievements that will be processed sequentially.
Rich Presence code is very similar to achievement and leaderboard code, but is written slightly differently due to the way it is handled by the site. Rich Presence is written and submitted to RA as a script, as opposed to a string of code like achievements and leaderboards. It still uses the same fundamental code as achievements and leaderboards, but has some additional features such as custom macros that may be used.
The key to writing solid code is to first understand what in RAM can be used to recognize a particular game event for which a developer intends to award an achievement, use for a leaderboard or Rich Presence. The next steps are finding the necessary memory addresses and their values to recognize when the event occurs and constructing logic to create a list of conditions that will only be simultaneously true on the intended frame.
- 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