Why signal sometime worked sometime not?

Godot Version

4.3

Question

why signal sometime worked sometime not?
as you can see in my code, signal Trigger_Every_12_Hour_Signal() sometime work sometime not.
you can try it by run it , then click x100 . if it worked , close the game then restart it again,
have 50-50 chance the signal wont tringger.
why this happend and what should i do?
this just replica from my game.
this main code

extends Node
#1/5 * INGAME_TO_REAL_MINUTE_DURATION
@export var gradient_texture:GradientTexture1D
const MINUTES_PER_DAY = 1440
const MINUTES_PER_HOUR = 60
const DAY_PER_SEASON = 2
const SEASON_PER_YEAR = 4#four season
#### 1 minute in game == 0.00436332312999 in rl ,example  5minute = 0.02181661564995
const INGAME_TO_REAL_MINUTE_DURATION = (2 * PI) / MINUTES_PER_DAY
var time :float = 0.0
var past_minute :int= -1

var world_current_total_day : int# the real day count
var world_current_hour : int
var world_current_minute : int
var world_total_current_minute : int
var world_current_day_in_season : int# not the real count, because +1day , so can display day1  insted 0day
var world_current_year : int

signal time_tick(day:int, hour:int, minute:int)
@warning_ignore("unused_signal")
signal Stop_Time_Circle()
@warning_ignore("unused_signal")
signal Start_Time_Circle()
signal Trigger_Every_12_Hour_Signal()
signal Trigger_Every_New_Day()


@export var INGAME_SPEED  = 1.0
@export var INITIAL_HOUR  = 8:
	set(h):
		INITIAL_HOUR = h
		time = INGAME_TO_REAL_MINUTE_DURATION * MINUTES_PER_HOUR * INITIAL_HOUR


func _ready() -> void:
	time = INITIAL_HOUR

func set_new_time_date():
	time = INGAME_TO_REAL_MINUTE_DURATION * MINUTES_PER_HOUR * INITIAL_HOUR

func _process(_delta: float) -> void:
	time += _delta * INGAME_TO_REAL_MINUTE_DURATION * INGAME_SPEED
	_recalculate_time()


func _recalculate_time() -> void:
	var total_minutes = int(time / INGAME_TO_REAL_MINUTE_DURATION)
	var day = int(total_minutes / MINUTES_PER_DAY)#1440 / 60 = 1
	var current_day_minutes = total_minutes % MINUTES_PER_DAY#when reach 1440(total minute in a day) it become 1
	var hour = int(current_day_minutes / MINUTES_PER_HOUR)
	var minute = int(current_day_minutes % MINUTES_PER_HOUR)
	
	if past_minute != minute:
		past_minute = minute
		time_tick.emit(day, hour, minute)
		if hour == 12 and minute == 0: 
			Trigger_Every_12_Hour_Signal.emit()
			print("Trigger at 12.0")
		if hour == 0 and minute == 0 : #24:00
			Trigger_Every_12_Hour_Signal.emit()
			print("Trigger at 0.0")
			
		
		world_current_total_day = day
		world_current_hour = hour
		world_current_minute = minute
		world_total_current_minute = total_minutes
		world_current_day_in_season = (world_current_total_day % DAY_PER_SEASON)+1
		world_current_year = int( world_current_total_day / (DAY_PER_SEASON*SEASON_PER_YEAR) ) 



func add_minute( _minute : int ) -> void :
	time += INGAME_TO_REAL_MINUTE_DURATION * _minute

func get_hour_text() -> String:
	if world_current_hour == 0:
		return str(24)#12 = 24:00
	if world_current_hour < 10 :
		#exmple 01:00 , 02:00
		return "0" + str(world_current_hour)
	#exmple 12:00 , 10:00
	return str(world_current_hour)

func get_minute_text() -> String:
	if world_current_minute < 10:
		return "0" + str(world_current_minute)#06 , 07 , 08
	return str(world_current_minute)


func _on_x_100_pressed() -> void:
	INGAME_SPEED = 100.0


func _on_x_1_pressed() -> void:
	INGAME_SPEED = 1.0

this label code

extends Label



func _ready() -> void:
	$"..".connect("time_tick", minute_trigger)
	$"..".connect("Trigger_Every_12_Hour_Signal" , trigger_signal_test_12_hour )
	pass # Replace with function body.

func minute_trigger( _day : int , _hour:int , _minute : int):
	text = $"..".get_hour_text() + ":" + $"..".get_minute_text()

func trigger_signal_test_12_hour():
	print("trigger from lbl node")
	$"../Label2".text = "trigger from lbl node"

func _input(event: InputEvent) -> void:
	if event.is_action_pressed("R_mouse"):
		print( $"..".is_connected("Trigger_Every_12_Hour_Signal" , trigger_signal_test_12_hour ) )

My guess is that all the conversion you’re doing means that sometimes your minutes are jumping from 59 to 1 due to rounding errors. To test this, write something like:

		if hour == 12:
			print("Hour 12 Minute %" % [minute])
			if minute == 0: 
			Trigger_Every_12_Hour_Signal.emit()
			print("Trigger at 12.0")
		if hour == 0:
			print("Hour 0 Minute %" % [minute])
			if minute == 0 : #24:00
			Trigger_Every_12_Hour_Signal.emit()
			print("Trigger at 0.0")

Watch and see what numbers are being output for minute.

I’d recommend simplifying your timekeeping. Create a timer that tracks the in-game 12-hours, and trigger off that. That will free up a lot of extra processing power. You’re currently doing the time conversion 60 times a second. For your clock labels, just set an in-game minute timer and in-game hour timer. When they go off, trigger a signal and have that update your labels.

1 Like

thank you. i see the problem now.

1 Like

Glad to help!