FrostyCat
Redemption Seeker
Restricting Unwanted Repetition with Flags
GM Version: All
Target Platform: All
Download: N/A
Links: N/A
Summary: A summary of flag patterns for GML development.
Introduction
This guide documents 4 commonly used flag patterns for general GML development. Protecting one-time actions against repetition is an essential mastery for all skill levels and helps avoid many common bugs.
What is a Flag?
A flag is simply a variable indicating the status of something. You can use flags to hold over a status from previous steps, so that currently running code can reference what has happened in the past. One of the most commonly referenced properties of the past is whether an action has already been conducted. By checking and updating this, you can accurately control the recurrence of one-time actions.
Symptoms of Unwanted Repetition
Pattern 1: Anti-Recurrence Flags
Anti-recurrence flags can be used to perform an action only when a condition transitions from false to true. In GM development, this is most common in collisions, where the condition is a collision-checking function like place_meeting().
General pattern:
Sometimes both the false-to-true and true-to-false transitions have associated actions. In these situations, you can use two flags together, one with the current state (is-flag) and another with the previous step's state (was-flag). If the previous and current states don't match, act according to the current state.
General pattern:
Rate-capping flags can be used to slow down the recurrence of a repeated action below once per step while a condition is true. This is most commonly used to control rate of fire.
General pattern:
Rolling sum flags can be used to perform an action every time a numeric value counts past an interval boundary. This is most commonly used to award lives or other rewards at fixed point intervals (e.g. every 10000 points for Pacman).
General Pattern:
GM Version: All
Target Platform: All
Download: N/A
Links: N/A
Summary: A summary of flag patterns for GML development.
Introduction
This guide documents 4 commonly used flag patterns for general GML development. Protecting one-time actions against repetition is an essential mastery for all skill levels and helps avoid many common bugs.
What is a Flag?
A flag is simply a variable indicating the status of something. You can use flags to hold over a status from previous steps, so that currently running code can reference what has happened in the past. One of the most commonly referenced properties of the past is whether an action has already been conducted. By checking and updating this, you can accurately control the recurrence of one-time actions.
Symptoms of Unwanted Repetition
- Spammed graphical or sound effects (e.g. a trail of effects or repeated sounds like "o-o-o-o-o-ow!").
- Variables increasing or decreasing by many times more than the amount specified in your code.
- Variables being disregarded or treated like 1 when counting down.
- Alarm not counting down despite being set.
- Staying still or moving in a straight line despite starting a non-linear path.
Pattern 1: Anti-Recurrence Flags
Anti-recurrence flags can be used to perform an action only when a condition transitions from false to true. In GM development, this is most common in collisions, where the condition is a collision-checking function like place_meeting().
General pattern:
Pattern 2: Was-Is FlagsCreate:
Step:Code:flag = true;
A common variation leaves out the else completely, preventing the action from running again on future false-true transitions.Code:if (condition) { if (flag) { /* One-time action */ flag = false; } } else { flag = true; }
Sometimes both the false-to-true and true-to-false transitions have associated actions. In these situations, you can use two flags together, one with the current state (is-flag) and another with the previous step's state (was-flag). If the previous and current states don't match, act according to the current state.
General pattern:
Pattern 3: Rate-Capping FlagsCreate:
Step: (Recall: ^^ is XOR, which gives true when either operand is true but not both)Code:was_flag = condition; is_flag = was_flag;
End Step:Code:is_flag = condition; if (was_flag ^^ is_flag) { if (is_flag) { /* false-to-true action */ } else { /* true-to-false action */ } }
Code:was_flag = is_flag;
Rate-capping flags can be used to slow down the recurrence of a repeated action below once per step while a condition is true. This is most commonly used to control rate of fire.
General pattern:
Pattern 4: Rolling Sum FlagsLet INTERVAL be the number of steps between recurrences. To convert a rate to an interval, take its reciprocal (INTERVAL = 1/RATE).
Create:
Step:Code:flag = INTERVAL;
A common variation is to reset the flag to 0 instead of INTERVAL for a more immediate response.Code:if (condition) { if (flag <= 0) { /* Repeated action */ flag += INTERVAL; } else { flag -= 1; } } else { flag = INTERVAL; }
Rolling sum flags can be used to perform an action every time a numeric value counts past an interval boundary. This is most commonly used to award lives or other rewards at fixed point intervals (e.g. every 10000 points for Pacman).
General Pattern:
Let the numeric value start counting from INITIAL_VALUE and the action recur after every increase of INTERVAL.
Create:
Step:Code:number = INITIAL_VALUE; next_trigger_flag = number+INTERVAL;
Code:if (number > next_trigger_flag) { /* Action */ next_trigger_flag += INTERVAL; }
Last edited: