What's the best way to store roles, players that have that role, and checking if a player has that role?

Storing

I wanted to make a “role” system, like discord. I want to be able to see everyone with that role, and also search by someones userId to see what roles they have. I’m guessing the best way to do this is by storing the roles a user has like this:

-- Inside of a "PlayerData" datastore
local playerDataStore = {
	["Player_849320432"] = {
		coins = 100,
		experience = 100,

		-- ...

		roles = {"CoolRole", "AnotherCoolRole"}
	}
} 

-- Inside of "SystemData" datastore
local systemDataStore = {
	bans = {"hacker23123", "c00lk1dlolzzz"},

	--- ...

	roles = {
		CoolRole = {
			Permissions = {},
			-- ...
			Players = {849320432, 940235342}, -- UserIds..
		}
	}
}

These roles will be created in-game, and also given / removed in-game. (this is why it’s all in a datastore, and not something like a modulescript)

Getting

I also wanted to get these roles, if I have an action, like banning a player, making a player jump, etc, that only can be ran by a certain role, would it be best to run two :GetAsync()s every time that action is ran, to see if the role has permission to do that + if the player has that role?

Note: Roles are going to be edited, created, and removed, frequently, players might also have new roles given and revoked from them a lot.

Does anyone have a better way of doing this? Please and thank you. :sparkling_heart:

Well rather then using getasync ever time you want to check if they have the role you could at when they join go though the role data and give the player a tag of what it is called then if they lose that role the tag is removed. When they lose a tag they could do Setaysnc to remove that role when a role is added setaysnc that new role.

First off you wanna use role ids just incase later you wanna change the name of the role. The role ids reference directly to their actual name based on settings

local ROLES = {
    [23] = "CoolRole",
    [255] = "AnotherCoolRole"
}

["Player_849320432"] = {
	coins = 100,
	experience = 100,

	-- ...

	roles = {
		[23] = {
			--- What ever role data here
		}, 
		[255] = {
			--- What ever role data here
		} 
	}
}

If the role no longer exist then you can automatically remove it from their data when they join

for _,roleId in playerData.roles do 
	if ROLES[roleId] == nil then
		playerData.roles[roleId] = nil
	end
end

Now that you have a per player system structure lets make sure we store the members within the role at a global level using an ordered datastore.

local function GiveRole(player, roleId)
       local playerData = GetPlayerData(player) -- what ever you to get the player data table reference
       local ds = DataStoreService:GetOrderedDataStore("Role_"..roleId)
       local roleMemberData = {
            --What ever data you wanna store
            RankTime = os.time(),
            RankedBy = "forbrad"
        }
       ds:SetAsync(tostring(player.UserId), roleMemberData) 
       playerData.roles[roleId] = roleMemberData 
end

Obvousily what i showed you is very vague but it can give you a general idea on how you wanna properly make a role system.

Please be aware of any rate limits you have with giving or reading roles.

1 Like