Can anybody look at my code and help me figure out why my game won't start? This is the code for Main. The HUD displays on the screen and I can click the start button which makes the start button disappear, but the message stays there and the mobs never appear.

I currently have the start_game() signal connected to new_game() and _on_start_game() in an attempt to get something to work but I can't figure it out.

extends CanvasLayer

# Notifies `Main` node that the button has been pressed
signal start_game


func show_message(text):
	$Message.text = text
	$Message.show()
	$MessageTimer.start()
	
	
	
func show_game_over():
	show_message("Game Over")
	# Wait until the MessageTimer has counted down.
	await $MessageTimer.timeout

	$Message.text = "Dodge the\nCreeps!"
	$Message.show()
	# Make a one-shot timer and wait for it to finish.
	await get_tree().create_timer(1.0).timeout
	$StartButton.show()
	
	
func update_score(score):
	$ScoreLabel.text = str(score)	
	
	
func _on_start_button_pressed():
	$StartButton.hide()
	start_game.emit()

func _on_message_timer_timeout():
	$Message.hide()	
  • xyz replied to this.

    bferguso Make sure that signal is actually connected to wanted callback function. Check it in Node tab right next to Inspector tab.

      I noticed the _on_start_button_pressed signal is a slightly different name than the object ($StartButton). Did you type out the signal name by hand or connect it in the Inspector? EDIT: @xyz basically said this already. Check your signals.

      xyz So I made the connections using the inspector and also copied and pasted the code from the tutorial, no hand typing. I only hand typed one connection because you have to, and that was "new_game".

      Note: The tutorial from godotengine.org says to do the following:

      "In the Node tab, connect the HUD's start_game signal to the new_game() function of the Main node by clicking the "Pick" button in the "Connect a Signal" window and selecting the new_game() method or type "new_game" below "Receiver Method" in the window. Verify that the green connection icon now appears next to func new_game() in the script."

      I'm not able to follow the above instructions suggesting to click "Pick" and select new_game(). It's not an option after selecting pick. I can only do this the second way the instructions suggest, which says to type "new_game" below "Receiver Method", however, when I do that it doesn't seem to be actually connecting?

      On the other hand, this YouTube tutorial suggests that it ONLY works by actually typing "new_game" in the receiver method, so who knows?

      Back to my attempt:

      Here are screenshots of the StartButton and MessageTimer connections:

      Also I made a mistake in my original post, that was the code for hud, not main. Although that's probably obvious. This is the code for main:

      extends Node
      
      @export var mob_scene: PackedScene
      var score
      
      # Called when the node enters the scene tree for the first time.
      func _ready():
      	
      
      
      func game_over():
      	$ScoreTimer.stop()
      	$MobTimer.stop()
      	$HUD.show_game_over()
      
      func new_game():
      	score = 0
      	$Player.start($StartPosition.position)
      	$StartTimer.start()
      	$HUD.update_score(score)
      	$HUD.show_message("Get Ready")
      	yield($StartTimer, "timeout")
      	$ScoreTimer.start()
      	$MobTimer.start()
      
      
      func _on_score_timer_timeout():
      	score += 1
      	$HUD.update_score(score)
      
      func _on_start_timer_timeout():
      	$MobTimer.start()
      	$ScoreTimer.start()
      	
      func _on_mob_timer_timeout():
      	# Create a new instance of the Mob scene.
      	var mob = mob_scene.instantiate()
      
      	# Choose a random location on Path2D.
      	var mob_spawn_location = get_node("MobPath/MobSpawnLocation")
      	mob_spawn_location.progress_ratio = randf()
      
      	# Set the mob's direction perpendicular to the path direction.
      	var direction = mob_spawn_location.rotation + PI / 2
      
      	# Set the mob's position to a random location.
      	mob.position = mob_spawn_location.position
      
      	# Add some randomness to the direction.
      	direction += randf_range(-PI / 4, PI / 4)
      	mob.rotation = direction
      
      	# Choose the velocity for the mob.
      	var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
      	mob.linear_velocity = velocity.rotated(direction)
      
      	# Spawn the mob by adding it to the Main scene.
      	add_child(mob)
      
      
      func _on_hud_start_game():
      	new_game()

      And here is screenshots of the connection in Main

      I see what the problem is now, but I do not know how to fix it. Even though the inspector shows a connection, There doesn't seem to be a connection in the script for Main. At least, I don't think there is. In the hud script, you can see the little green connection icons on the left side of the script left of func _on_start_button_pressed(): and func _on_message_timer_timeout():. However, there isn't an icon in Main left of func _on_hud_start_game() like you would expect.

      When I had the program open last night, it wasn't showing the green connection button on any of the above. Now that I restarted my computer and the green connection button is showing (I haven't touched the file at all other than closing and reopening/exploring) I'm thinking it was glitching last night which was really throwing me off. Assuming the green connection buttons are showing accurately now, I just need to figure out why there isn't one for _on_hud_start_game():. I will work on it and see if I can come up with a solution, but does anybody have a solution in the meantime?

      I figured it out.... well sort of. I had this line yield($StartTimer, "timeout") which i added from the YouTube tutorial, which is 2 years old, not the official updated tutorial from the godotengine.org website. GoDot said 'yield' is outdated, said to use 'await'. So I changed it to 'await'. But then the debugger kept telling me that there was some syntax error, even though the game would run, just had issues with the node connections. So I commented out the entire line and all of a sudden all the connections in main appeared. The game works now! Thanks for the help everybody!

      Better to stick with 3.x if you're following a tutorial for 3.x

        xyz
        Yes you're right. I have been sticking to the most updated tutorial (I think it's actually version 4) now. However...

        I am having an even more confusing problem now. I tried to finish the tutorial by adding sounds and using the Enter key to trigger the start button, but now the Player won't appear anymore. I kept hitting undo until I went back to before making these changes... way before making these changes. All the way back to where I was when I originally made this post and.... the Player still doesn't appear. I don't understand what's going on.

        Here is the current code for main:

        extends Node
        
        @export var mob_scene: PackedScene
        var score
        
        # Called when the node enters the scene tree for the first time.
        
        		
        	
        
        
        func game_over():
        	$ScoreTimer.stop()
        	$MobTimer.stop()
        	$HUD.show_game_over()
        
        func new_game():
        	score = 0
        	$Player.start($StartPosition.position)
        	$StartTimer.start()
        	$HUD.update_score(score)
        	$HUD.show_message("Get Ready")
        	#await($StartTimer, "timeout")
        	$ScoreTimer.start()
        	$MobTimer.start()
        
        
        func _on_score_timer_timeout():
        	score += 1
        	$HUD.update_score(score)
        
        func _on_start_timer_timeout():
        	$MobTimer.start()
        	$ScoreTimer.start()
        	
        func _on_mob_timer_timeout():
        	# Create a new instance of the Mob scene.
        	var mob = mob_scene.instantiate()
        
        	# Choose a random location on Path2D.
        	var mob_spawn_location = get_node("MobPath/MobSpawnLocation")
        	mob_spawn_location.progress_ratio = randf()
        
        	# Set the mob's direction perpendicular to the path direction.
        	var direction = mob_spawn_location.rotation + PI / 2
        
        	# Set the mob's position to a random location.
        	mob.position = mob_spawn_location.position
        
        	# Add some randomness to the direction.
        	direction += randf_range(-PI / 4, PI / 4)
        	mob.rotation = direction
        
        	# Choose the velocity for the mob.
        	var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
        	mob.linear_velocity = velocity.rotated(direction)
        
        	# Spawn the mob by adding it to the Main scene.
        	add_child(mob)
        
        
        func _on_hud_start_game():
        	new_game()

        Current code for hud

        extends CanvasLayer
        
        # Notifies `Main` node that the button has been pressed
        signal start_game
        
        
        func show_message(text):
        	$Message.text = text
        	$Message.show()
        	$MessageTimer.start()
        	
        	
        	
        func show_game_over():
        	show_message("Game Over")
        	# Wait until the MessageTimer has counted down.
        	await $MessageTimer.timeout
        
        	$Message.text = "Dodge the\nCreeps!"
        	$Message.show()
        	# Make a one-shot timer and wait for it to finish.
        	await get_tree().create_timer(1.0).timeout
        	$StartButton.show()
        	
        	
        func update_score(score):
        	$ScoreLabel.text = str(score)	
        	
        	
        func _on_start_button_pressed():
        	$StartButton.hide()
        	start_game.emit()
        
        func _on_message_timer_timeout():
        	$Message.hide()	

        All the connections seem to be in place and working, but still... no Player shows up on the screen. And the screen says game over in a few seconds. I see that $Player.start($StartPosition.position) is under the new_game function, so I feel like he should be appearing. And in the 2D screen he's in the right spot.

        The code you posted is not readable. You need to place ~~~ before and after the code to display it correctly.

        But it would be better to upload the whole project folder as a .zip. Omit the .godot and .import subfolders from the .zip.

        Also specify the exact Godot version that you are using.

          DaveTheCoder Got it, thank you.

          I am using Godot version 4.0.2.

          Please let me know if this works. I omitted .godot but I didn't see a .import subfolder anywhere.

          dodge.zip
          2MB

          Thank you for your help!

          DaveTheCoder Ohhhh thank you! I was understanding the order to be the opposite! But of course that makes sense since HUD is on top of Player. Thanks again for the help!

          DaveTheCoder Sorry one last question, do you know why I can't get the music to loop? (in the file I sent you the music isn't in the code, I have it in the code now but it only plays once and stops). It is an OGG file which the documentation says should loop automatically, but when I open it in the inspector, the Loop On check box is not checked and it doesn't give me the option to check it.

          I was able to turn on looping by re-importing the .ogg file.

          Select the .ogg file in the FileSystem dock. In the Scene dock, click the Import tab. Then in the Import tab, re-import the file and set Loop to On.

          I don't know if this is a Godot bug, or a missing step in the tutorial.

            DaveTheCoder Thank you! The tutorial does not suggest importing it that way. This is the entire section on sound effects/music in the tutorial:

            "Sound and music can be the single most effective way to add appeal to the game experience. In your game assets folder, you have two sound files: "House In a Forest Loop.ogg" for background music, and "gameover.wav" for when the player loses.

            Add two AudioStreamPlayer nodes as children of Main. Name one of them Music and the other DeathSound. On each one, click on the Stream property, select "Load", and choose the corresponding audio file.

            To play the music, add $Music.play() in the new_game() function and $Music.stop() in the game_over() function.

            Finally, add $DeathSound.play() in the game_over() function."

            I tried it your way and it worked. Thanks again!