-
Notifications
You must be signed in to change notification settings - Fork 10
Circumvent the Problem of a Counter Incrementing Twice in the Same Frame
In this example you'll see how to circumvent the problem of a counter incrementing twice in the same frame by combining SubSource and AddHits.
In the Game Boy Advance library there's a Christmas platformer game called Santa Claus Jr. Advance. There are some achievements for collecting all candy canes in each one of the bonus stages.
Such achievements were supposed to be quite simple, like this:
| ID | Special? | Memory | Cmp | Type | Mem/Val | Hits |
|---|---|---|---|---|---|---|
| 1 | 0xCANDIES | != | Delta | 0xCANDIES | (N) | |
| 2 | ResetIf | 0xSTAGE | != | Value | 0xBONUS |
This translates into "check if the candy canes counter changed N times in the bonus stage".
Note: we're using 0xCANDIES != Delta 0xCANDIES (using !=, and not >) cause when the player has 99 candies and collect one more, the counter goes to zero.
However, there is an aspect in this game (and many others) where if the player collect 2 candy canes simultaneously the counter is increased by 2 in the same frame. When it happens the hit counter is increased by one while the candy counter is increased by two. This, obviously, ruins the logic used above.
In order to circumvent this issue we have to use that technique of using SubSource to count specific increments combined with the AddHits flag.
Let's take a look at the achievement logic and then we'll see the explanation:
Addresses
-
0x80dc: Candy Canes counter. -
0x809c: Stage ID.
So now the structure of the achievement is going to be like this:
Conditions
-
Together with condition 2, is a trick used to check if
0xCANDIES - Delta 0xCANDIES = 2. In other words, the candy counter was incremented by two. -
Used together with condition 1 (as explained above) and 3. As explained in its respective page, when the
AddHitscondition is true, the hit counter in the next condition is incremented. Therefore, in our example here, when condition 2 is true, the hitcounter in condition 3 is incremented. -
Count when the candy counter changes.
-
Reset the counter if not in the Bonus stage.
All these conditions could be translated as "while in the bonus stage, trigger the achievement if the candy counter changes 99 times, and if the candy counter is incremented by 2 in the same frame, count an extra change in the candy counter."
So, now it is 100% solved, right? Well, actually, almost. There is still a very minor exception. Remember it was said before that != was being used instead of > because when the player has 99 candies and collect one more, the counter goes to zero?
This means that, if we get two canes in the same frame (which is already rare), there's a very small possibility that this change will be from 98 -> 00 or from 99 -> 01. In these only two cases our code won't work, because 00 - 98 is not 2, it is -98. Same thing for 01 - 99, it is not 2, it is also -98.
Despite being a very unlikely possibility, we should treat this case too. So we're gonna add two more requirements to the code, and it will end up looking like this:
It is the same as before, with the only changes being lines 3 and 4, which represents an extra SubSource + Add Hits to check if 0xCANDIES - Delta 0xCANDIES = -98, only to take care of this very minor exception just mentioned.
And now it is solved!
- 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

