I didn’t manage to patch the bug with gold not adding so ignore the gold falling from the sky
The Test place https://www.roblox.com/games/6786571483/Quest-Test (Uncopylocked Place Verison)|
Quest_Test.rbxl (56.9 KB) - Just View output log to see what is actually happening
You will need to access API services to test because the test utilizes datastore’s but the datastores will wipe everytime a player joins repeat what happened
Please note: These are just an example of just how to start this isn’t a full-fledge system to take and use willy nilly
QuestManager Module
local QuestModule = {}
local DataManager = require(game.ServerScriptService.DataManagers.DataManager) -- // A module that has been set up to use ProfileService by Loleris
local QuestDetails = require(game.ServerScriptService.InformationModules.QuestDetails) --// Quest Info Module
function QuestModule.StartQuest(Player,Quest_ID)
local Profile = DataManager.GetStatisticProfile(Player)
local Data = Profile.Data
local Quests = Data.Quests
for QuestIndex,Quest in pairs(Quests) do
print(QuestIndex,Quest)
if Quest and Quest.ID ~= Quest_ID then --// Checking if already has quest even if its completed or not // not allowing any copies of the same quest
else
warn(Player.Name.. " Already has this quest")
return
end
end
local QuestAmount = table.getn(Quests) --// Amount of Quests
local Quest = {} --// Table being stored in Datastore
Quest.ID = Quest_ID --// Storing the ID of quest
Quest.Prog = {} --// Table of Quest Progress // Can be shorten to just P if desired
Quest.TS = os.time() --// TimeStamp of when quest has begun
table.insert(Quests,QuestAmount+ 1,Quest)--//Adding Quests to datastore // ProfileService will do all the work Datastores
end
function QuestModule.ClearQuest(Player,Quest_ID) --// Clears Quest when its complete setting prog table to true // to save space in the datastore
local Profile = DataManager.GetStatisticProfile(Player)
local Data = Profile.Data
local Quests = Data.Quests
for QuestIndex,Quest in pairs(Quests) do print(QuestIndex,Quest)
if Quest.ID == Quest_ID and Quest.Prog ~= true then --// Checking if QuestID Matchs
Quest.Prog = true --// Setting progress to tree meaning quest is completed // Wont be the same if ur not using profile service
local QuestInfo = QuestDetails.Get_Quest_FromID(Quest.ID) --// Fetches Info
print("CONGRATS!!! | ", "Quest Completed: " ..QuestInfo.Quest_Name.. " | Rewarding ",QuestInfo.QuestRewards)
--// You can add code to give out rewards for completed quest within this if statement
end
end
print(Quests)
end
function QuestModule.Check(Player,KeyName,Value)
local Profile = DataManager.GetStatisticProfile(Player)
if not Profile then return end
local Data = Profile.Data
local Quests = Data.Quests
if #Quests == 0 then print(Player.Name .. " has no quests")
else
for QuestIndex,Quest in pairs(Quests) do
if Quest and Quest.Prog ~= true then
local QuestInfo = QuestDetails.Get_Quest_FromID(Quest.ID) --// Fetches Requirements
for K, V in pairs(QuestInfo.QuestRequirments) do
if K == KeyName and QuestInfo.QuestRequirments[KeyName] then --// Checking if Data being changed is accurate to Requirements KeyName
if V == Value then --// Quest requirements meet // Clearing quest // This can use more work
QuestModule.ClearQuest(Player,Quest.ID)
else
Quest.Prog[KeyName] = Value
end
end
end
end
end
end
end
return QuestModule
I attempted to comment as much as possible
QuestDetails Module
local QuestDetails = {}
QuestDetails.Q1 = {
Quest_Name = "The Quest of Time / 40 Seconds",
Quest_ID = 1,
QuestRequirments = {
SecondsPlayed = 25
},
QuestRewards = {"Goodies","Trophy"}
}
QuestDetails.Q2 = {
Quest_Name = "The Quest of Time / 50 Seconds",
Quest_ID = 1,
QuestRequirments = {
SecondsPlayed = 50
},
QuestRewards = {"Goodiesx2","Trophyx2"}
}
QuestDetails.Q3 = {
Quest_Name = "The Quest for GOLD",
Quest_ID = 1,
QuestRequirments = {Gold = 5},
QuestRewards = {"Gold Trophy","Rewards"}
}
function QuestDetails.Get_Quest_FromID(ID)
local ID = "Q"..ID
for QuestID,Quest in pairs(QuestDetails) do
local ID_Prefix = string.find(QuestID,'Q')
if ID_Prefix == 1 then
if type(Quest)== "table" and QuestID == ID then
return Quest
end
end
end
end
function QuestDetails.Get_Quest_FromName(Name)
for QuestID,Quest in pairs(QuestDetails) do
if type(Quest)== "table" and Name == Quest.Quest_Name then
return Quest
end
end
end
return QuestDetails
How I used QuestManager
In my StatManager module I added QuestManger.Check() This will check if the value of Stat being changed and see if it matches the quest requirements value. This will NOT be a fix-all solution because sometimes quest requirements will be met and the values will not match.
Here is an example of using QuestManger.Check() after setting a value
QuestModule.Check(Player,"SecondsPlayed",SecondsPlayed)--// Checking After setting Data
Every time SecondsPlayed was changed I ran QuestManger.Check() to see if it met quest requirements.
Important part of QuestModule.Check()
if #Quests == 0 then
print(Player.Name .. " has no quests") --// Checks if there are any quest active
else
for QuestIndex,Quest in pairs(Quests) do --// Looping through Quests to find Quests Inprogress
if Quest and Quest.Prog ~= true then
local QuestInfo = QuestDetails.Get_Quest_FromID(Quest.ID) --// Fetches Requirements
for K, V in pairs(QuestInfo.QuestRequirments) do --// Looping Through Quest Requirements to compare values
if K == KeyName and QuestInfo.QuestRequirments[KeyName] then --// Checking if Data being changed is accurate to Requirements KeyName
if V == Value then --// Quest requirements meet // Clearing quest // This can use more work
QuestModule.ClearQuest(Player,Quest.ID) --// Req are met so Clearing quest and Granting rewards
else
Quest.Prog[KeyName] = Value --// Setting Quest Values to store progress made
end
end
end
end
end
end
To add quests I made QuestManager.StartQuest(Player,QuestID)
For example how of I added a quest 1-3
local QuestManager = require(game.ServerScriptService.DataManagers.QuestModule)
Players.PlayerAdded:Connect(function(Player)
QuestManager.StartQuest(Player,1) --// Added quest via ID QuestManager.StartQuest(Player,QuestID)
QuestManager.StartQuest(Player,2)
QuestManager.StartQuest(Player,3)
end)
How can I tell if it WORKS?!?!
https://gyazo.com/862b93c8588756f159d7d1c20a07fe1c.gif - Gif of what occurs
As you can see it counts to 25
QuestDetails.Q1 = {
Quest_Name = "The Quest of Time / 40 Seconds",
Quest_ID = 1,
QuestRequirments = {
SecondsPlayed = 25
},
QuestRewards = {"Goodies","Trophy"}
}
Quest one requirement is 25 seconds
-
You can see that name of quest is printed as well as a table of the rewards
-
Below that you can see that the progress is set to true meaning the quest is completed
-
Below that you can see quest two with a progress of 24 seconds will soon reach the goal of 50 seconds
QuestDetails.Q2 = {
Quest_Name = "The Quest of Time / 50 Seconds",
Quest_ID = 1,
QuestRequirments = {
SecondsPlayed = 50
},
QuestRewards = {"Goodiesx2","Trophyx2"}
}
You may be asking How can it see the quest info?
A function in QuestDetails module called QuestDetails.Get_Quest_FromID(Quest.ID) returns the questinfo table
local QuestInfo = QuestDetails.Get_Quest_FromID(Quest.ID) --// Fetches Info
print("CONGRATS!!! | ", "Quest Completed: " ..QuestInfo.Quest_Name.. " | Rewarding ",QuestInfo.QuestRewards)