Trying to make a game, dont know how to do this part

I want to make a game similiar to wolves, if you know it then you also know it includes roles!

that part im confused on, cause i do want to assign roles to people randomly AND with a limit for each role but i do not know how

game script so far

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local function BeginGame()
	for i = 20, 0, -1 do
		task.wait(1)
		ReplicatedStorage.Status.Value = "Intermission:"..i
	end
	ReplicatedStorage.Status.Value = "Night Phase"
end

BeginGame()

local script under the text label

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local TimeLabel = script.Parent

ReplicatedStorage.Status.Changed:Connect(function()
	TimeLabel.Text = ReplicatedStorage.Status.Value
end)

for data saving/loading

local Players = game:GetService("Players")

local DataStoreService = game:GetService("DataStoreService")
local WinsDataStore = DataStoreService:GetDataStore("Data")

Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Wins = Instance.new("IntValue")
	Wins.Name = "Wins"
	Wins.Parent = leaderstats
	
	local RoleString = Instance.new("StringValue")
	RoleString.Name = "Role"
	RoleString.Parent = player
	RoleString.Value = ""
	
	local success, CurrentWins = pcall(function()
		return WinsDataStore:GetAsync(player.UserId)
	end)
	if success and CurrentWins then
		Wins.Value = CurrentWins
	else
		Wins.Value = 0
	end
end)

local function SaveData(player)
	local Wins = player:FindFirstChild("leaderstats") and player.leaderstats:FindFirstChild("Wins")
	if Wins then
		local success, err = pcall(function()
			WinsDataStore:UpdateAsync(player.UserId, function(oldValue)
				return Wins.Value
			end)
		end)
		if not success then
			warn("Failed to save data for " .. player.Name .. ": " .. err)
		end
	end
end

Players.PlayerRemoving:Connect(SaveData)

task.spawn(function()
	while task.wait(600) do
		for i, player in pairs(Players:GetPlayers()) do
			SaveData(player)
		end
	end
end)

the roles ive made in the replicatedstorage

local Roles = {
	Villager = {
		Team = "Village",
		Ability = nil
	},
	Werewolf = {
		Team = "Werewolf",
		Ability = "Kill",
		Max = 3
	},
	Seer = {
		Team = "Village",
		Ability = "Peek",
		Max = 1
	},
	Doctor = {
		Team = "Village",
		Ability = "Protect",
		Max = 1
	}
}
return Roles

i would like any help please!

the role value string, i want that to be the main thingy yaknow?
to control things, to check what role the player has, or to detect when it changes and it’ll be displayed on screen

Figured something out, should work for you, populate the player table with actual players

local players = {"Plr1","Plr2","Plr3","Plr4","Plr5","Plr6"}

local roleNameAmounts = {
	["Role1"] = 2,
	["Role2"] = 1,
	["Role3"] = 3
}

local roleDetails = {
	["Role1"] = {["Name"] = "Role1", ['Some Stat'] = "Cat"},
	["Role2"] = {["Name"] = "Role2", ['Some Stat'] = "Dog"},
	["Role3"] = {["Name"] = "Role3", ['Some Stat'] = "Chicken"}
	
}

local assignedRoles = {}

for roleName, roleAmount in pairs(roleNameAmounts) do
	
	while roleAmount > 0 do

		local curPlayer = players[1]
		table.remove(players, 1)	

		assignedRoles[curPlayer] = roleDetails[roleName]
		roleAmount -= 1
	end
end

print(assignedRoles)

I just realized I could’ve stored the role amounts inside role details and accomplish the same thing, don’t know why I didn’t do that but It’s an easy modification if you want it to work like that.

would appreciate, also tell me where i’d put this
also perhaps the role limit? if max then dont give the player this role and try a different one
cause i cant have 5 wolves out of pure luck and 1 villager (example

It’s a server script in Server Script service. The amount of each role combined has to match the number of players in the table, I didn’t make that happen automatically because I didn’t know how many or how much of each role you wanted.

You can specify number of roles, if you put only one wolf only one wolf will be assigned, the amount of each role is predetermined it’s not up to chance.

aand how do i like, use this? put it in a function?

The role amounts dictionary stores the number of each role you want

im kind of a slow learner… im sorry i dont get what you just said

I tried to simplify it by putting everything needed into one table. If something does not make sense let me know

The amountOfPlayersToAssign variable dictates how many players get that role, everything following it is optional and you can add however many key value pairs you want.

local players = {"Plr1","Plr2","Plr3","Plr4","Plr5","Plr6"}

local roleDetails = {
	["Role1"] = {["AmountOfPlayersToAsign"] = 2, ["Name"] = "Role1", ['Some Stat'] = "Cat"},
	["Role2"] = {["AmountOfPlayersToAsign"] = 3, ["Name"] = "Role2", ['Some Stat'] = "Dog"},
	["Role3"] = {["AmountOfPlayersToAsign"] = 1, ["Name"] = "Role3", ['Some Stat'] = "Chicken"}

}

local assignedRoles = {}

for roleName, statsTable in pairs(roleDetails) do

	while statsTable["AmountOfPlayersToAsign"] > 0 do

		local curPlayer = players[1]
		table.remove(players, 1)	
		
		local statsTableWithoutPlayerAmount = table.clone(statsTable)
		statsTableWithoutPlayerAmount["AmountOfPlayersToAsign"] = nil 
		assignedRoles[curPlayer] = statsTableWithoutPlayerAmount
		
		statsTable["AmountOfPlayersToAsign"] -= 1
	end
end

print(assignedRoles)

ahhh i see it now, you’re a life saver thank you ^^

1 Like

No problem, just remember the combined total number of players must match the combined total number of all roles you’re assigning.

1 Like

hmmm new problem for me, the value is being left blank when i try something like this

local Players = game:GetService("Players")

local PlayerTable = {}
for _, player in ipairs(Players:GetPlayers()) do
	table.insert(PlayerTable, player)
end

local roleNameAmounts = {
	["WereWolf"] = 3,
	["Villager"] = 20,
	["Seer"] = 1
}

for roleName, roleAmount in pairs(roleNameAmounts) do
	while roleAmount > 0 and #PlayerTable > 0 do
		local curPlayer = table.remove(PlayerTable, 1)

		local RoleValue = curPlayer:WaitForChild("Role")
		RoleValue.Value = roleName

		roleAmount -= 1
	end
end

i dont know if i ruined the script by removing most of it but yeah, the value is not changing to the name
NEVERMIND IT JUST DID IT TOO QUICKLY!

question, does this randomize the roles or fill the first role then fill the 2nd role? cause i need this to be randomized

Randomize the table of players instead, much easier. But to answer your question if the roles are 3 role A, 2 Role B and 1 Role C in that order. It will assign the first 3 players role A, the next 2 role B and the last one role C. Shuffle the player table and it will be random, I don’t know if :GetPlayers currently orders players in some way in the table it returns.

that wont work for this :sob: i need all roles to be randomized, if villager will have the most slots and there are only 10 players out of 20, then theres gonna be that many villagers