How to make a one-time Intro system

I am making a game called PLACE: Reborn which is a game focused on hangout and sandbox.

I made an UI for new players to get the main idea of the game itself, however I also wanted them to be aware on keeping the game clean.

Here’s the UI so far:

Image

After waiting 20 seconds, the player can continue and will be awarded a badge for cooperation and won’t recieve the prompt ever (even after a rejoin)

The main problem is that the player can delete that specific badge from their inventory after they have complied which I want to avoid.

Scripts on how it was done:

UI script
local button = script.Parent
local event = game.ReplicatedStorage:FindFirstChild("Agreement")

for i = 20, 0, -1 do
	button.TextLabel.Text = i
	wait(1)
	
	if i == 0 then
		button.TextLabel.Text = "CONTINUE"
		button.Interactable = true
	end
end

button.MouseButton1Click:Connect(function(plr)
	event:FireServer()
	button.TextLabel.Text = "ENJOY!"
	task.wait(1)
	local tweenserv = game:GetService("TweenService")
	local info = TweenInfo.new(1.5,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut)
	local tween = tweenserv:Create(script.Parent.Parent,info, { Position = UDim2.new(0.5,0,2,0) })
	-- UI tweens to bottom after clicking button
	tween:Play()
	task.wait(2)
	script.Parent.Parent.Parent:Destroy()
end)
Server script
local badgeID = 1401345761994419
local badgeService = game:GetService("BadgeService")
local agreeEvent = game.ReplicatedStorage:FindFirstChild("Agreement")

local Players = game:GetService("Players")
local UI = script.AgreementUI

Players.PlayerAdded:Connect(function(player)
	task.wait(2)
	if not badgeService:UserHasBadgeAsync(player.UserId, badgeID) then
		UI:Clone().Parent = player.PlayerGui
	end
end)

agreeEvent.OnServerEvent:Connect(function(player)
	task.wait(3)
	if not badgeService:UserHasBadgeAsync(player.UserId, badgeID) then
		badgeService:AwardBadge(player.UserId, badgeID)
	end
end)

Any tips?

3 Likes

If you have a datastore, you can make a boolean like “awardedbadge”, then just set it to true once the player has got the badge, then just check in your badge awarding script(on join usually), if that boolean is false, and the player doesn’t have the badge, give the badge, if one of the conditions is false, don’t give the badge.

3 Likes

I’m not good at coding in general, how can this be done?

1 Like

@JAcoboiskaka1121 gave a good idea and i believe this is the best way to do it. Just setting a boolean value to true, once the player completed the tutorial. Then, save the value in your datastore, the value can be within the player, that way its safely stored, and then check if its true or false when they rejoin. This will determine if you need the tutorial to show

Heres the data store documentation if you need it

1 Like

I mean, you’ll need a datastore for any saving in general, if you don’t know that, it’ll be hard for you to set up your script/s optimally, but Ill give you a brief edit of your script on how you can do that:

local DataStoreService = game:GetService("DataStoreService")
local datastore = DataStoreService:GetDataStore("badgeSaving")

local template = { gotBadge = false } -- You can add your own keys here, or use a module.
local playerData = {} -- cache the players data.

local badgeID = 1401345761994419
local badgeService = game:GetService("BadgeService")
local agreeEvent = game.ReplicatedStorage:FindFirstChild("Agreement")

local Players = game:GetService("Players")
local UI = script.AgreementUI

Players.PlayerAdded:Connect(function(player)
	local success, result = pcall(function()
		playerData[player.UserId] = datastore:GetAsync(player.UserId) or template
	end)
	
	if not success then warn("error getting player data or said data does not exist.") return end
	
	task.wait(2)
	if not badgeService:UserHasBadgeAsync(player.UserId, badgeID) and not playerData[player.UserId].gotBadge then
		UI:Clone().Parent = player.PlayerGui
	end
end)

Players.PlayerRemoving:Connect(function(player)
		local success, result = pcall(function()
			return datastore:SetAsync(player.UserId, playerData[player.UserId])
		end)

		if not success then warn("failed to update data store") return end
		playerData[player.UserId] = nil
end)

agreeEvent.OnServerEvent:Connect(function(player)
	if not playerData[player.UserId] then return end

	task.wait(3)
	if not badgeService:UserHasBadgeAsync(player.UserId, badgeID) and not playerData[player.UserId].gotBadge then
		local awardSuccess, err = pcall(function()
			badgeService:AwardBadge(player.UserId, badgeID)
		end)
		
		if awardSuccess then
			playerData[player.UserId].gotBadge = true
			datastore:SetAsync(player.UserId, playerData[player.UserId])
		else
			warn("failed to award badge")
		end
	end
end)

Let me know if you get any errors or if something isn’t working.

2 Likes

place that script inside server script service

---this script adds a bool value in to the player that can be saved 
local DataStoreService = game:GetService("DataStoreService")
local IntroductionStore = DataStoreService:GetDataStore("IntroductionData")

game.Players.PlayerAdded:Connect(function(player)
	local data = Instance.new("Folder")
	data.Name = "data"
	data.Parent = player

	local introduction = Instance.new("BoolValue")
	introduction.Name = "introduction"
	introduction.Value = false
	introduction.Parent = data

	local success, result = pcall(function()
		return IntroductionStore:GetAsync(player.UserId)
	end)
	if success and result ~= nil then
		introduction.Value = result
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local data = player:FindFirstChild("data")
	if data then
		local introduction = data:FindFirstChild("introduction")
		if introduction then
			pcall(function()
				IntroductionStore:SetAsync(player.UserId, introduction.Value)
			end)
		end
	end
end)

all you have to do is make script change that value to what you want :smiley:

1 Like

whene changing the value make sure it is done by script not local script or it wont save

Big thanks to those who helped :)‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.