Roblox Admin Commands Guide
Roblox admin commands allow players to moderate the game’s experience. Players with admin privileges can kick or ban players that harm the experience for others. We can also set up different types of roles for different types of players. Each role has its own set of abilities.
What you’ll learn
- Store and manage player privileges
- How to use the command design pattern
- Build your own custom commands
- How to use the HD Admin plugin
Create a custom player role system
Let’s go over how we can build our own player role system to manage access levels and command privileges. If you rather not use someone else’s plugin or script, then you should use your own that is trustworthy.
Different types of player roles
The first type of player role is the administrator. An administrator has nearly full control of the game.
Above all other roles, we have the owner account. The owner account has full unfettered access to all Roblox admin commands and abilities.
A developer is another type of role where they may have some admin privileges or could have full admin rights. The developer role gives a player the abilities they need to build or test game features. You can set up this role system in a private server so developers can only change the game in a test environment instead of using your production environment.
The moderator role allows a player to take on the responsibility of maintaining a safe and fair environment for all players. Moderators should have the ability to kick, ban, mute players, or place players into a temporary holding area.
A premium player role is used for those players that have a premium Roblox subscription. With this role, we can grant access to exclusive content or give special commands. These commands should make the game more exciting and fun but not give them a major advantage against normal players.
A normal role is any player that joins that does not fit any other role. Player’s with a normal role have limited privileges and access.
What is the command design pattern?
The command design pattern is a behavioral pattern where an object contains all necessary info to perform an action. Such info includes the object to perform an action on or different parameter values to use.
With the command pattern, we can implement several features such as storing a history of actions or changes for player privileges. Having a history log allows you to audit or review changes which are great for the security of your game’s experience. You can set up a logging system by having all commands go through a central server script that validates and runs all commands.
The pattern works by having a common interface for the objects that set up and create commands and objects that will manage and execute these commands. Other objects that run the command only need to use this common interface (a common set of function names) without knowing the actual internal workings of the command.
Organizing player privileges
With each role, we can assign different commands that they have the power to use. We’ll define a few objects to set this up. Commands must get defined within a server script to prevent exploiters from decompiling it as a local script. Local scripts should only send minimal information required to start a command. Server scripts should receive this info to validate and then call the desired function or event.
First, let’s define the command object.
local Command = {}
local function Command:new()
local o = {
Name = "",
SentBy = nil
}
self.__index = self
return metatable(o, self)
end
local function Command:execute()
-- add command logic
end
Next, let’s define the player role object.
local PlayerRole = {}
local function PlayerRole:new()
local o = {
Name = "",
Commands = {}
}
self.__index = self
return metatable(o, self)
end
local function PlayerRole:CanUse(command)
local playerCanUse = false
for i, command in ipairs(self.Commands) do
if command.Name == commandName then
playerCanUse = true
break
end
end
return playerCanUse
end
Let’s use an enum object to define all command names.
local CommandsEnum = {
KickPlayer = 1000,
BanPlayer = 1001,
AwardGold = 2000,
WithdrawGold = 2001
}
Here’s an example admin role object.
local AdminPlayerRole = PlayerRole:new()
AdminPlayerRole.Name = "admin"
AdminPlayerRole.Commands = { CommandsEnum.KickPlayer, CommandsEnum.BanPlayer }
We’ll need an object to collect and run our commands. We’ll use a remote event to validate the player’s role can use the command. Once validated, we’ll use a command factory to create the command object and add the command to our runner’s command array.
local CommandRunner = {}
local function CommandRunner:new()
local o = {}
o.Commands = {}
self.__index = self
return metatable(o, self)
end
local function CommandRunner:Execute()
for i, command in ipairs(self.Commands) do
command.Execute()
self.Command[i] = nil
end
end
local runner = CommandRunner:new()
-- Receive command event
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerCommandEvent = Instance.new("RemoteEvent", ReplicatedStorage)
PlayerCommandEvent.Name = "PlayerCommand"
local function onPlayerCommandFired(player, eventData)
-- validate player’s role can use command
-- create command using a command factory with eventData.CommandName
-- add command to runner
table.insert(runner.Command, newPlayerCommand)
end
PlayerCommandEvent.OnServerEvent:Connect(onPlayerCommandFired)
while true do
runner:Execute()
end
Here’s an example command to kick a player from the server.
local KickPlayerCommand = Command:new()
function KickPlayerCommand:new()
local o = {}
o.Name = CommandsEnum.KickPlayer
o.PlayerToKick = nil
o.Command = "/kick "
o.KickMessage = ""
self.__index = self
setmetatable(o, self)
end
local Player = game:GetService("Players")
function KickPlayerCommand:Execute()
if self.PlayerToKick
-- kick player
self.PlayerToKick:Kick(self.KickMessage)
end
end
Player role security
All commands should run through a server-side script to limit exploiters from sending unauthorized commands. This goes especially for actions that affect player state and data. Data would include any player progress or in-game currency that they’ve earned.
Server script logic must validate that a player’s command comes from an authorized user. To validate these commands, we can use their role that’s stored in the game’s data store.
Storing player privileges
Depending on the player size of your game, we can use different methods of storing player roles and privileges.
The simplest method is to have it all done in the script. Though this is limited by how easily we can update the data. With this method, all data will live in server memory. So if a server goes down that will effectively delete this data.
Using this simplified method, we can have a single owner or admin that can invoke commands to update this data in server memory.
A more robust solution would use Roblox data stores. Instead of relying on just the owner, you can give control to players you trust instead. Within the data store, we’ll have objects that contain which roles each player has. All role logic exists in scripts that rely on this data to control who has access.
Player authorization data store script
We’ll first define the Player authorization service constructor function.
local DataStoreService = game:GetService("DataStoreService")
local PlayerAuthorizationErrors = {
NOT_ADMIN = 1000
}
local PlayerAuthorizationService = {}
local function PlayerAuthorizationService:new()
local o = {}
o.datastore = DataStoreService:GetDataStore("PlayerAuthorization")
self.__index = self
return setmetatable(o, self)
end
local function PlayerAuthorizationService:_createPlayerModel()
return {
PlayerId = nil,
Name = "",
Role = nil
}
end
local function PlayerAuthorizationSevice:GetPlayerModelById(playerId)
local model = o.datastore:GetAsync("player_" .. playerId)
model.Role = RoleFactory:GetRole(model.Role.Name)
return model
end
local function PlayerAuthorizationService:CreatePlayerModel(player, role)
local model = self:_createPlayerModel()
model.PlayerId = player.UserId
model.Name = player.DisplayName
model.Role = RoleFactory:GetRole(role)
return model
end
local function PlayerAuthorizationService:RequestorIs(requestor, role)
local requestor = o.datastore:GetAsync("player_" .. requestor.UserId)
return requestor.Role.Name == role
end
-- validate CRUD operations of requestor is an admin
local function PlayerAuthorizationService:ValidateAdminRequestor(requestor)
return self:RequestorIs(requestor, "admin")
end
The ValidateAdminRequestor function confirms that the player making sensitive data changes such as adding new player records has the admin role. Use the RequestorIs function to restrict functions to other roles.
local function PlayerAuthorizationService:AddPlayer(requestor, player, role)
if self:ValidateAdminRequestor(requestor) then
local model = self:CreatePlayerModel(player, role)
o.datastore:SetAsync("player_" .. player.UserId, model)
return model
end
error({ code = PlayerAuthorizationErrors.NOT_ADMIN, message = "requestor is not authorized" } )
end
The command runner can use the CanUse function to validate that the player has the correct role to use the desired command.
local function PlayerAuthorizationService:CanUse(player, command)
-- check that player has given command
local model = self:GetPlayerModelId(player.UserId)
return model.Role:CanUse(command)
end
We’ll use a separate module script to create a role factory object. The factory pattern simplifies creating role object models that use a common interface.
-- new module script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Roles = ReplicatedStorage:WaitForChild("Roles")
local RoleFactory = {}
local function RoleFactory:new()
local o = {}
self.__index = self
return setmetatable(o, self)
end
local function RoleFactory:GetRole(rolename)
if rolename == "admin" then
return Roles.AdminRole
elseif rolename == "owner" then
return Roles.OwnerRole
elseif rolename == "moderator" then
return Roles.ModeratorRole
elseif rolename == "developer" then
return Roles.DeveloperRole
elseif rolename == "premium_player" then
return Roles.PremiumPlayerRole
else rolename == "normal_player" then
return Roles.NormalPlayerRole
end
end
return RoleFactory
How to run Roblox admin commands
Using the Roblox chat system is the easiest method to run commands. Another option is to use a Gui.
Use the Roblox chat system to run commands
We’ll use the Player.Chatted event to parse out commands.
local Player = game:GetService("Players")
local Commands = {
KickPlayer = "/kick "
}
local function stringMatches(input, shouldMatch)
return input:sub(1, shouldMatch:len()):lower() == shouldMatch:lower()
end
local function onPlayerChatted(player, message, recipient)
local command = nil
if stringMatches(Commands.KickPlayer) then
command = KickPlayerCommand:new()
command.PlayerToKick = player
command.KickMessage = player.Name .. " has been kicked!"
end
if command then
-- validate player can use the command
local playerCanUseCommand = PlayerAuthorizationService:CanUse(player, command.Name)
If playerCanUseCommand then
command:Execute()
end
end
end
local function onPlayerAdded(player)
player.Chatted:Connect(onPlayerChatted)
end
Player.PlayerAdded:Connect(onPlayerAdded)
Use a Gui to run commands
Now that we have a player command authorization service, we can create any type of front end or GUI interface to interact with it.
The first option could include a /admin command to display the admin console. It’s important to note that the authorization service acts as the main gatekeeper when running any commands.
Any admin UI must exist as a local script, making it accessible to exploiters if not built correctly. So instead of thinking of it as “the player wants to run this command”, think of it as “can this player use this command?”.
Using Roblox HD Admin
HD Admin gives you a lot out of the box. You can easily set up player roles, create custom commands, custom events, and change the appearance of players.
How to add HD Admin to your Roblox game
- To add HD admin to your game, add it to your inventory.
- In a new or existing game, open up the explorer
- Select the inventory tab
- Once you’ve found HD Admin in your inventory, add it to your game’s workspace
- Now you can load up your game, set up different player roles, and commands
Check out their tutorials for more information.
What’s Next
You now understand how to organize and provide the tools to different types of players so all players have a great experience in your game. Remember to code defensively when giving other players control of powerful Roblox admin commands and abilities.
Please consider joining my email newsletter for future updates and content!
Thank you for reading and stay curious!