Game triggering event randomly: Event that causes death

Godot Version

4.3

Question

I’m making a game that only has me and an artist, and I’ve finished the game except there are so many bugs that it’s unplayable. I think that this is the biggest one. I’ve tried for days to fix it but I couldn’t fix it no matter what I tried! So now about the bug, the game is a FNAF fan game, and you have to prepare a bowl of cereal and place it in the left hallway camera when chip is in the lower front hallway. This will make chip eat it then go to the main stage. You need to pour the cereal first or you die. Now, here’s the issue: Sometimes after you make the cereal, randomly the milk and bowl of cereal with milk in it will appear and then you will die because it thought you poured the milk first. There’s a lot of code, so I’ll only give the code related to this issue. Sorry if I’m bad at describing the issue, I’m new to the godot forum and this is my first godot game.

func _on_milk_button_button_up():
if cerealDragging == false && bowlState != 2 && bowlState != 3 && makingCereal == true:
milkDragging = true;

func _on_cereal_button_button_up():
if milkDragging == false && bowlState == 0 && makingCereal == true && hasCereal == false:
cerealDragging = true;

func _on_bowl_area_area_entered(area):
if area.name == “cerealArea” && makingCereal == true:
print(“Cereal entered area.”);

	cereal.visible = false;
	cerealPour.visible = true;
	
	await get_tree().create_timer(2).timeout;
	
	if bowlState == 0:
		bowlEmpty.visible = false;
		bowlCereal.visible = true;
	
		bowlState = 1;
	
	cerealPour.visible = false;
	
	cerealDragging = false;
	
	cereal.position = Vector2(1055, 308);
	cereal.visible = true;
if area.name == "milkArea" && makingCereal == true:
	milk.visible = false;
	milkPour.visible = true;
	
	await get_tree().create_timer(2).timeout;

	if bowlState == 1 && makingCereal == true:
		bowlCereal.visible = false;
		bowlBoth.visible = true;
	
		bowlState = 3;
	
		milkPour.visible = false;
	
		milkDragging = false;
		cerealDragging = false;
	
		milk.position = Vector2(1290, 303);
		milk.visible = true;
		
		clickMe.visible = true;
		
		cerealCooldown = 5;
	elif bowlState == 0 && makingCereal == true:
		bowlEmpty.visible = false;
		bowlMilk.visible = true;
	
		bowlState = 2;
	
		milkPour.visible = false;
	
		milkDragging = false;
	
		milk.position = Vector2(1290, 303);
		milk.visible = true;

		inJumpscare = true;

		milkCrime.playing = true;
		message.playing = false;
		
		await get_tree().create_timer(6).timeout;
		
		chipJumpscare();

func _on_cereal_done_button_button_up():
if bowlState == 3 && milkDragging == false:
hasCereal = true;

	bowlState = 0;

	bowlBoth.visible = false;
	bowlEmpty.visible = true;
	clickMe.visible = false; 

	bowlTimer.visible = true;
	cerealTimerLabel.visible = true;

	cerealTimer = 10;

	cerealTimer2.start();
	
	cerealTimer = 10;
	
	cerealCounting = true;
	
	cerealTimer = 10;

I think it would help if you put a recognizable print-call in every branch of your methods and then send the output here so we can backtrack whats happening

Here is the new code and the output:

func _on_milk_button_button_up():
if cerealDragging == false && bowlState != 2 && bowlState != 3 && makingCereal == true:
milkDragging = true;

func _on_cereal_button_button_up():
if milkDragging == false && bowlState == 0 && makingCereal == true && hasCereal == false:
cerealDragging = true;

func _on_bowl_area_area_entered(area):
if area.name == “cerealArea” && makingCereal == true:
print(“Cereal entered area.”);

	cereal.visible = false;
	cerealPour.visible = true;
	
	await get_tree().create_timer(2).timeout;
	
	if bowlState == 0:
		bowlEmpty.visible = false;
		bowlCereal.visible = true;
	
		bowlState = 1;
		
		print("Bowl state is 1");
	
	cerealPour.visible = false;
	
	cerealDragging = false;
	
	cereal.position = Vector2(1055, 308);
	cereal.visible = true;
if area.name == "milkArea" && makingCereal == true:
	print("Milk in area");
	
	milk.visible = false;
	milkPour.visible = true;
	
	await get_tree().create_timer(2).timeout;

	if bowlState == 1 && makingCereal == true:
		bowlCereal.visible = false;
		bowlBoth.visible = true;
	
		bowlState = 3;
		
		print("Bowl state is 3");
	
		milkPour.visible = false;
	
		milkDragging = false;
		cerealDragging = false;
	
		milk.position = Vector2(1290, 303);
		milk.visible = true;
		
		clickMe.visible = true;
		
		cerealCooldown = 5;
	elif bowlState == 0 && makingCereal == true:
		bowlEmpty.visible = false;
		bowlMilk.visible = true;
	
		print("Bowl state is 2");
	
		bowlState = 2;
	
		milkPour.visible = false;
	
		milkDragging = false;
	
		milk.position = Vector2(1290, 303);
		milk.visible = true;

		inJumpscare = true;

		milkCrime.playing = true;
		message.playing = false;
		
		await get_tree().create_timer(6).timeout;
		
		chipJumpscare();

func _on_cereal_done_button_button_up():
if bowlState == 3 && milkDragging == false:
print(“Cereal done button up”);

	hasCereal = true;

	bowlState = 0;

	bowlBoth.visible = false;
	bowlEmpty.visible = true;
	clickMe.visible = false; 

	bowlTimer.visible = true;
	cerealTimerLabel.visible = true;

	cerealTimer = 10;

	cerealTimer2.start();
	
	cerealTimer = 10;
	
	cerealCounting = true;
	
	cerealTimer = 10;

Godot Engine v4.3.stable.official.77dcf97d8 - https://godotengine.org
Vulkan 1.3.260 - Forward+ - Using Device #1: NVIDIA - NVIDIA GeForce GTX 1060 with Max-Q Design

Cereal entered area.
Cereal entered area.
Bowl state is 1
Milk in area
Milk in area
Milk in area
Bowl state is 3
Cereal done button up
Bowl state is 2

Im not sure what exactly is causing the problems, because i dont know what you are actively doing in game and whats supposed to happen as consequenzes of your actions.

One possible problem i see is that you always create a timer and then something happens. In this time of the timer waiting there can be a new call for something to happen which might have unforseen consequenzes
My suggestion is to use a waiting-variable that is set to true when you start a timer and set to false when the timer finishes and add to every if-statement the condition “waiting” is set to false:

var waiting: bool = false

if ... and not waiting:
    ...
    waiting = true
    await get_tree()...
    waiting = false
1 Like

This fixed it! I have no idea how but it fixed it!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.