Char/Character Command by @LoveliestJacob
Click here to view the old post. (Version v1.2)
Hello, I made a command commonly known as “char” for fun.
The model includes the ability to hide usage of the command, match/keep player size, whitelist users, & a gamepass requirement option.
I would like to mention that the code could likely be changed to be more efficient. So if you have any suggestion/changes please tell me.
Model: https://www.roblox.com/library/7084191278/CharCommand-v1-2
Modal (creator marketplace): CharCommand v1.2 - Creator Marketplace (roblox.com)
Place: Open Source Projects - Roblox
Contents:
CharCommand
-- SETTINGS --
local prefix = "/"
local matchsize = false
local hidemessage = true
local gamepassid = nil -- leave nil if you dont want the command to require a gamepass
local needswhitelist = false -- set to true if you want only players in whitelist to use the command
local whitelist = {}
-- list of user ids of who you would like to use this command, requires needswhitelist to be true
-- owner of the game/group is added by default, so you dont need to add them yourself
-- Examples: local whitelist = {1,2,3}
-- END OF SETTINGS --
local gamepassusers = {}
local chatservice = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner"):WaitForChild("ChatService"))
game:GetService("Chat"):RegisterChatCallback(Enum.ChatCallbackType.OnServerReceivingMessage, function(message)
local chatspeaker = chatservice:GetSpeaker(message.FromSpeaker)
local arguments = message.Message:lower():split(" ")
local player = chatspeaker:GetPlayer()
local normalarguments = message.Message:split(" ")
if player == nil then
return message
end
if arguments[1] == prefix.."char" then
if hidemessage == true then
message.ShouldDeliver = false
end
if gamepassid ~= nil then
if table.find(gamepassusers, player.UserId) == nil then
chatspeaker:SendSystemMessage("You need to own the gamepass to use this command.", message.OriginalChannel)
return message
end
end
if needswhitelist == true then
if table.find(whitelist, player.UserId) == nil then
chatspeaker:SendSystemMessage("You are not whitelisted to use this command.", message.OriginalChannel)
return message
end
end
if arguments[2] == nil then
chatspeaker:SendSystemMessage("Please provide a username.", message.OriginalChannel)
elseif player.Character == nil then
chatspeaker:SendSystemMessage("Character has not loaded.", message.OriginalChannel)
else
script.CharFunction.Fire:Fire(player, chatspeaker.Name, message.OriginalChannel, arguments, normalarguments, matchsize)
end
end
return message
end)
if game.CreatorType == Enum.CreatorType.User then
table.insert(whitelist, game.CreatorId)
end
game:GetService("Players").PlayerAdded:Connect(function(player)
if game.CreatorType == Enum.CreatorType.Group then
if player:GetRankInGroup(game.CreatorId) == 255 then
table.insert(whitelist, player.UserId)
end
end
if gamepassid ~= nil then
local success, err = pcall(function()
if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, gamepassid) then
table.insert(gamepassusers, player.UserId)
end
end)
end
end)
CharFunction
local chatservice = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner"):WaitForChild("ChatService"))
script.Fire.Event:Connect(function(player, name, channel, arguments, normalarguments, matchsize)
local chatspeaker = chatservice:GetSpeaker(name)
local humanoiddescription = nil
local success, err = pcall(function()
humanoiddescription = game:GetService("Players"):GetHumanoidDescriptionFromUserId(game:GetService("Players"):GetUserIdFromNameAsync(arguments[2]))
end)
if humanoiddescription ~= nil then
if player.Character.Humanoid:FindFirstChild("HumanoidDescription") then
if matchsize == true then
local pasthumanoiddescription = player.Character.Humanoid.HumanoidDescription
humanoiddescription.BodyTypeScale = pasthumanoiddescription.BodyTypeScale
humanoiddescription.DepthScale = pasthumanoiddescription.DepthScale
humanoiddescription.HeadScale = pasthumanoiddescription.HeadScale
humanoiddescription.HeightScale = pasthumanoiddescription.HeightScale
humanoiddescription.ProportionScale = pasthumanoiddescription.ProportionScale
humanoiddescription.WidthScale = pasthumanoiddescription.WidthScale
end
end
end
if success then
player.Character.Humanoid:ApplyDescription(humanoiddescription)
chatspeaker:SendSystemMessage("Successfully made your character look like "..normalarguments[2].."!", channel)
else
chatspeaker:SendSystemMessage("An error occurred, did you provide the correct username? If so, that user might be terminated.", channel)
end
end)
(Better) Setting Explanations
Name | Default Value | Explanation |
---|---|---|
prefix | "/" |
Chat command prefix. For example, if the prefix is “;” the command would then be “;char”. |
matchsize | false |
If false, your character will change to the size of the person you are changing to. (R15 Characters Only) |
hidemessage | true |
If true, the command will not show in chat when used. Please note that this does not hide the command response, which is only shown to the player who used the command anyways. |
gamepassid | nil |
This setting allows you to provide a gamepass requirement. If someone doesn’t own the gamepass, they will not have permission to use the command. Important: If needswhitelist is true then the player will still need to be in the whiteliest even if they own the gamepass. |
needswhitelist | false |
If true, players will need to be in the whiteliest in order to be able to use the command. Owner of the group/game is added by default. Important: If gamepassid is not nil then the player will be required to own the gamepass, even if they are in the whiteliest. |
whitelist | {} |
Table of userids of who should be in the whitelist. If you wanted Roblox, Builderman, and Stickmasterluke to be in your whitelist for example: {1, 156, 80254}
|
Edit (5/6/2022): If you’re looking for a video guide, check this video out!
https://youtu.be/H3cEVOXA7b8
Recently updated: I’ve recently updated the module to support TextChatService. (Legacy chat is still supported.) I’ve also added a bit more customization, while keeping the purpose of the module the same. Command permissions was heavily changed, now going by a “if any of these are true, let them in” kind of system.
Char/Character Command enables players in your game to run a command to turn their character into someone else’s. Includes methods to lock the command behind a gamepass or whitelist.
It’s important to note that this does not do anything other than modify the character’s customization. Name display and etc do not get modified. It’s possible for bad actors to trick younger players into thinking they are someone else (usually popular figures). Please use this module with consideration.
Installation
Grab the model/scripts from one of the following locations:
- Creator Store: https://create.roblox.com/store/asset/18357052702/Char-Command
- File: CharModuleLoader.rbxm (7.5 KB)
- Testing Place: new char command testing - Roblox
Click here to view the raw source.
CharModuleLoader (Script)
local CharModule = require(script.CharModule)("char", "/")
CharModule:ToggleKeepSize(false)
-- Examples
-- CharModule:ToggleKeepSize(true)
-- CharModule.Access:AddWhitelist({"Roblox", 1})
-- CharModule.Access:AddGamepass(0)
CharModuleLoader/CharModule (Module Script)
local PlayersService = game:GetService("Players")
local ChatService = game:GetService("Chat")
local TextChatService = game:GetService("TextChatService")
local StarterPlayerService = game:GetService("StarterPlayer")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local MarketPlaceService = game:GetService("MarketplaceService")
local AccessTable = {}
local Settings = {
KeepSize = false,
PromptGamepassPurchase = nil
}
local UsingLegacyChat = false
local NotificationsRemoteEvent: RemoteEvent | nil = nil
if TextChatService.ChatVersion == Enum.ChatVersion.LegacyChatService then UsingLegacyChat = true end
if script:FindFirstChild("CharModuleLocal") and UsingLegacyChat == false then
script.CharModuleLocal.Parent = StarterPlayerService.StarterPlayerScripts
NotificationsRemoteEvent = Instance.new("RemoteEvent")
NotificationsRemoteEvent.Name = "CharModuleNotificationsRemoteEvent"
NotificationsRemoteEvent.Parent = ReplicatedStorage
end
return function(CommandString: string | nil, Prefix: string | nil)
CommandString = (CommandString or "char"):lower()
Prefix = (Prefix or "/"):lower()
local function ChangeCharacter(Player: Player, TargetUsername: string): string
local HasAccess = false
if #AccessTable == 0 then
HasAccess = true
else
for _, AccessFunction in ipairs(AccessTable) do
if AccessFunction(Player) == true then
HasAccess = true
break
end
end
end
if HasAccess == false then
if Settings.PromptGamepassPurchase ~= nil then
MarketPlaceService:PromptGamePassPurchase(Player, Settings.PromptGamepassPurchase)
return "You do not have access to use this command. You have been prompted to purchase the gamepass which gives you access to use the command."
else
return "You do not have access to use this command."
end
end
local Success, ErrorMessageOrUsername = pcall(function()
local Character: Model = Player.Character
local Humanoid: Humanoid = Character.Humanoid
local UserId = PlayersService:GetUserIdFromNameAsync(TargetUsername)
local NewHumanoidDescription = PlayersService:GetHumanoidDescriptionFromUserId(UserId)
if Settings.KeepSize == true then
local CurrentHumanoidDescription: HumanoidDescription | nil = Humanoid:FindFirstChildOfClass("HumanoidDescription")
if CurrentHumanoidDescription ~= nil then
local Properties = {"BodyTypeScale", "DepthScale", "HeadScale", "HeightScale", "ProportionScale", "WidthScale"}
for _, Property in ipairs(Properties) do
NewHumanoidDescription[Property] = CurrentHumanoidDescription[Property]
end
end
end
Humanoid:ApplyDescription(NewHumanoidDescription)
return TargetUsername
end)
if not Success then
return "Something went wrong: "..ErrorMessageOrUsername
else
return "Successfully changed your character to " .. ErrorMessageOrUsername .. "."
end
end
if UsingLegacyChat == true then
local ChatMessagesService = require(ServerScriptService:WaitForChild("ChatServiceRunner"):WaitForChild("ChatService"))
ChatService:RegisterChatCallback(Enum.ChatCallbackType.OnServerReceivingMessage, function(Message)
local Speaker = ChatMessagesService:GetSpeaker(Message.FromSpeaker)
local Player = Speaker:GetPlayer()
if not Player then return Message end
if Message.Message:lower():split(" ")[1] == Prefix .. CommandString then
Message.ShouldDeliver = false
task.spawn(function()
local ResultMessage = ChangeCharacter(Player, Message.Message:lower():split(" ")[2])
Speaker:SendSystemMessage("[System Message]: " .. ResultMessage, Message.OriginalChannel)
end)
end
return Message
end)
else
local TextChatCommands = TextChatService:WaitForChild("TextChatCommands")
local Command = Instance.new("TextChatCommand")
Command.Name = "CharCommand"
Command.PrimaryAlias = Prefix .. CommandString
Command.Triggered:Connect(function(Source, Message)
local Player = PlayersService:GetPlayerByUserId(Source.UserId)
if not Player then return end
local ResultMessage = ChangeCharacter(Player, Message:lower():split(" ")[2])
pcall(function()
return NotificationsRemoteEvent:FireClient(Player, ResultMessage)
end)
end)
Command.Parent = TextChatCommands
end
local Methods = {}
Methods.Access = {}
function Methods:ToggleKeepSize(Value: boolean)
Settings.KeepSize = Value
end
function Methods.Access:AddFunction(AccessFunction: (Player: Player) -> boolean)
table.insert(AccessTable, AccessFunction)
end
function Methods.Access:AddGamepass(GamepassId: number)
Settings.PromptGamepassPurchase = GamepassId
table.insert(AccessTable, function(Player)
local Success, Result = pcall(function()
return MarketPlaceService:UserOwnsGamePassAsync(Player.UserId, GamepassId)
end)
if Success then
return Result
else
return false
end
end)
end
function Methods.Access:AddWhitelist(Players: {number | string})
table.insert(AccessTable, function(Player)
local InWhitelisted = false
for _, UsernameOrId in ipairs(Players) do
if type(UsernameOrId) == "string" then
if Player.Name == UsernameOrId then
InWhitelisted = true
break
end
elseif type(UsernameOrId) == "number" then
if Player.UserId == UsernameOrId then
InWhitelisted = true
break
end
end
end
return InWhitelisted
end)
end
return Methods
end
CharModuleLoader/CharModule/CharModuleLocal (Local Script)
local TextChatService = game:GetService("TextChatService")
local PlayersService = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalPlayer = PlayersService.LocalPlayer
local NotificationsRemote: RemoteEvent = ReplicatedStorage:WaitForChild("CharModuleNotificationsRemoteEvent")
local Channels = TextChatService:WaitForChild("TextChannels")
NotificationsRemote.OnClientEvent:Connect(function(Message: string)
if type(Message) ~= "string" then return end
for _, Channel: TextChannel in ipairs(Channels:GetChildren()) do
if Channel:FindFirstChild(LocalPlayer.Name) then
Channel:DisplaySystemMessage("<b>[System Message]:</b> " .. Message)
break
end
end
end)
Place the script in ServerScriptService
, then you’re all set. (See next section for customization.)
Customization/API
If you don't know how to script, click here for a beginner explanation.
To make changes, open the CharModuleLoader
script that you placed inside ServerScriptService
.
- To edit the prefix and the name of the command. Edit the following line:
local CharModule = require(script.CharModule)("char", "/")
-- Examples:
-- * Replace "char" with "character" to make the command /character.
-- * Replace "/" with "!" to make the command !char.
- If you do not want a player’s character to change sizes when they use the command. Edit the following line:
CharModule:ToggleKeepSize(false)
-- Change the word false to true to apply this change.
- To lock the command behind a whitelist. Add the following to the end of the script:
CharModule.Access:AddWhitelist({"Username", 0})
-- The list supports user ids and username. (User ids are recommended.)
-- For example, if you wanted Roblox to be able to use the command, then you would do:
CharModule.Access:AddWhitelist({1}) -- Or CharModule.Access:AddWhitelist({"Roblox"})
-- Since the `AddWhitelist` takes a table, you can add as many ids or usernames as you wish:
CharModule.Access:AddWhitelist({1, 2, "Example1", 3, "Example2", "Example3"})
- If you would like to lock the command behind a gamepass. Then add the following to the end of the script:
CharModule.Access:AddGamepass(0)
-- Replace 0 with the id of the gamepass.
Scripts
-
CharModuleLoader - An example loader for the module, can be easily replaced with your own.
-
CharModule - The main module with methods for customization.
- CharModuleLocal - A local script which is used to display chat messages. Can be deleted without breaking any core functionality. (Not used at all when legacy chat is enabled.)
-
CharModule - The main module with methods for customization.
API
require(CharModule)(CommandString: string | nil, Prefix: string | nil)
→ Methods{}
-
CommandString
- Optional name of the command. Default is"char"
. -
Prefix
- Optional prefix for the command. Default is"/"
. - Returns a table of methods for further customization.
Methods:ToggleKeepSize(Value: boolean)
→ void
Set the value of KeepSize
. True will prevent the size of a character from changing when the command is used.
-
Value
- The boolean to setKeepSize
to.
Methods.Access → AccessMethods{}
A table of access methods which modify the requirements for using the command.
AccessMethods:AddFunction(AccessFunction: (Player: Player) -> boolean)
→ void
Adds an access function to the table of requirements.
-
AccessFunction
- A function which takes the player as the first argument and returns a boolean indicating whether the player has access or not.
Example:
CharModule.Access:AddFunction(function(Player)
return Player.Name == "Roblox"
end)
AccessMethods:AddGamepass(GamepassId: number)
→ void
Adds an access function which is based on if a player owns the provided gamepass.
-
GamepassId
- The id of the gamepass.
AccessMethods:AddWhitelist(Players: {number | string})
→ void
Adds an access function which checks if the player’s username or id is in a whitelist/table.
-
Players
- A table of usernames and/or ids which should have access.
Usage Showcase
Char/Character Command Showcase (youtube.com)
Questions/Support/Etc
If you need assistance or have any suggestions for the module, please let me know!
Happy coding!