Skip to main content
About this guide

Time to complete: 3min
Difficulty: Medium

Setting up Khol's admin

Here's a guide on how to install and properly configure khol's admin for your game and unlock the full potential of the terminal.

Insert the model​

Get the model from the official website and put it in ServerScriptService.

Basic configuration​

Open the Settings file under Config > Settings and replace it with this config:

Configuration
--[[ DEFAULT ROLES
┏━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ RANK ┃ ROLE ┃ DETAILS ┃
┣━━━━━━━━━╋━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ inf ┃ creator ┃ Can do everything, automatically given to the creator of the group/game. ┃
┃ 4 ┃ superadmin ┃ Can permanently role users, change settings, shutdown servers, give badges, and use commands globally. ┃
┃ 3 ┃ admin ┃ Can permanently ban users and give roles per server. ┃
┃ 2 ┃ mod ┃ Can kick and server ban with other potentially abusive commands. ┃
┃ 1 ┃ vip ┃ Can only use commands on themselves, limited to non-abusive cosmetic commands. ┃
┃ 0 ┃ everyone ┃ The default role, limited to basic features. ┃
┗━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
--]]

return {

-- ⛔ BAN DATABASE
-- Format: ["UserId"] = {Username, Reason, Duration, BannedByUserId}
-- Duration: -1 = permanent, 0 = server ban, >0 = temp ban (UTC timestamp)
bans = {
},

-- 👤 USER ROLES - Assign roles by UserId or Username
userRoles = {
vip = {},
mod = {},
admin = {},
superadmin = {},
creator = {},
},

-- 📦 ASSET ROLES
assetRoles = {
-- [assetId] = { "vip", "mod" },
},

-- 💵 GAMEPASS ROLES
gamepassRoles = {
-- [gamepassId] = { "vip", "mod" },
},

-- 💳 SUBSCRIPTION ROLES
subscriptionRoles = {
-- [subscriptionId] = { "vip", "mod" },
},

-- 🏢 GROUP ROLES
groupRoles = {
-- [groupId] = {
-- { rank = 200, roles = { "vip", "admin" }, exactRank = false },
-- },
},

-- 👥 FRIEND ROLES
friendRoles = {
-- "vip",
},

-- 👑 FREE ADMIN ROLES - ⚠️ Affects all players
freeAdmin = {
-- "vip",
-- "mod",
-- "admin",
},

announcements = {
-- {
-- From = "_K", -- userId or "_K"
-- Duration = 30, -- seconds, 0 = no auto-hide
-- Text = "Hi!",
-- },
},

notifications = {
-- {
-- From = "_K", -- userId or "_K"
-- Duration = 30, -- seconds, 0 = no auto-hide
-- Text = "Hi!",
-- },
},

-- 🔧 SYSTEM SETTINGS
prefix = { ";", ":" }, -- Command trigger characters
splitKey = "%s", -- Command/argument separator

commandBarRank = 0, -- Minimum rank for Command Bar (false = disable)
dashboardRank = 0, -- Minimum rank for Dashboard (false = disable)
dashboardButtonRank = false, -- Minimum rank for Dashboard button (false = disable)
joinNotificationRank = false, -- Minimum rank for join notifications (false = disable)

welcomeBadgeId = 0, -- Badge for new players (0 = none)

addToCharts = false, -- Add this game to the Kohl's Admin Charts (⚠️ Requires "Allow HTTP Requests" in File > Game Settings > Security) https://roblox.com/games/17873329124/Kohls-Admin-Charts
vip = false, -- Enable VIP features (⚠️ Required if addToCharts is true)

chatCommands = true, -- Enable commands via chat
commandRequests = false, -- Request commands on same/higher rank
onlyShowUsableCommands = false, -- Show only purchasable/usable commands
getKohlsAdminPopup = false, -- Show the Get Kohl's Admin popup
wrongPrefixWarning = true, -- Warn on incorrect prefix
saveLogs = true, -- Save/sync logs across servers

theme = "Default", -- Initial theme (customize in Config.Themes)
changeThemeAuthority = "Client", -- "Client", "Server", or "Studio"

commands = { -- Configure command access per role
everyone = {
help = true,
shutdown = false,
},
vip = {},
mod = {},
admin = {},
superadmin = {},
creator = {},
},

-- 🎭 ROLE CONFIGURATION
roles = {
{ -- Default Role
_key = "everyone", -- ⚠️ DO NOT CHANGE

name = "Player",
color = "#aaa", -- Hex color only

groups = {
-- "creator", -- clearlogs, hidelogs, script, localscript, etc.
-- "superadmin", -- badge, clearterrain, reserve, shutdown, global, etc.
-- "administration", -- announce, role, btools, gear, insert, place, serverlock, etc.
-- "moderation", -- ban, kick, jail, teleport, mute, warnings, etc.
-- "environment", -- fix, lighting, gravity, wind, water, atmosphere, etc.
-- "general", -- respawn, refresh, spectate, view, vote, xray, etc.
-- "fun", -- disco, explode, clone, punish, zombie, etc. (abusive)
-- "vip", -- appearance, accessories, animations, particles, etc.
"utility", -- help, version, info, logs, etc. (safe basics)
},

limits = {
cooldown = 4, -- Cooldown period in seconds
commands = 4, -- Max commands per cooldown
targets = 1, -- Max targets per command
},

permissions = {
admin = false, -- ⚠️ Bypasses all permissions
banasync = false, -- Saved bans
saveRoles = false, -- Saved roles
settings = false, -- Saved settings
serverlogs = false, -- Server logs
},

onlyTargetSelf = true, -- Can only use commands on self
},

{ -- VIP Role
_key = "vip", -- ⚠️ DO NOT CHANGE
name = "VIP",
color = "#0ff",
groups = { "vip" },
limits = { cooldown = 4, commands = 16, targets = 1 },
permissions = {},
onlyTargetSelf = true,
},

-- 🎭 Create as many roles as you want!
-- Use the _key in other settings like friendRoles to auto give the role
-- Helper would be higher rank than VIP, and lower than moderator

-- {
-- _key = "helper",
-- name = "Helper",
-- color = "#080",
-- groups = { "general" },
-- limits = { cooldown = 4, commands = 32, targets = math.huge },
-- permissions = { serverlogs = true },
-- },

{ -- Moderator Role
_key = "mod", -- ⚠️ DO NOT CHANGE
name = "Moderator",
color = "#0f0",
groups = { "moderation", "general", "environment", "fun", "vip" },
limits = { cooldown = 4, commands = 32, targets = math.huge },
permissions = { serverlogs = true },
},

{ -- Administrator Role
_key = "admin", -- ⚠️ DO NOT CHANGE
name = "Administrator",
color = "#fc0",
groups = { "administration", "moderation", "general", "environment", "fun", "vip" },
limits = { cooldown = 4, commands = 64, targets = math.huge },
permissions = { banasync = true, serverlogs = true },
},

{ -- SuperAdmin Role
_key = "superadmin", -- ⚠️ DO NOT CHANGE
name = "SuperAdmin",
color = "#f80",
groups = { "superadmin", "administration", "moderation", "general", "environment", "fun", "vip" },
permissions = { banasync = true, saveRoles = true, settings = true, serverlogs = true },
},

[math.huge] = { -- Creator Role (Highest Authority)
_key = "creator", -- ⚠️ DO NOT CHANGE
name = "Game Creator",
color = "#f00",
permissions = { admin = true },
},
},
}

Configure group permissions​

In your settings file, locate the group roles table and edit it according to the example:

-- 🏢 GROUP ROLES
groupRoles = {
-- [groupId] = {
-- { rank = 200, roles = { "vip", "admin" }, exactRank = false },
-- },
},

Add custom commands​

You can add custom commands by creating a module script in the Config > Addons folder.

Examples​

Team chat toggle command
return function(_K)
local TextChatService = game:GetService("TextChatService")
local isTeamChatEnabled = false

local function setupServer()
local general = TextChatService:WaitForChild("TextChannels"):WaitForChild("RBXGeneral") :: TextChannel
general.ShouldDeliverCallback = function(message:TextChatMessage, source:TextSource)
if(isTeamChatEnabled)then
local player = game:GetService("Players"):GetPlayerByUserId(message.TextSource.UserId)
if(message.TextSource.UserId == source.UserId)then
_K.Remote.Notify:FireClient(player,{
From = "_K",
Text = `<font color="rgb(255,125,0)">Your message was not sent because teamchat only mode is enabled !</font>`,
})
end


return "BLOCKED"
else
return true
end
end
end

local function runServer(context, enable)
if(enable ~= nil)then
isTeamChatEnabled = enable
else
isTeamChatEnabled = not isTeamChatEnabled
end
context._K.Remote.Notify:FireAllClients({
From = "_K",
Text = `<b>Team chat {isTeamChatEnabled and "enabled" or "disabled"}</b>`,
})
end

local arg = {
type = "boolean",
name= "enable",
description= "Wether to enable or disable the team chat only mode",
optional= true,
}
local command = {
name = "Teamchat",
aliases= { "tc" }, -- Table of aliases.
description= "Toggle team chat only mode", -- Description of what the command does.
group= "moderation", -- What group the command belongs to.
noLog= false, -- If the command should be hidden from logs.
args= { arg }, -- A table of argument definitions.
permissions= { }, -- A table of role permissions required to run the command.
envClient=nil, -- Sets up an environment for the command.
env=setupServer, -- Sets up an environment for the command.
runClient=nil, -- What runs on the client of the player that ran the command.
run=runServer -- What the command runs on the server.
}



_K.Registry.registerCommand(_K, command)
end
Server lock toggle command
local GROUP_ID = 10055198
local MINIMUM_RANK = 110 -- Minimum rank in the group to join when the lock is active


return function(_K)
local isGroupLockEnabled = false

local groupInfo = game:GetService("GroupService"):GetGroupInfoAsync(GROUP_ID)

local minRank
for i,rankData in pairs(groupInfo.Roles) do
if(rankData.Rank > MINIMUM_RANK)then
minRank = rankData
break
end
end

local function setupServer()
game.Players.PlayerAdded:Connect(function(player:Player)
if(isGroupLockEnabled == true)then
local rankInGroup = player:GetRankInGroup(GROUP_ID)
if(rankInGroup < MINIMUM_RANK)then
player:Kick(`Grouplocked server ! You must be {minRank.Name}+ in {groupInfo.Name} to join !`)
end
end
end)
end

local function runServer(context, enable)
local addText = ""
if(enable ~= nil)then
isGroupLockEnabled = enable
else
isGroupLockEnabled = not isGroupLockEnabled
end
if(isGroupLockEnabled == true)then
addText = `<br />Only <font color="rgb(18,221,201)"><b>{minRank.Name}+</b></font> from <font color="rgb(18,221,201)"><b>{groupInfo.Name}</b></font> can join`
end
context._K.Remote.Notify:FireAllClients({
From = "_K",
Text = `<b>Group lock {isGroupLockEnabled and "enabled" or "disabled"} !</b>{addText}`,
})
end

local arg = {
type = "boolean",
name= "enable",
description= "Wether to enable or disable the group lock",
optional= true,
}
local command = {
name = "grouplock",
aliases= { "gc" },
description= "Toggle server group lock",
group= "moderation",
noLog= false,
args= { arg },
permissions= { },
envClient=function() print("Grouplock command made by Omega77073") end,
env=setupServer,
runClient=nil,
run=runServer
}



_K.Registry.registerCommand(_K, command)
end
Group lock command


local BYPASS_GROUPS = {} -- Default list of allowed groups IDs, cannot be modified in-game









local allowedGroups = {}


local groupLockAllowed
local httpService = game:GetService("HttpService")
local groupService = game:GetService("GroupService")
return function(_K)
local isGroupLockEnabled = false

local groupIdType = {
filterLog = true,
transform = function(v)
return if v == "" then 0 else tonumber(v)
end,
validate = function(v)
return v ~= nil and v == math.floor(v), "Only whole numbers are valid"
end,
parse = function(v, self)
local s,r = pcall(groupService.GetGroupInfoAsync, groupService, v)
if(s)then
return r
end
if self.definition.optional and self.rawArg == "" then
return ""
end
return nil, "Invalid group"
end,
suggestions = function(text)
return { if tonumber(text) then text else nil }
end,
}
local function setupServer()

groupLockAllowed = Instance.new("StringValue")
groupLockAllowed.Name = "GroupLockAllowed"
groupLockAllowed.Parent = game.ReplicatedStorage
groupLockAllowed.Value = httpService:JSONEncode(allowedGroups)

game.Players.PlayerAdded:Connect(function(player:Player)
if(isGroupLockEnabled == true)then
for _,allowedGroupId in pairs(BYPASS_GROUPS)do
if(player:GetRankInGroup(allowedGroupId) > 0)then
return
end
end

for _,allowedGroup in pairs(allowedGroups)do
if(player:GetRankInGroup(allowedGroup.id) > 0)then
return
end
end

player:Kick(`Grouplocked server ! You cannot join unless you are in one of the whitelisted groups.`)
end
end)
end

local function runServer(context, enable)
if(enable ~= nil)then
isGroupLockEnabled = enable
else
isGroupLockEnabled = not isGroupLockEnabled
end
context._K.Remote.Notify:FireAllClients({
From = "_K",
Text = `<b>Group lock {isGroupLockEnabled and "enabled" or "disabled"} !</b>`,
})
end


local arg = {
type = "boolean",
name= "enable",
description= "Wether to enable or disable the group lock",
optional= true,
}
local command = {
name = "grouplock",
aliases= { "gc" },
description= "Toggle server group lock",
group= "moderation",
noLog= false,
args= { arg },
permissions= { },

envClient=function() print("Grouplock command made by Omega77073") end,
env=setupServer,
runClient=nil,
run=runServer
}


local arg2 = {
type = "groupId",
name= "groupId",
description= "The id of the whithelisted group",
optional= false,
}
local command2 = {
name = "grouplock-add",
aliases= { "gcadd","gc+" },
description= "Add a group to the group lock whitelist",
group= "moderation",
noLog= false,
args= { arg2 },
permissions= { },
envClient=nil,
env=nil,
runClient=nil,
run=function(context, groupData)
table.insert(allowedGroups, {
id = groupData.Id,
Name = groupData.Name
})
groupLockAllowed.Value = httpService:JSONEncode(allowedGroups)
context._K.Remote.Notify:FireClient(context.fromPlayer,{
From = "_K",
Text = `<b>Added <font color="rgb(18,221,201)">{groupData.Name}</font> to the group lock whitelist</b>`,
})
end,
}

local arg3 = {
type = "groupLockIdType",
name= "group",
description= "The id or name of the group to remove from the whitelist",
optional= false,
}
local command3 = {
name = "grouplock-remove",
aliases= { "gcremove","gc-" },
description= "Add a group to the group lock whitelist",
group= "moderation",
noLog= false,
args= { arg3 },
permissions= { },
envClient=nil,
env=nil,
runClient=nil,
run=function(context, groupData)
for i,group in pairs(allowedGroups)do
if(group.id == groupData.id)then
table.remove(allowedGroups, i)
end
end
groupLockAllowed.Value = httpService:JSONEncode(allowedGroups)
context._K.Remote.Notify:FireClient(context.fromPlayer,{
From = "_K",
Text = `<b>Removed <font color="rgb(18,221,201)">{groupData.Name}</font> from the group lock whitelist</b>`,
})
end,
}


local groupLockGroupIdType = {
filterLog = true,
transform = nil,
validate = function(v)
local allowedGroups = game:GetService("HttpService"):JSONDecode(game.ReplicatedStorage.GroupLockAllowed.Value)
for _,group in pairs(allowedGroups)do
if(string.sub(tostring(group.id),1,#v) == tostring(v) or string.sub(string.lower(group.Name),1,#v) == string.lower(v))then
return true
end
end
return false, "Group not found"
end,
parse = function(v, self)
local allowedGroups = game:GetService("HttpService"):JSONDecode(game.ReplicatedStorage.GroupLockAllowed.Value)
for _,group in pairs(allowedGroups)do
if(string.sub(tostring(group.id),1,#v) == tostring(v) or string.sub(string.lower(group.Name),1,#v) == string.lower(v))then
return group
end
end
return nil, "Invalid group"
end,
suggestions = function(text)
local allowedGroups = game:GetService("HttpService"):JSONDecode(game.ReplicatedStorage.GroupLockAllowed.Value)
local suggestions = {}
text = tostring(text)
for _,group in pairs(allowedGroups)do
if(string.sub(tostring(group.id),1,#text) == tostring(text))then
table.insert(suggestions, tostring(group.id))
end
if(string.sub(string.lower(group.Name),1,#text) == string.lower(text))then
table.insert(suggestions, group.Name)
end
end
return suggestions
end,
}

_K.Registry.registerType("groupLockIdType", groupLockGroupIdType)
_K.Registry.registerType("groupId", groupIdType)
_K.Registry.registerCommand(_K, command3)
_K.Registry.registerCommand(_K, command2)
_K.Registry.registerCommand(_K, command)
end