Daily & weekly quest system

I’m trying to make a daily and weekly quest system that resets every 24 hours for the daily quests and resets every 7 days for the weekly quests and have the part where it gets a total of 6 random quests from a dictionary and adds them to a table. I have no idea where to go from here really and don’t know how os.time works.

What I have so far:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local QuestsDaily = require(ReplicatedStorage.Databases.QuestsDaily)

local dailyQuestsTable = {}

local categorys = {"Power Quests", "Punching Quests", "Gathering Quests"}

while #dailyQuestsTable < 6 do
	local category = categorys[math.random(1, #categorys)]
	local quest = QuestsDaily[category][math.random(1, #QuestsDaily[category])]

	if not table.find(dailyQuestsTable, quest) then
		table.insert(dailyQuestsTable, quest)
	end
end

print(dailyQuestsTable)

The players quest GUI:
image

The quests dictionary in a ModuleScript:

local QuestsDaily = {
	["Power Quests"] = {
		{
			Name = "Daily Training I",
			Description = "Gain 1M Power",
			PowerNeeded = 1000000,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Training II",
			Description = "Gain 1B Power",
			PowerNeeded = 1000000000,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Training III",
			Description = "Gain 1T Power",
			PowerNeeded = 1000000000000,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Training IIII",
			Description = "Gain 1Q Power",
			PowerNeeded = 1000000000000000,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},
	},

	["Punching Quests"] = {
		{
			Name = "Daily Punching I",
			Description = "Punch 100 Times",
			PunchesNeeded = 100,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Punching II",
			Description = "Punch 250 Times",
			PunchesNeeded = 250,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Punching III",
			Description = "Punch 750 Times",
			PunchesNeeded = 750,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Punching IIII",
			Description = "Punch 1,500 Times",
			PunchesNeeded = 1500,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},
	},

	["Gathering Quests"] = {
		{
			Name = "Daily Gathering I",
			Description = "Collect 50 Orbs",
			OrbsNeeded = 50,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Gathering II",
			Description = "Collect 150 Orbs",
			OrbsNeeded = 150,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Gathering III",
			Description = "Collect 350 Orbs",
			OrbsNeeded = 350,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},

		{
			Name = "Daily Gathering IIII",
			Description = "Collect 550 Orbs",
			OrbsNeeded = 550,
			Rewards = {
				{
					rewardType = "Tokens",
					value = 50,
				}
			}
		},
	},
}

return QuestsDaily

Basically you’d have to store, likely in a dictionary, in a datastore the name of the quest and the os.time of when it was completed (unless you want the progress to reset daily as well), everytime the player joins check if the time passed between the current os.time and the stored os.time is higher than 24 hours (in seconds so 86400 seconds), in that case 24 hours have passed so you can remove the quest from the datastore (or reset its progress).
For the weekly ones follow the same procedure except it will be 7 days in seconds (86400 * 7 = 604800)

2 Likes

Well aside from having almost no idea how to do that. What I need to do right now is find a way to get the contents of the dailyQuestsTable to save and sync between all servers and somehow display each quest in the table to the clients guis. And also reset the dailyQuestsTable every 24 hours.

You could store the day they log in by doing this:


local date = os.date("*t")
DataStore:SetAsync(plr.UserId, date)

And then check if a day has passed with something like this

local lastLoginDate = DataStore:GetAsync(plr.UserId)
local date = os.date("*t")

if
   (
        (
             date.day - lastLoginDate.day == 1 and
             date.month == lastLoginDate.month
        ) or
        (
             date.day - lastLoginDate.day == date.day and
             date.month - lastLoginDate.month == 1
        )
   ) and
   (
        date.year - lastLoginDate.year == 0 or
        date.year - lastLoginDate.year == 1
   )
then
   --A day has passed!
end

Displaying the available quests on the client is actually fairly simple. Cycle through your module that has all the details and update the UIs on the client. I assume you’d use that frame with the “Name” and “Description” labels as template, you could clone that for each quest and change the name/description based on the info from the module

to save and sync between all servers

Not quite sure what you mean by that but if you mean syncing the progress, using datastores will work

having almost no idea how to do that

Your dictionary would basically be structured like this:

-- the zeroes be an os.time number
local playerQuests = {
   ["Daily Training I"] = 0000000,
   ["Daily Training II"] = 0000000,
}

You’d save it and get it from a DataStore. For example, when a quest is completed:

local QuestStore = game:GetService("DataStoreService"):GetDataStore("Quests")
local currentQuests = QuestStore:GetAsync(player.UserId)
currentQuests = currentQuests or {} -- sets it to an empty table in case the player has no data
currentQuests[questName] = os.time() -- replace questName with the name of the quest that was completed, be it 'Daily Training I' or whichever one it is
QuestStore:SetAsync(currentQuests)

Everytime the player join you’d then check every quest and their os.time() with the current os.time()

local QuestStore = game:GetService("DataStoreService"):GetDataStore("Quests")
local currentQuests = QuestStore:GetAsync(player.UserId)
currentQuests = currentQuests or {}
for questName, completionTime in currentQuests do
   if os.time() - completionTime >= 86400 then -- a day has passed so the player can get the daily quest again
      currentQuests[questName] = nil
   end
end