How do I stop server script from forgetting chosenPlayer after changing characters?

Ello, I’m trying to create a server script that chooses one player randomly to become the killer, and morphs them into a new model.

However, upon changing their character, the script no longer recognizes the chosen player as the killer.

I’ve tried researching DataStores and MemoryStores, but I’m not 100% sure that’s what I need.

Morph script:

local MorphEvent = game.ReplicatedStorage:FindFirstChild("MorphEvent")


MorphEvent.OnServerEvent:Connect(function(player, requestedMorphName)
	print(player.Name, "wants to morph into a ",requestedMorphName)
	if requestedMorphName == "testkiller" then 	
		local oldCharacter = player.Character
		local morphModel = game.ServerStorage.Killers:FindFirstChild(requestedMorphName)
		local newCharacter = morphModel:Clone()

		newCharacter.HumanoidRootPart.Anchored = false
		newCharacter:SetPrimaryPartCFrame(oldCharacter.PrimaryPart.CFrame)

		player.Character = newCharacter
		newCharacter.Parent = workspace
		
		oldCharacter:Destroy()
	end
end)

Server script:

Note: I removed some code that I believe is unnecessary for the forum post,
but if you need more context/code, let me know!


local Players = game:GetService('Players')
local ServerStorage = game:GetService('ServerStorage')

local mapFolder = ServerStorage:WaitForChild('Maps')
local buttonevent = game.ReplicatedStorage:WaitForChild("ButtonsEvent")

local roundActive = false


function GetPlayers()
	local list = {}
	
	for _, player in pairs(Players:GetPlayers()) do
		
		if player.Character then
			table.insert(list, player)
		end
	end
	
	return list
end

function GetPlayersInGame()
	local list = {}
	
	for _, character in pairs(workspace:GetChildren()) do
		if not character:IsA('Model') then continue end
		
		if character:GetAttribute("Survivor") then
			table.insert(list, Players:GetPlayerFromCharacter(character))
		end
	end
	
	return list
end

function SetUpKiller(Player : Player)		
	
	local Character = Player.Character

	Character:SetAttribute("Killer", true)

	script:WaitForChild("killerValues"):Clone().Parent = Character
	
	buttonevent:FireClient(Player) -- (enables killer menu, where they can choose who to be)
	
	task.wait(10)
	
	SpawnCharacters(Character)
end

Thanks for your help!

2 Likes

i’m believe the reason why this is happening is because you’re setting the killer attribute and value to the player’s old character then you delete it.

Instead, I think you should just do this:

player:SetAttribute("Killer", true)
script:WaitForChild("killerValues"):Clone().Parent = Player

that way, the attribute persist even when you delete the character

Edit: I should mention that the code you provided doesn’t actually show where/how you’re checking for the killer attribute so this may not be the solution

1 Like

I apologize, I’m still pretty new to coding.

Here is more to the serverscript:

while task.wait() do
	local playerList = GetPlayers()
	
	if #playerList >= amountToStart then
		local index = math.random(1, #playerList)
		
		roundActive = true
		
		Intermission()
		
		local chosenKiller = playerList[index]
		
		table.remove(playerList, index)
		
		workspace:SetAttribute("Status", "Loading Map...")		
		CreateMap()
		
		for _, player in pairs(playerList) do
			SetUpSurvivor(player)
		end
		
		workspace:SetAttribute("Status", "The KILLER will be coming soon...")
		SetUpKiller(chosenKiller)
		
		workspace:WaitForChild('CurrentMap'):WaitForChild('MapData'):WaitForChild('Spawn'):Remove()
		
		currentCountdownValue = ROUND_TIME 
		
		task.spawn(RunGame)
		
		repeat task.wait()
		until (#GetPlayersInGame() <= 0) or (currentCountdownValue == 0)
		
		roundActive = false
		print("game end")
		workspace:SetAttribute("Status", "Game ended")
		task.wait(5)
		
		CleanGame()
	
	else
		print("waiting for players")
		workspace:SetAttribute("Status", "Waiting for players...")
		task.wait(1)
		end
	end

I’ll look into your method in the meantime!

thanks for sending your code. I’m reading it right now and I can’t seem to find where/how its checking for the killer attribute/value. Is it possible if you could show where its being checked?

2 Likes

I am really sorry. This code uses multiple tutorials in which I combined, and while I tried to understand their code to the fullest, I’m not the best at it.

		local chosenKiller = playerList[index]
		
		table.remove(playerList, index) -- remove killer from player list

If I’m not mistaken, this is where it checks for the killer(?) (unless the code doesn’t check for the killer, I don’t really know.)

Don’t be sorry, I’m happy to help you with whatever you need!

The code you posted is where the killer is selected and then removed from the survivor list, but it doesn’t necessarily check whether a player is the killer.

I should have clarify sooner, but when I said "where/how its checking for the killer", im mostly interested in what you do with the Killer attribute and killerValues value after setting them in the
SetUpKiller() function because that might help us find where the issue is coming from.

1 Like

Currently, the killerValues folder has no use, and the Killer attribute only gets checked in the CleanGame() function, where their values get reset after the game ends.

1 Like

That means my initial assumption regarding the attribute/value were wrong.
I’m not exactly sure what the issue is. Would it be possible if you could explain how you figured out the script no longer recognizes the chosen player as the killer like do you get an error message, does the round system stops working, does a ui not show or is it something else?

The killer ui is supposed to wait 10 seconds before being disabled, yet it goes away as soon as the player clicks the button. Additionally, after the player morphs into the killer model, their Killer attribute and killerValues folder gets deleted, and they don’t get teleported into the map or get reset by the CleanGame() function.

I’d also like to mention that these issues happen permanently. Even if you wait for a game to start while already in the killer morph, it doesn’t give any attributes or folders. (Even the survivor attribute).

There are no errors.

1 Like

Never use math.random(), you should use this:

local Random = Random.new() at the top script, and everytime you use random below use
local index = Random:NextInteger(1, #playerList), because math.random sometimes isn’t random. You could use math.randomseed(tick() * time()) but this is the better solution.

2 Likes

I appreciate the tip! I’ll definitely be using this from now on.

1 Like

I believe I’ve figured out the issue!

function SetUpKiller(Player : Player)		
	
	buttonevent:FireClient(Player)
	
	task.wait(10)
 	
	local Character = Player.Character
	
	Character:SetAttribute("Killer", true)

	script:WaitForChild("killerValues"):Clone().Parent = Character
	
	SpawnCharacters(Character)
end

Using what klrh said about setting the attributes to the old character then deleting it, all I changed was move the buttonevent and task.wait(10) before it defined what the character was. Now the script works perfectly.

Thank you klrh and pro_dev!

2 Likes