Table of Contents

Custom Currency System

This is about Creating Custom Currency System for Map Developer using Simple Script

Requirements

IMPORTANT! Use Same Name with the Script Variable Use. Which is “CURRENCY_DATA” as private string group Variable

To enable Player Saving Data you can easily turn on Upload Cloud Variable.

Create the Framework

I recommend put this script into UI Script. Since you will use Shop UI, Rewards UI and etc. Which can make the Currency Handling easier using this Framework.

Step 1 : Creating GLOBAL Variable

Global Variable is declared without using prefix “local”. Global Variable can be Called anywhere within same folder. UI Script and Global Script are Different Folder so they does not share GLOBAL VARIABLE script.

Use a name that Easy to remember such as “GLOBAL_CURRENCY”. Now this is your first 2 Lines Code looks like.

GLOBAL_CURRENCY = {} -- Initiate The Currency Global Table to Store Function and Methods..
GLOBAL_CURRENCY.DATA = {} --Table to Store Currency Data.

Step 2: Creating Methods Function

Create a Currency Method

Method to create currency type and store it. Here is the breakdown for each parameter.

function GLOBAL_CURRENCY:CreateCurrency(name, id , description , type)
    -- initiate new Table with exact Name of  Currency and store its id, description and type
    self.DATA[name] = {name=name,id=id,description=description,type=type}
end 

Method to get Player Currency

This Method is to Obtain Player Currency Data by Name

function GLOBAL_CURRENCY:GetCurrency(playerid,name)
    -- String Group 
    local r,datas = Valuegroup:getAllGroupItem(18, "CURRENCY_DATA",playerid)
    if r == 1001 then 
        Player:notifyGameInfo2Self(playerid,"CURRENCY DATA NOT FOUND!")
    end 
    return datas[GLOBAL_CURRENCY.DATA[name].id] or 0;
end 

Method to Display Number Currency Pretty

This convert number to string that can be displayed on UI and looks pretty Short. Such 1000 into “1k”.

function GLOBAL_CURRENCY:PrettyDisplay(amount)
    amount = tonumber(amount)
    local formatted = ""
    if amount >= 1e12 then
        formatted = string.format("%.1fT", amount / 1e12) -- Display in Trillions
    elseif amount >= 1e9 then
        formatted = string.format("%.1fB", amount / 1e9) -- Display in Billions
    elseif amount >= 1e6 then
        formatted = string.format("%.1fM", amount / 1e6) -- Display in Millions
    elseif amount >= 1e3 then
        formatted = string.format("%.1fk", amount / 1e3) -- Display in Thousands
    else
        formatted = tostring(amount) -- If less than 1000, display the full amount
    end
    return formatted
end

Method to Update UI

This method is to handle Currency Update from player when Currency are being used or obtained.

-- Store UI_Data inside GLOBAL_CURRENCY
GLOBAL_CURRENCY.UI_DATA={}
 
-- This is Tell What UI element should be updated when calling UpdateUI for player
function GLOBAL_CURRENCY:AddUI2Update(name,uiid,elementid)
    if GLOBAL_CURRENCY.UI_DATA[name] == nil then 
        -- initiate an Empty table if it is nil
        GLOBAL_CURRENCY.UI_DATA[name] = {}
    end 
    table.insert(GLOBAL_CURRENCY.UI_DATA[name],{uiid=uiid,elementid=elementid});
end
 
-- Can Be Called  from any UI element to update the UI
function GLOBAL_CURRENCY:UpdateUI(playerid,name)
    if GLOBAL_CURRENCY.UI_DATA[name] == nil then 
        print("FAILED TO UPDATE UI : NO ELEMENTID WERE ADDED")
        return false 
    end 
    local ammountPretty = GLOBAL_CURRENCY:PrettyDisplay(GLOBAL_CURRENCY:GetCurrency(playerid,name))
    for i,a in ipairs(GLOBAL_CURRENCY.UI_DATA[name]) do
        Customui:setText(playerid,a.uiid,a.elementid,ammountPretty)
    end 
end

Method to Modify Player Currency

Add Currency for Player. When using this function you may need time validation to avoid exploit or glitch.

function GLOBAL_CURRENCY:AddCurrency(playerid, name, v_ammount)
    -- Get Player Data 
    local ammount = GLOBAL_CURRENCY:GetCurrency(playerid,name)
    -- handle if ammount is empty 
    if ammount == nil then
        -- Player currency is not set Yet !
        ammount = 0 
    end 
    if type(ammount) == "String" then 
        ammount = tonumber(ammount);
    end 
    ammount = ammount + v_ammount;
 
    local id = GLOBAL_CURRENCY.DATA[name].id;
    -- Add Amount to Player Data
    local r = Valuegroup:setValueNoByName(18, "CURRENCY_DATA", id, tostring(ammount), playerid)
    if r == 0 then 
        -- Automatically Update all UI for player 
        GLOBAL_CURRENCY:UpdateUI(playerid,name)
        return  true;
    else 
        print("ERROR WHEN TRYING TO ADD CURRENCY TO PLAYER DATA")
        return false;
    end 
end

Decrease Currency for Player. This method allowing currency of player can goes below zero.

function GLOBAL_CURRENCY:DecreaseCurrency(playerid, name, v_ammount)
    -- Get Player Data 
    local ammount = GLOBAL_CURRENCY:GetCurrency(playerid,name)
    -- handle if ammount is empty 
    if ammount == nil then
        -- Player currency is not set Yet ! 
        ammount = 0 
    end 
    if type(ammount) == "String" then 
        ammount = tonumber(ammount);
    end 
    ammount = ammount - v_ammount;
 
    local id = GLOBAL_CURRENCY.DATA[name].id;
    -- Add Amount to Player Data
    local r = Valuegroup:setValueNoByName(18, "CURRENCY_DATA", id, tostring(ammount), playerid)
    if r == 0 then 
        -- Automatically Update All UI for player
        GLOBAL_CURRENCY:UpdateUI(playerid,name)
        return true 
    else 
        print("ERROR WHEN TRYING TO DECREASE VALUE ON PLAYER SAVE CURRENCY_DATA")
        return false
    end 
end 

Spend Currency for Player. Check is it Capable to Spend Currency return false when not enough Currency to spend Decrease the Currency and return true when enough Currency to spend.

function GLOBAL_CURRENCY:SpendCurrency(playerid, name, v_ammount)
    -- Get Player Data 
    local ammount = GLOBAL_CURRENCY:GetCurrency(playerid,name)
    -- handle if ammount is empty 
    if ammount == nil then
        -- Player currency is not set Yet
        ammount = 0 
    end 
    if type(ammount) == "String" then 
        ammount = tonumber(ammount);
    end 
    ammount = ammount - v_ammount;
    if ammount >= 0 then 
    local id = GLOBAL_CURRENCY.DATA[name].id;
    -- Add Amount to Player Data
    local r = Valuegroup:setValueNoByName(18, "CURRENCY_DATA", id, tostring(ammount), playerid)
        if r == 0 then 
            -- Automatically Update All UI for player
            GLOBAL_CURRENCY:UpdateUI(playerid,name)
            return true 
        else 
            print("ERROR WHEN TRYING TO UPDATE VALUE ON PLAYER SAVE CURRENCY_DATA")
            return false
        end 
    else 
        Player:notifyGameInfo2Self(playerid,"Not Enough "..name.." Need "..ammount.." of "..name);
        return false;
    end 
end

Example of Usage

Creating Currency

Create a 1st Currency which name is “Coin” and the Description is Currency That is Used for Ingame Items and Shop, Can Be Obtained for Free or Via Top Up. Type is C which is custom variable that you can use later.

GLOBAL_CURRENCY:CreateCurrency(
    "Coin",1,
    [[Currency That is Used for Ingame Items and Shop, Can Be Obtained for Free or Via Top Up]],
    "C")

Register an UI Element to Updated when a Currency Changes

Example to add register UI Element to Updated when a Currency Changes. And Update the UI when player entering the game.


Example to use with Shop UI Script

Shop UI itself is Very Long and Complex. but here is the snippet of the Implementation.