-
Notifications
You must be signed in to change notification settings - Fork 10
Achievement Logic Features
There are several tools and options available to a developer. Knowing how to properly utilize them will improve the quality of your sets. These tools/options can be used in the Achievement Editor:
For more help regarding these, our Discord server is always open for assistance.
In the Achievement Editor, the field on the far right side is Hit Count.
The default is Zero, which means the condition must be true for the achievement to trigger.
If you set a target hit count, like 5, it means the condition must be true for at least that many frames, and once that hit count target is met, it doesn't need to be met again at any other time.
PLEASE NOTE: if a condition has a non-zero hit count, and reaches the number required, this condition is no longer tested. It remains true, UNLESS you have a ResetIf
, which we will discuss below.
Conditions with Reset If
and PauseIf
flags can also have hits. Follow the links for details.
- Using hit counts to detect a specific event happening multiple times
- Using hit counts as a timer
- Using hit counts to detect a status being changed multiple times
Achievements can have groups added to them that allow for alternative requirements to unlock an achievement. These are called Alt Groups,
When using Alt groups, for the achievement to trigger, all the conditions in the Core group MUST be true. And then all the conditions of ANY Alt group must be true. In other words, each Alt group uses OR
logic.
In this dummy example for Contra (NES) the achievement requires, "While on stage look up or crouch." Lets look at what's in the Core group and in the Alt groups:
In the core group: 0x18 = 5
. This checks that the player is on stage.
In Alt 01
: 0xbc = 1
. This checks that the player is looking up.
In Alt 02
: 0xbc = 2
. This checks that the player is crouching.
As long as the player is on stage. The core group is true. If the player looks up, Alt 01 is true. If the player crouches, Alt 02 is true. If core + Alt 01 OR Alt 02 are true, the achievement will trigger.
-
To add or remove Alt groups click the
+
or-
button in the bottom left of the achievement editor.
-
If you want to simply test for this
OR
that you can leave the core group blank and add this inAlt 01
, and that inAlt 02
. -
No matter how many
Alt groups
an achievement has, if the Core group is true, only one Alt has to be true for the achievement to trigger. -
When using ResetIf and PauseIf, PauseIf only pauses the group that it's in, but ResetIf resets hit counts in all groups and prevents achievements from triggering so long as the reset is active.
-
Advanced: An Alt group can have conditions that are NEVER true. When using pauses and resets in an Alt group it is possible to create a pausable reset. In other words, a reset that will only reset under certain (paused) conditions. Remember: the reset will affect all group, including your core group. This can be applied to multiple Alt groups in the same achievement. Just make sure that you have at least one Alt group that is will be true. One possible always true condition
Value 1 = Value 1
.
A Delta
value is the previous frame's value. Note: when you use Delta
it is implicit that you are referring to an address and not a value.
Examples of how it can be used:
- Detect if the level has been increased:
level > delta level
. It means "current level is greater than the previous frame's level". - Detect damage:
health < delta health
. It means "current health is smaller than the previous frame's health". Or you can just make the previous frame's value a requirement.health delta = 1
means "the previous frame's value for health must be 1 when the achievement pops up."
You can see how it works in the Real Examples page.
In the Achievement Editor, it's the field titled as Flags
If the associated condition is true, all hit counts in the achievement will be reset to 0. This includes hit counts in other groups (more about groups below).
The achievement will not trigger if one or more ResetIf
conditions is true, even if there are no conditions with hit count targets.
You can see how it works in the Real Examples page.
A Reset If
condition with a hit count target will only trigger when the hit count target is met. If another ResetIf
condition it met, all conditions, including the ResetIf
with the hit count will have their hit counts reset to 0.
It is very common to use a condition with a hit count of 1 as a start marker for an achievement, and use a ResetIf
to cancel the achievement before the end condition is met. A common example is a damageless achievement: "From start of (level/battle), reset if damage taken, trigger at end of (level/battle)". When the start condition is true, a hit count is captured. If it's still set when the end condition is true, the achievement triggers. If the ResetIf
condition triggers, the hit count on the start condition is set back to zero, which makes the condition false when evaluating the state when the end condition is true, and the achievement will not trigger.
While true, the PauseIf
pauses activity for all conditions in the same group. It does not pause conditions in other groups (more about groups below).
Note: keep in mind that all conditions in the sentence above includes ResetIf
conditions! In other words ResetIf
won't work while a PauseIf
is active.
The PauseIf
is usually used to prevent hit counts from going up during a specific situation (like pausing the game). It's used when you want to keep previously earned hit count, but don't want to increment it or reset it while something else is going on.
A PauseIf
condition with a hit count target will only trigger when the hit count target is met. Once the hit count target is met, the group remains paused until a ResetIf
condition in another group is true or until the game is reset. A PauseIf
without a hit count will unpause when the condition is no longer true.
Note: most likely this technique is not needed for simple games. So, it's not mandatory for jr-devs.
When a condition has the Add Source
flag, the value on that memory address is added to the value of the address on the condition right below, and the comparison is made on the condition below the one with the Add Source
flag. It may sound a bit confusing, but the example below will clarify how this works:
In this example the value in 0x8010
will be added to the value in 0x8020
and the comparison is if this sum is greater than zero.
If the value in 0x8010
is 1
and the value in 0x8020
is 2
, the comparison will be 1 + 2 > 0
, or 3 > 0
.
Note: All the comparison fields on the condition with the Add Source
flag are ignored.
Trying to summarize the explanation in an image:
Note: you can use the Add Source
flag to sum more addresses, like in the example below:
Note: most likely this technique is not needed for simple games. So, it's not mandatory for jr-devs.
Works similarly to Add Source
, but the Sub Source
flag makes the value in the memory address have a negative value.
Note 1: Sub Source
is NOT a subtraction flag. It just makes the value be negative.
Note 2: The final line (without Add Source
or Sub Source
) is still added for the final comparison.
Using that Add Source
usecase example, if we replaced it with the Sub Source
and with the same values (value(0x8010) = 1
and value(0x8020) = 2
), the comparison would be -1 + 2 > 0
, or 1 > 0
.
Sub Source can also be used to track specific increases in addresses. The condition below states that the current value in address 0x00cbd6
less 30
(0x1e
in hexadecimal) must be equal previous value of that same address. Effectively, this means that the condition is true whenever the value in address 0x00cbd6
increases by exactly 30.
Note: most likely this technique is not needed for simple games. So, it's not mandatory for jr-devs.
Adds the hit count for the current condition to the next achievement condition. The total hit count will be used when determining if the target hit count for the next non-Add Hits
condition is met. If the next non-Add Hits
condition does not have a hit target, the Add Hits
condition has no effect on the achievement.
All fields are supported on an Add Hits
condition. If the condition is met, the hit count for the condition is incremented (and will stop incrementing if a target hit count is specified).
The Add Hits
condition does not have to be true for the achievement to trigger. The next non-Add Hits
condition does, which is affected by the Add Hits
condition.
ResetIf
and PauseIf
can be applied to a condition following any number of Add Hits
, Add Source
, or Sub Source
conditions.
Going back to the Add Source
example above, if ResetIf
were applied to condition 2, the achievement would reset because 1 + 2 > 0
.
Feature | RA_Integration | RetroArch |
---|---|---|
ResetIf HitCount | 0.073 | 1.7.4 |
PauseIf HitCount | 0.073 | 1.7.4 |
Leaderboard Cancel AND | 0.073 | 1.7.0 |
Leaderboard OR | 0.073 | 1.7.4 |
Delay achievement processing on load | 0.073 | 1.7.4? |
Full 32-bit value support | 0.073 | 1.7.0 |
- 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