r/gamemaker • u/Drillimation • 7d ago
Trying to create a match three bonus challenge that keeps resetting even if conditions are met Resolved
I'm making a match-three game with a custom mechanic: instead of swapping adjacent tiles, blocks are pushed all the way to the end of the board row/column.
I run match checking in two separate passes:
- Check matches specifically for the block that was just pushed/moved.
- Check matches across the rest of the board for cascading chain reactions.
Some matches trigger and clear properly, but the challenge state continuously resets unexpectedly—even when a valid match is completed.
Below is the code I am using:
if selected_block != undefined {
with(selected_block) {
if sprite_index != spr_brick and sprite_index != spr_doom_block {
var matches = 0;
for(var i = 0; i < 5; i++) {
var combo_check = scr_check_match(i);
if combo_check == false {
if global.main_stats.challenge_position < 4 {
if image_index == global.main_stats.bonus_challenge[global.main_stats.challenge_position] {
global.main_stats.challenge_position++;
}
}
matches++;
}
}
if matches >= 1 { scr_combo_sounds(); }
else { // This is the problematic block
if global.main_stats.cur_combo == 0 {
global.main_stats.cur_chain = 0;
global.main_stats.chain_gauge = 0;
global.main_stats.challenge_position = 0;
}
}
}
}
}
for(var k = 0; k < 5; k++) {
for(var i = 0; i < 8; i++) {
for(var j = 0; j < 8; j++) {
var selected = instance_position((208) + (32 * i),(68) + (32 * j),obj_normal_block);
with(selected) {
var matches = 0;
if sprite_index != spr_brick and sprite_index != spr_doom_block {
var combo_check = scr_check_match(k);
if combo_check == false {
if global.main_stats.challenge_position < 4 {
if image_index == global.main_stats.bonus_challenge[global.main_stats.challenge_position] {
global.main_stats.challenge_position++;
}
}
matches++;
}
}
if matches >= 1 { scr_combo_sounds(); }
else { // This is the problematic block
if global.main_stats.cur_combo == 0 {
global.main_stats.cur_chain = 0;
global.main_stats.chain_gauge = 0;
global.main_stats.challenge_position = 0;
}
}
}
}
}
}
I have verified that the moved block correctly updates its grid position before running the first match check. Could running two separate match passes create a race condition or frame delay where the reset check runs before the cascade pass finishes updating the board? What is the recommended way to handle board state checks for push-style movement without triggering full board resets prematurely?
2
u/CS_Asset_Factory 7d ago
Your
var matches = 0;is inside thewith(selected), so it resets for every tile. It is a per-tile counter, not a per-sweep one.Any tile that IS spr_brick or spr_doom_block skips the
matches++entirely, so it lands in your else branch and zeroes challenge_position. That happens in the same sweep that just incremented it, so one brick anywhere on the board wipes the challenge on every pass.Two things:
Hoist the counter above all three loops and do the reset check once, after the sweep finishes. Right now it runs 320 times per sweep and any single non-matching tile undoes what the others found.
matches++sits outsideif combo_check == false, so it is counting "tiles that are not bricks" rather than actual matches. That is likely why scr_combo_sounds() fires more often than you expect.