Starte machine and timer trouble

Godot Version

godot-4

Question:

` So, I’m new to Godot. I’m not a complete beginner to programming, but I’m still close to a noob and don’t know much of the terminology yet.

Here’s the issue I’m struggling with:

I’ve started implementing my character controller using a node-based state machine (fumbling in the dark a bit here). I already had a working 2D player controller with a jump buffer and coyote time.

Now, while refactoring my code to use the state machine approach, I’ve encountered a problem with the jump buffer. By all accounts, as far as my inexperienced eyes can tell, it should work correctly, and it does about 90% of the time. However, in some cases, the buffer just doesn’t work.

In really simple terms: while in the air, if you press space, it sets buffer_on to true and starts a timer that, when done, resets buffer_on to false. If the player is on the ground (is_on_floor() == true) and buffer_on is true, the player enters the jump state. Otherwise, it goes into the landed state.

After using print commands for debugging, I noticed that in some cases, while in the air state, the check for buffer_on and is_on_floor() fails, causing the player to go into the landing state.

If anyone could take a look at the code or offer advice, I’d really appreciate it. I’m fairly new to this, so please go easy on me! `

extends State

class_name AirState


@export var ground_state : State
@export var landing_state : State
@export var jumping_state : State 
# Called when the node enters the scene tree for the first time.

# Holds the coyote timer instance so it can be disconnected or stopped.
var buffer_timer = null
var buffer_timer_started = false  # Tracks if the timer has been started





func state_process(delta):
	if character.is_on_floor():
		if not p_jump_buffered:
			next_state=landing_state
			
		else:
			# Reset buffered jump and timer before transitioning to jumping state
			p_jump_buffered = false
			reset_buffer_timer()
			print("you jumped from jump buffer")
			next_state = jumping_state
	else:
		boost_left_check()






func state_input(event : InputEvent):
	# Check if jump is pressed and buffer timer has not been started
	if event.is_action_pressed("jump_move"):
		reset_buffer_timer()
		# Start buffer timer 
		print(" you started the buffer timer")
		p_jump_buffered = true
		buffer_timer = get_tree().create_timer(character.player_jump_buffer_time)
		buffer_timer.timeout.connect(buffer_timeout)
		buffer_timer_started = true #Prevent multiple buffer timers
		
		# handles doubble jump if player has enough boost stat
		if p_can_jump:
			if character.act_boost_amount >= 1:
				boost_reduce(1)
				p_jump_buffered=false
				reset_buffer_timer()
				next_state = jumping_state
			
				
				

# check if player has boost
func boost_left_check():
	if character.act_boost_amount <= 0:
		p_jump_available = false
		p_can_jump = false
	else:
		p_jump_available = true
		p_can_jump = true 

# reduce  the amount of boost if any left
func boost_reduce(amount: int):
	if character.act_boost_amount > 0:
		character.act_boost_amount -= amount
		

# reduce the jump amount if there is any left
func jump_reduce(amount: int):
	if character.act_jump_amount > 0:
		character.act_jump_amount -= amount

func buffer_timeout() -> void:
	p_jump_buffered = false
	buffer_timer_started = false
	print('buffer time ended ended')


func reset_buffer_timer():
	if buffer_timer:
		buffer_timer.timeout.disconnect(buffer_timeout)  # Disconnect the timeout
		buffer_timer = null
	print("buffer timer reset")
	buffer_timer_started = false