How can I create a daily chest system?

I want to create a daily chest system for my game. I dont know where to start really. I have an idea for using os.clock(), but I dont know how to progress from there. How could I create this system?

1 Like
2 Likes

Looking at the thread, it shows implementations of using a datastore system for os.date. I have never used os.date functions, so how would I be able to make a datastore similar to that?

I think you might just be confused on the vocabulary?

A DataStore can store pretty much anything. It’s just a container for data.

os.date returns a table representing a date and time. You can just store that in the DataStore.

I know what a datastore is. I am asking how would you be able to implement the system where it can check whether or not its been time to open the chest. Lets say after 24 hours

Yes, that was your original question. I linked to an answer I made to a similar question, which directly talks about how you would implement a system that runs code once every 24 hours.

Which parts specifically of that answer do you need more clarification on? It talks about how to use os.date and gives a diagram that shows what your code should do with the result of os.date.

I am most confused on how the Datastore system would work. So would I be making some type of int value and that value would be of os.time? Or for example, if I touch a part and its hasnt been 24 hours yet, I would enabled a text label saying its not time yet.

Are you asking how to store the current time in a data store?

Because you can just store the result from os.date right in the datastore

local ds = game:GetService("DataStoreService")

local store = ds:GetDataStore("LastOpenedChest")

-- store the current time in the data store...
store:SetAsync(tostring(game.Players.LocalPlayer.UserId), os.date("!*t"))

-- ...and read it back out when you need to
local lastOpened = store:GetAsync(tostring(game.Players.LocalPlayer.UserId))

So lastOpened would just be the result you originally got from os.date("!*t"), something like

{
["day"] = 19,
["hour"] = 22,
["isdst"] = false,
["min"] = 7,
["month"] = 7,
["sec"] = 12,
["wday"] = 2,
["yday"] = 200,
["year"] = 2021
}

And then you can use that like normal in the other os | Roblox Creator Documentation time-based functions, like os.difftime to get the difference between the last opened date and the current one:

local current = os.date("!*t")

local secondsPassed = os.difftime(current, lastOpened)

So does os.time continually run? Lets say the player is in game. It doesnt stop correct?

I’m a bit confused by your question.

First, I’m saying you should use os.date("!*t") instead of os.time(), so that you don’t need to worry about timezones and stuff.

Second, os.date/os.time only run when you call them. They return different things based on when you call them:

-- I know I said to use os.date but just for example's sake:

print(os.time()) -- 1626733068
wait(5)
print(os.time()) -- 1626733073

It might be worth your while to read through the documentation before going further.

It doesn’t automatically run he’s saying that when the player joins back to compare the current time to the time saved when he left/opened the daily reward

Alright I have read the documentation but still kinda confused. How will I be able detect when the player joined compared to the timer i have set.

Well if you save it with os.time() it stores the time in seconds so subtract that time by the current time (in seconds using os.time()) and then check if it’s less than or equal too 86,400 (which is 24 hours) if it is let them claim the reward again

Ok then, I will write some sample code, then get back to you. Also, how would you display the remaining time for you to open a chest, like a text label saying 24 hours left or something

Billboard GUI with a script that uses a remote event handled by the client

So no use of os.time()? how would I use the Remote Event

No you need the os.time() and datastore but your GUI would have a script that displays the saved time that the player collected their reward minus the current time. You would want to format it though.

How would I be able to format it though?

Check the dev forum I know there’s a post for that as I’ve used it in the past

I couldn’t find the one I was talking about but this seems like it should work just as well:

local TimeToStop = 86400 --Amount of seconds in one day (So it would be for daily)
function Format(Int)
	return string.format("%02i", Int)
end
function convertToHMS(Seconds)
	local Minutes = (Seconds - Seconds%60)/60
	Seconds = Seconds - Minutes*60
	local Hours = (Minutes - Minutes%60)/60
	Minutes = Minutes - Hours*60
	return Format(Hours)..":".. Format(Minutes)..":"..Format(Seconds)
end

Now all thats left to do is set the text to Format(TimeToStop)

Link to post: