Skip to content


A UIControl for a button which allows players to purchase perks within a game. Similar to UIButton, but designed to present a consistent purchasing experience for players across all games. Inherits from UIControl.


Property Name Return Type Description Tags
isInteractable boolean Returns whether the button can interact with the cursor (click, hover, etc). Read-Write
isHittable boolean When set to true, this control can receive input from the cursor and blocks input to controls behind it. When set to false, the cursor ignores this control and can interact with controls behind it. Read-Write


Function Name Return Type Description Tags
GetPerkReference() NetReference Returns a reference to the perk for which this button is currently configured. If no perk has been set, returns an unassigned NetReference. (See the .isAssigned property on NetReference.) None
SetPerkReference(NetReference) None Configures this button to use the specified perk. None
GetCurrentTouchIndex() integer Returns the touch index currently interacting with this button. Returns nil if the button is not currently being interacted with. Client-Only


Event Name Return Type Description Tags
clickedEvent Event<UIPerkPurchaseButton> Fired when button is clicked. This triggers on mouse-button up, if both button-down and button-up events happen inside the button hitbox. None
pressedEvent Event<UIPerkPurchaseButton> Fired when button is pressed. (mouse button down) None
releasedEvent Event<UIPerkPurchaseButton> Fired when button is released. (mouse button up) None
hoveredEvent Event<UIPerkPurchaseButton> Fired when button is hovered. None
unhoveredEvent Event<UIPerkPurchaseButton> Fired when button is unhovered. None


Example using:

In this example a player can click on a UI Perk Purchase Button (Client UI with Perk Net Reference), and will be given a certain amount of gems. These gems will be added to the player's resource, and also save in player storage so that the total gems persist between game sessions.

The UI Perk Button doesn't need any client side Lua logic when a player clicks the button because Core handles this for you.

-- Server script. Player storage enabled.
-- The perk reference (repeatable).
local GEMS_PERK = script:GetCustomProperty("Gems")

-- Total gems to give per purchase.
local TOTAL_GEMS = script:GetCustomProperty("TotalGems") or 1

-- Check if a perk is assigned.
if not GEMS_PERK.isAssigned then
    warn("No perk reference assigned")

-- Will be called when a perk is purchased by the player.
local function PerkChanged(player, perk)
    print(string.format("%s purchased %s perk",, perk))

    -- Check that the perk that was purchased matches
    -- the GEMS_PERK reference so you can give gems.
    if perk == GEMS_PERK then
        player:AddResource("Gems", TOTAL_GEMS)

        -- Fetch the players existing data.
        local playerData = Storage.GetPlayerData(player)

        -- Update the gems amount in the player data.
        playerData.gems = player:GetResource("Gems")

        -- Set the players storage data with the updated data.
        Storage.SetPlayerData(player, playerData)

-- For debugging to see if the gems resource updated.
-- This would usually be in a client script that would update
-- the player's UI with their updated Gem amount.
local function PlayerResourceChanged(player, resource, newAmount)
    if resource == "Gems" then
        print(string.format("%s gems: %s",, newAmount))

-- Set the perkChangedEvent for the player when the join
-- the game.
local function OnPlayerJoined(player)

    local playerData = Storage.GetPlayerData(player)

    -- Set the players resource with the gems in storage.
    player:SetResource("Gems", playerData.gems or 0)

    -- This would usually be in a client script to update
    -- the UI for the player to show their resources when
    -- the amount changes.


See also: Player.HasPerk | NetReference.isAssigned | Game.playerJoinedEvent | CoreObject.GetCustomProperty | Storage.SetPlayerData | CoreLua.print

Example using:



Perks are a system to create in-game purchases that allow players to support game creators and enable exclusive content.

Learn more about Perks here.

In the following example, a script is a child of a Perk Purchase Button, of type UIPerkPurchaseButton. The user interface container that has the button is in a client context. The specifics of the Perk come in through the custom property MyPerk, which is then assigned to the button with SetPerkReference(). When the player joins we connect to the perkChangedEvent and print out their existing perks with the LogPerks() function.

-- Perk Net Reference custom parameters
local MY_PERK = script:GetCustomProperty("MyPerk")
local TEST_LIMITED_TIME = script:GetCustomProperty("TestLimitedTime")
local TEST_PERMANENT = script:GetCustomProperty("TestPermanent")
local TEST_REPEATABLE = script:GetCustomProperty("TestRepeatable")

-- Mapping of PerkNetRefs to table of properties, in this case a name
local perkList = {}
perkList[TEST_LIMITED_TIME] = { name = "limited-time" }
perkList[TEST_PERMANENT] = { name = "permanent" }
perkList[TEST_REPEATABLE] = { name = "repeatable" }

-- Set purchase button's Perk to given custom property

function DebugLog(msg)

function OnPerkChanged(player, perkRef)
    DebugLog("on perks changed " ..

    if (perkList[perkRef] ~= nil) then
        DebugLog("perk changed: " .. perkList[perkRef].name)


function LogPerks(player)
    -- Example of HasPerk() and GetPerkCount().
    -- For non-repeatable perks checking GetPerkCount() > 0
    -- is equivalent to HasPerk() == true
    for perkRef, prop in pairs(perkList) do
        DebugLog("-- perk: " ..

        local hasPerkMsg = "    has perk?: " .. tostring(player:HasPerk(perkRef))
        local perkCountMsg = "    count: " .. tostring(player:GetPerkCount(perkRef))


        -- Example of getting Perk reference of parent Perk button
        local parentPerkRef = script.parent:GetPerkReference()
        if (parentPerkRef.isAssigned and perkRef == parentPerkRef) then
            DebugLog("is parent perk ref")

function OnPlayerJoined(player)
    -- Connect perkChangedEvent

    -- Log perks player has initially on join


See also: Player.HasPerk | NetReference.isAssigned | Game.playerJoinedEvent | CoreObject.GetCustomProperty | CoreLua.print | UI.PrintToScreen | Event.Connect


UI in Core | Implementing Perks

Last update: May 3, 2022