How to make a Quest System

Hi! Today I will teach you how to make a quest system. This is a series tutorial that includes quest modules, quest GUI, rewards, and datastores. Let’s begin :smiley:

~ PART 1 OF QUEST TUTORIAL SYSTEM ~

This part deals with the quest module.

First we’re going to make a module script and a remote event in the Replicated Storage. The module script contains a table of all the quest you’re going to make. This is the code:

local questModule = {
	Quests = {
		Quest1 = {
			Name = "Grab 2 bunnies",
			Reward = 50,
			Currency = "Gold"
		}
	}
}

return questModule

You can add more quests you like after Quest1. The Name variable inside Quest1 is the name of the quest. The Reward variable is the amount you’re going to add to the Currency variable. The Currency variable can be any currency you have in the player. It can be “Gold”, “Gems”, “Pets”, etc.

Now we’re going to add a normal script to an object that’s going to give you the quest. the object can be an NPC, Part, etc. But before you add the normal script, don’t forget to add a proximity prompt to the object. This is the code in the normal script:

local questModule = require(game:GetService("ReplicatedStorage"):WaitForChild("QuestModule"))
local prompt = script.Parent:WaitForChild("ProximityPrompt")
local addQuestToGUI = game:GetService("ReplicatedStorage"):WaitForChild("AddQuest")

local quest = "Grab 2 bunnies"

local number = 2

local parentName = script.Parent.Name	

local function findQuest()
	for _,questInModule in pairs(questModule.Quests) do
		if questInModule.Name == quest then
			print("Found quest")
			return questInModule
		end
	end
end

prompt.Triggered:Connect(function(player)
	if game.Players:FindFirstChild(player.Name) then
		local questFound = findQuest()
		addQuestToGUI:FireClient(player, questFound, parentName)
	end
end)

As you can see, we used require for the questModule variable since we’re getting a module script and it’s important to use require on module scripts. The prompt variable is the proximity prompt I told you before. The addQuestToGUI variable is the remote event in the replicated storage. The quest variable is the name of the quest the script is going to give to the player. The number variable is an optional variable that holds the number of objects the player is going to get. For example, the quest needs you to get 20 easter eggs, the number you put in the number variable should be 20. The parentName variable is an optional variable that contains the name of the NPC when you have the script in an NPC. The function findQuest loops through questModule.Quests (which is a table in the module script that contains the quests) to find if a quest’s Name variable is the same as the quest variable. The prompt.Triggered event fires when the proximity prompt in the object is triggered or pressed. Inside it is an if statement to check if the player who triggered the proximity prompt is still in the game. If it finds the player is still in game, it will run the code inside the if statement which is running the findQuest function and firing the addQuestToGUI remote event.

Now if we add a local script to the starter gui with this code:

local event = game.ReplicatedStorage:WaitForChild("AddQuest")

event.OnClientEvent:Connect(function(questFound, name, number)
	print(questFound.Name)
	print(name)
	print(number)
end)

It should work. Let’s test it.
RESULT VIDEO:


As you can see, it printed out the parameters we sent to the client.

I hope you learned something about this tutorial! If you liked this tutorial, please give a like and feel free to give feedback. Also, stay tuned for part 2 :smiley:

77 Likes

This was really helpful for a quest framework! Thank you

3 Likes

I’m getting the following error: Infinite yield possible on ‘ReplicatedStorage:WaitForChild(“AddQuest”)’
What did I do wrong?

Nevermind. I’m giving up on this tutorial. It assumes I know more than I do and leaves steps out. I’m a beginner.

If you want to develop Roblox games you need to learn to script a little. You can’t rely on tutorials.