Function acting on timer instantly occurs instead of waiting


#1

06%20PM

I was trying to get a door to disappear for a few seconds then come back into the game in the same spot through a factory but after the door disappears it instantly reappears except for when I set the “DOOR_INTERVAL” greater than around one billion.


#2

socket.gettime() gets the current time in seconds since the universe began. There have been many billions of seconds since the universe began, so “now > DOOR_INTERVAL” will always evaluate to true (unless DOOR_INTERVAL is huge, as you noticed).

You want to use relative timing, such as Timer, or making your own.


#3

I added the timer by @Britzl to my dependencies, but I don’t really understand how to use it and in this situation.


#4

Use:

os.clock()

To get the exact time, in seconds. To update it to the current time and keep it relevant to your ‘now’ variable, you’d want to do something like this:

local DOOR_INTERVAL = 5
local now = 0
function on_message(self, message_id, message, sender)
     if message_id == hash("create_door") then
          now = os.clock()
          DOOR_INTERVAL = DOOR_INTERVAL + os.clock()
          -- Your if statement here will only be called
          -- when the message is received, thus it will always
          -- return false, so you need
          -- a different solution:
          self.create_door = true
     end
end

-- Now in update, for your new solution:
function Update(self, dt)
     if self.create_door == true then
          if now >= DOOR_INTERVAL then
               factory.create("#doorfactory")
               self.create_door = false
          end
     end
end
          

#5

I used your setup for the timer, but it seems that the function doesn’t respond (“now” is not greater than the DOOR_INTERVAL) except for when the Interval is set to <1


#6

My bad… You have to update the now variable the same way in the update function. Otherwise it remains the same value and would never reach DOOR_INTERVAL, as you encountered. Just do the same statement in update: now = os.clock(), and that should solve your issue.


#7

I updated the function in update, but it still seems to not be working. I’ve tested everything else with the function print but the variable “now” is never greater than “DOOR_INTERVAL” even when I left it on for a while.


#8

Odd. I tested this and it works, with two changes. 1) I swapped everything in the message function to the init function, and 2) I changed the factory.create line to a print statement to do a quick test. Here’s my setup with everything working:

local DOOR_INTERVAL = 5
local now = 0

function init(self)
	self.create_door = true

	DOOR_INTERVAL = DOOR_INTERVAL + os.clock()
	now = os.clock()
end

function update(self, dt)
	if self.create_door == true then
		now = os.clock()
		if now >= DOOR_INTERVAL then
			print("We did it...?")
			self.create_door = false
		end
	end
end

If you’re still having trouble, sorry. Not much else I can do.


#9

Actually, only since EPOCH (1970-01-01) on non Windows, and 1601-01-01 on Windows. Documentation


#10

Many might consider EPOCH to be the start of a universe :smile: But yes, indeed, it’s quite a lot closer than the actual beginning of the universe.


#11

How does “now” ever reach the value “DOOR_INTERVAL” if “DOOR_INTERVAL” is set to a value + however long the CPU runs, whereas “now” is set only to the CPU run time?


#12
  1. Add Timer as a dependency in game.project
  2. Select Project->Fetch Libraries
  3. You should now see a read-only folder named “timer” in your Assets
  4. Use timer.seconds() to get a callback after a period of time has elapsed.

To hide something for a while and then show it again try this:

-- disable all components on the game object, effectively making it disappear
msg.post("door", "disable") 
-- start the timer and enable the door again when the timer triggers
timer.seconds(DOOR_INTERVAL, function()
    msg.post("door", "enable")
end)

#13

Do I have to use an “On_Message” function too or does that message automatically disable and enable objects?


#14

Automatically. https://www.defold.com/ref/go/#disable


#15

Ok it seems to be working thanks!


#17

How does “now” ever reach the value “DOOR_INTERVAL” if “DOOR_INTERVAL” is set to a value + however long the CPU runs, whereas “now” is set only to the CPU run time?

Because DOOR_INTERVAL is only initiated with the current CPU time at the point of the message. Say the game had been running for 28 seconds when the message was sent. So: DOOR_INTERVAL = 28sec (runtime) + 5sec (wait time) = 33sec. Now, in Update(), you’re updating the ‘now’ variable every frame. So: now = 28.116sec …28.232sec …and etc until it goes past 33 seconds of run time. Once it’s been 5 seconds since the message was received, the if now >= DOOR_INTERVAL statement returns true.

Anyway, glad you solved your issue.