--[[
[Link]
=====================
This script kit gives you an *internal* group/role system that lets players join a
team directly inside your game (no external Roblox group, no Robux).
📂 Files included (all in this single textdoc):
1. **GroupServer** – ServerScriptService script that:
• creates Teams automatically
• loads/saves each player’s chosen group via DataStore
• receives RemoteEvent requests to join a group and applies rules
2. **GroupClient** – LocalScript that lives under *StarterGui > ScreenGui* and
builds a basic button-based UI allowing the player to choose a group.
🔧 Setup steps (quick):
------------------------------------------------------------
1. In **Explorer** make sure you have a ***Teams*** container (Model → Service).
2. Paste the *GroupServer* code into a new **Script** called `GroupServer`
inside **ServerScriptService**.
3. Paste the *GroupClient* code into a **LocalScript** inside a **ScreenGui**
(e.g. name it `ChooseGroupGui`) under **StarterGui**.
4. Publish your place (DataStores only work on published places) and
**Game Settings → Security → Enable Studio Access to API Services** so the
DataStore calls work while testing in Studio.
5. Press Play. A small window appears with buttons like "Join Police".
Click to join. Your team changes and the choice is saved for next time.
Add/Remove groups:
• Edit `AvailableGroups` table in *GroupServer* **and** `groups` array in
*GroupClient* to keep them in sync.
• For a locked/VIP group demo, change the `requestedGroup == "VIP"` section.
Ready-made colour selection uses `[Link]()` – swap for your desired
palette.
-----------------------------------------------------------------]]
-- =============================================================
-- === GroupServer (place this Script in ServerScriptService) ===
-- =============================================================
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GroupStore = DataStoreService:GetDataStore("PlayerGroup")
local AvailableGroups = {
"Police",
"Thieves",
"Builders",
"VIP"
}
-- Utility: ensure Teams exist
local function ensureTeams()
for _, name in ipairs(AvailableGroups) do
if not Teams:FindFirstChild(name) then
local team = [Link]("Team")
[Link] = name
[Link] = [Link]() -- pick fixed colours if you
prefer
[Link] = false
[Link] = Teams
end
end
end
ensureTeams()
-- RemoteEvent for group join requests
local joinGroupEvent = ReplicatedStorage:FindFirstChild("JoinGroupEvent")
if not joinGroupEvent then
joinGroupEvent = [Link]("RemoteEvent")
[Link] = "JoinGroupEvent"
[Link] = ReplicatedStorage
end
-- Load player
[Link]:Connect(function(player)
local success, saved = pcall(function()
return GroupStore:GetAsync([Link])
end)
if success and typeof(saved) == "string" and [Link](AvailableGroups, saved)
then
player:SetAttribute("Group", saved)
local team = Teams:FindFirstChild(saved)
if team then [Link] = team end
else
player:SetAttribute("Group", "None")
end
end)
-- Save on exit
[Link]:Connect(function(player)
local group = player:GetAttribute("Group") or "None"
pcall(function()
GroupStore:SetAsync([Link], group)
end)
end)
game:BindToClose(function()
-- save everyone on server shutdown
for _, player in ipairs(Players:GetPlayers()) do
local group = player:GetAttribute("Group") or "None"
pcall(function()
GroupStore:SetAsync([Link], group)
end)
end
end)
-- Handle join requests from clients
[Link]:Connect(function(player, requestedGroup)
if typeof(requestedGroup) ~= "string" then return end
if not [Link](AvailableGroups, requestedGroup) then return end
-- Example rule: VIP requires a gamepass (replace pass ID!)
local isAllowed = true
if requestedGroup == "VIP" then
local GamePassService = game:GetService("MarketplaceService")
local VIP_PASS_ID = 12345678 -- swap for your pass id
local owns = false
pcall(function()
owns = GamePassService:UserOwnsGamePassAsync([Link],
VIP_PASS_ID)
end)
isAllowed = owns
end
if isAllowed then
player:SetAttribute("Group", requestedGroup)
local team = Teams:FindFirstChild(requestedGroup)
if team then [Link] = team end
pcall(function()
GroupStore:SetAsync([Link], requestedGroup)
end)
joinGroupEvent:FireClient(player, true, requestedGroup)
else
joinGroupEvent:FireClient(player, false, requestedGroup)
end
end)
-- =============================================================
-- === GroupClient (LocalScript under StarterGui > ScreenGui) ===
-- =============================================================
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local player = [Link]
local joinGroupEvent = ReplicatedStorage:WaitForChild("JoinGroupEvent")
local PlayerGui = player:WaitForChild("PlayerGui")
--\n-- Build simple UI programmatically -- no need for manual GUI design in Studio
--//
local screenGui = [Link]("ScreenGui")
[Link] = "ChooseGroupGui"
[Link] = false
[Link] = PlayerGui
local frame = [Link]("Frame")
[Link] = [Link](0, 400, 0, 260)
[Link] = [Link](0.5, -200, 0.5, -130)
[Link] = [Link](0.5, 0.5)
[Link] = 0.2
frame.BackgroundColor3 = [Link](30, 30, 30)
[Link] = 0
[Link] = screenGui
local UIList = [Link]("UIListLayout")
[Link] = [Link]
[Link] = [Link]
[Link] = [Link]
[Link] = [Link](0, 6)
[Link] = frame
local title = [Link]("TextLabel")
[Link] = [Link](1, 0, 0, 30)
[Link] = "Choose a group to join:"
[Link] = true
[Link] = 1
title.TextColor3 = [Link](1,1,1)
[Link] = [Link]
[Link] = frame
local groups = {"Police", "Thieves", "Builders", "VIP"}
local function makeButton(name)
local btn = [Link]("TextButton")
[Link] = [Link](1, -20, 0, 40)
[Link] = "Join " .. name
[Link] = true
btn.BackgroundColor3 = [Link](50, 50, 50)
btn.TextColor3 = [Link](1,1,1)
[Link] = [Link]
[Link] = 0
[Link] = true
[Link] = frame
btn.MouseButton1Click:Connect(function()
joinGroupEvent:FireServer(name)
end)
end
for _, g in ipairs(groups) do
makeButton(g)
end
local info = [Link]("TextLabel")
[Link] = [Link](1, 0, 0, 24)
[Link] = ""
[Link] = 1
info.TextColor3 = [Link](1,1,1)
[Link] = [Link]
[Link] = true
[Link] = frame
[Link]:Connect(function(success, grp)
if success then
[Link] = "You joined " .. grp .. "!"
wait(1.5)
[Link] = false
else
[Link] = "You don't have permission for " .. grp
wait(2)
[Link] = ""
end
end)
-- Hide GUI if player already has a group
if player:GetAttribute("Group") and player:GetAttribute("Group") ~= "None" then
[Link] = false
end
-- Enable GUI later if you want a change-team button, e.g. via hotkey etc.
-- =============================================================
-- === END OF [Link] ===
-- =============================================================