How could I keep track of Boss Fights for Progression?

I am trying to make an RPG and I want to have boss fights as a requirement to progress. I don’t want to use a badge to detect if the player has defeated a boss, because I want a player to be able to defeat a boss multiple times in case if I add some rare loot.

I was thinking of doing something with Boolean Values that are named after each boss that become enabled for the player when they beat them for the first time, but I don’t know how I’d be able to save that so they can continue off where they were before.

I was thinking I could put the Boolean Values in StarterPlayerScripts, and then use datastores or something like that, but I don’t know how I’d do it. I don’t even know if this way I am doing is too complex.

Any help would be appreciated, thank you!

I think that’s a simple way to track boss fights. Using boolean value instances seems a little extra, you could just have a ModuleScript that stores the values and handles the datastore at the same time.

I am not familiar with Module Scripts, how would I go abouts doing that?

I’d love to write a quick example for you, but I genuinely can’t restrain myself from throwing in type checking (which would easily overcomplicate the entire thing for someone who doesn’t use the type engine)
If you want, I can still try and keep it as simple as possible though.

If you dont mind, that would work. I will take a look at it and try to understand how it exactly works.

1 Like
-- ModuleScript somewhere in ServerScriptService
local Players = game:GetService("Players")
local HTTPService = game:GetService("HTTPService") -- For converting data to strings and back
local DSS = game:GetService("DataStoreService")
local BossTrackerStore = DSS:GetDataStore("BossTracker")

local bossTracker = {}

type playerData = {
    boss1 : boolean,
    boss2 : boolean,
    boss3 : boolean
}

bossTracker.Data = {} :: {[number]: playerData} -- Stores the table described above for each userId

-- Load data when player joins
Players.PlayerAdded:Connect(function(player)
	-- Create default data
	local newData : playerData = {
		boss1 = false,
		boss2 = false,
		boss3 = false
	}
	
	-- Try to load data from the datastore
	local success, storeData = pcall(function()
		return BossTrackerStore:GetAsync(player.UserId)
	end)
	
	-- If failed, assign default data
	if (not success) or (not storeData) then
		print(success, storeData)
		bossTracker.Data[player.UserId] = newData
	end
	
	-- If data is successfully decoded, assign that data
	storeData = HTTPService:JSONDecode(storeData) :: playerData
	if storeData then
		bossTracker.Data[player.UserId] = storeData
	end
	
end)

-- Save data when player leaves
Players.PlayerRemoving:Connect(function(player)
	local currentData = bossTracker.Data[player.UserId] -- Get the data currently in the table
	local encoded = HTTPService:JSONEncode(currentData) -- Encode into a string to store in the datastore
	
	local success, err = pcall(function()
		BossTrackerStore:SetAsync(player.UserId,encoded)
	end)
	if not success then print(err) end -- Print the error if it didn't succeed
end)

return bossTracker



-- Some other server-side script
local BossTracker = require(game.ServerScriptService.BossTracker) -- Get the ModuleScript
...
...
local function setBoss1Defeat(player)
	BossTracker.Data[player.UserId].boss1 = true -- Set the value of boss1 for the given player to true
end
local function setBoss2Defeat(player)
	BossTracker.Data[player.UserId].boss2 = true
end

I’m not exactly experienced with datastores (had to take a look at the documentation) so there might be some hiccups, but this code should work. I also tried to comment it as best as I could to help you understand what’s going on.
If there’s anything else, let me know.

1 Like

I think I can understand it, it uses booleans to track 3 bosses so far and uses datastores to check if they are completed or not.

Do you know how I’d be able to set these booleans to true when the player beats a boss? The bosses are NPCs with broken AI and buffed health, for context.

And to check if a player has beaten a boss, do I do DSS:GetDataStore(“BossTracker”) (in a different script, in lets say a door), and check if, for example, boss1 = true then the door opens?

Thank you for the help.

You can simply just directly access the value in BossTracker.Data, as shown at the bottom of the code.

Oh, so I’d in a script, check if the boss has 0 health then do setBoss1Defeat()?

Would the code be something like this?

– Script placed inside humanoid

script.Parent.Died:connect(function()
if script.Parent:FindFirstChild(“creator”) then
setBoss1Defeat(script.Parent.creator.Value.userId)
end
end)

or would this code not work?

That would work, yes, but you don’t have to necessarily call that function, you can just directly do BossTracker.Data[script.Parent.creator.Value.UserId].boss1 = true

I’m sorry for bugging you again, but do you know how I’d be able to call the modulescript from a click detector?

Here is my code for the click detector:
local badgeId = 947048343416658
local badgeServ = game:GetService(“BadgeService”)

local BossTracker = require(game.ServerScriptService.BossTracker) – Get the ModuleScript

script.Parent.MouseClick:Connect(function(player)
print(“Clicked”)
player.Data.MeleeXP.Value = player.Data.MeleeXP.Value + 500
player.Data.Beli.Value = player.Data.Beli.Value + math.random(1000,3000)

print("Awarded Money")

BossTracker.Data[player.UserId].boss1 = true

print("Setboss1totrue")

badgeServ:AwardBadge(player.UserId, badgeId)
print("Vanquished the Queen Bee!!!!")



wait(0.01)
script.Parent.Parent:Destroy()

end)

It looks like it gets stuck where I call in the module script.

Is the module script in ServerScriptService, or somewhere else? Try using game:GetService("ServerScriptService") instead of game.ServerScriptService

It is in Server Script Service. It does not work when I try to use GetService instead. It gives me multiple errors stating “Requested Module was requested recursively”

That error shows when the module you require() also has a require() to a script that (at some point) has a require() back to that module. I don’t know how all of your code looks so I can’t find it for you, you’ll have to find the problem line yourself.

The module doesn’t have a require() though.

Found out the problem. Httpservice was called HTTPService instead of HttpService. Thank you!

1 Like

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