How to create a chat tag based on if the user has bought a gamepass

Hi there! Today, I’ll show you how to create a custom chat tag such as:

[VIP] Stickmasterluke: Hello!

in studio! This is actually pretty simple, but I’ll gie you a step-by-step guide on how to do it.

Step 1

Create a new Script (not LocalScript) inside of ServerScriptService. You can name it what you’d like, but I have named it TagVIP as you can see.
image

Step 2

You’ll need to supply a variable so we know what the ID of the gamepass you have to buy to get the tag is. In this instance, I’ve named the variable gamepassId.

local gamepassId = 7004828
local service = game:GetService("MarketplaceService")

Step 3

The computer needs to know to run this when a player joins, and it will take the gamepassId variable we made before and see if the player owns a gamepass corresponding to that ID.

game.Players.PlayerAdded:Connect(function(player)
    if (service:UserOwnsGamePassAsync(player.UserId, gamepassId)) then

Step 4

Now is the fun part! We get to create and customise the tags.

        local tags = {
            {
                TagText = "👑VIP",
                TagColor = Color3.fromRGB(0, 255, 255)
            }
        }

Make sure to change the TagText variable to anything you’d like, my recommendation is not making it too big as it could block the chat.

You can also change the TagColor too! change the RGB variable to anything you’d like, such as 214, 213, 150 if you’d like a gold colour!

Step 5

The last part, but the most important. This is the part which actually adds your tag whenever you speak.

        local ChatService = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner").ChatService)
        local speaker = nil
        while speaker == nil do
            speaker = ChatService:GetSpeaker(player.Name)
            if speaker ~= nil then break end
            wait(0.01)
        end
        speaker:SetExtraData("Tags",tags)
        speaker:SetExtraData("ChatColor",Color3.fromRGB(226, 226, 0))
    end
end)

Finished Product

A finished script should look exactly like this:

local gamepassId = 7004828
local service = game:GetService("MarketplaceService")
game.Players.PlayerAdded:Connect(function(player)
    if (service:UserOwnsGamePassAsync(player.UserId, gamepassId)) then
        local tags = {
            {
                TagText = "👑VIP",
                TagColor = Color3.fromRGB(0, 255, 255)
            }
        }
        local ChatService = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner").ChatService)
        local speaker = nil
        while speaker == nil do
            speaker = ChatService:GetSpeaker(player.Name)
            if speaker ~= nil then break end
            wait(0.01)
        end
        speaker:SetExtraData("Tags",tags)
        speaker:SetExtraData("ChatColor",Color3.fromRGB(226, 226, 0))
    end
end)

You can copy and paste this, but I recommend you check out the steps so you know what you are doing and can learn with Lua!

Anyways, I hope this guide can really help you. Have a nice day, and good luck with your game(s)!

45 Likes

Wow this is really helpfully . Now I can make this in my game , thanks! :smiley:

2 Likes

No worries, glad to see that I can help you! Good luck with your game.

1 Like

There is a little typo

Did you mean give you step by step?

Btw this is a really good tutorial.

2 Likes

Thanks for your feedback, much appreciated! I’ll change that now.

3 Likes

how can i change the font of the vip tag?

1 Like

Hello Davixx!

Sadly, you can’t change the font of your text singularly, however if you change the chat font all together the tag will update to that font as well!

3 Likes

Hey there, snazzy tutorial!

Another user posted a tutorial regarding the Lua Chat System earlier which is just how to configure tags in general. Like that post, I have feedback to give so that you can properly use the Lua Chat System’s API to your advantage. I would encourage you to take a look at some of the docs, since they do have some very useful information.


GetService

Please use GetService to remain consistent in how you get services. As some services can be renamed, do not have proper names (e.g. RunService has a space in it) or cannot be accessed through direct indexing, GetService is your friend for remaining consistent in how you fetch services.

Use clear variable names

You want to be clear in what your variables are pointing towards. service should be MarketplaceService or anything to indicate that you are working with the aforementioned service. This will better help your code stay readable and accessible. In addition, if you are working with other services, you want that distinction of what service you are going to be working with as you are writing out code. Clear variable names are the best variable names.

Use variables

I noticed that you require the ChatService in the added function. Avoid this! Make the ChatService an upvalue so that you can avoid calling for the service frequently. You will always have it available after the first require. The same goes with the tags table and creating a new table for every player, though I believe this is a non-problem. This would just make everyone’s tag table point to the same one.

local ServerScriptService = game:GetService("ServerScriptService")
local MarketplaceService = game:GetService("MarketplaceService")

local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)

local GAME_PASS_ID = 123456

local VIP_TAGS = {
    {
        TagText = "👑VIP",
        TagColor = Color3.fromRGB(0, 255, 255)
    }
}

Use the API

The ChatService provides you wonderful APIs that you can use to couple your code with the service rather than with an outside one. Chat tag scripts like this should almost never rely on the Players service. Use SpeakerAdded so you can act based on when the ChatService registers a new player rather than the player connecting to the server. Use ChatSpeaker:GetPlayer() to get the player object, if one is associated. More in the next header.

Don’t use anonymous functions

Avoid direct connections via anonymous functions so you can account for both new and existing players. Store your function in a local variable, connect it then run it in case there are already any existing speakers (this can happen, including for non-player speakers!).

-- speakerAdded fires with the name of the speaker, not players
local function speakerAdded(speakerName)
    doCodeOnSpeaker()
end

ChatService.SpeakerAdded:Connect(speakerAdded)
for _, speaker in ipairs(ChatService:GetSpeakerList()) do
    speakerAdded(speaker)
end

Putting the feedback all together

With this feedback in mind, you can have a renewed code sample that allows you to set chat tags for players without any added bulk and you can also account for overlooked cases, such as the aforementioned non-player speaker case. Putting it all together, you can have a code sample that looks a bit like the following:

local ServerScriptService = game:GetService("ServerScriptService")
local MarketplaceService = game:GetService("MarketplaceService")

local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)

local GAME_PASS_ID = 123456

local VIP_TAGS = {
    {
        TagText = "👑VIP",
        TagColor = Color3.new(0, 1, 1)
    }
}

local function speakerAdded(speakerName)
    local speaker = ChatService:GetSpeaker(speakerName)
    local player = speaker:GetPlayer()

    -- ChatSpeaker belongs to a player entity
    if player then
        if MarketplaceService:UserOwnsGamePassAsync(player.UserId, GAME_PASS_ID) then
            speaker:SetExtraData("Tags", VIP_TAGS)
            speaker:SetExtraData("ChatColor", Color3.fromRGB(0, 226, 226))
        end
    end
end

ChatService.SpeakerAdded:Connect(speakerAdded)
for _, speaker in ipairs(ChatService:GetSpeakerList()) do
    speakerAdded(speaker)
end

I hope this feedback will prove useful towards improving the way you work with the chat system. :slightly_smiling_face:

17 Likes

Thank you! As I am pretty new to scripting, I don’t know everything. Your reply has definitely helped me out and I’m sure this can help me out in the future!

6 Likes