Currency system without leaderstats

I’m trying to make a currency system inside my game but I can’t seem to find out how to make one without leaderstats. How can I make it so that the currency ui changes every time the person kills without making it show on the leaderboard?

2 Likes

just make another folder with other name than leaderstats and add your values in it then everytime when someone kills add that kills to that value

3 Likes

I got the first part done but how do I connect it with the killer? I’ve tried to just copy the creator script from the classic roblox sword but it didn’t work.

how does it work doesnt with work with player.leaderstats.kills.value += 1 just do player.(yourfoldername).kills.value += 1

I don’t have a kills leaderboard though. I just want to connect the tool to the currency system

show me the code so i can see whats going on

This is my current code

game.Players.PlayerAdded:Connect(function(plr)
	local currency_holder = Instance.new("Folder")
	currency_holder.Name = "currency"
	currency_holder.Parent = plr
	
	local cash = Instance.new("IntValue")
	cash.Name = "currency_value"
	cash.Value = 0
	cash.Parent = currency_holder
	

	plr.CharacterAdded:Connect(function(char)
		local humanoid = char:FindFirstChild("Humanoid")

		humanoid.Died:Connect(function(killed)
			local tag = humanoid:FindFirstChild("creator")
			local killer = tag.Value
			if tag and killer then
				killer.currency_holder:FindFirstChild("currency_value").Value = killer.currency_holder:FindFirstChild("currency_value").Value + 5
			end
		end)
	end)
	
end)

and this is what was inside the tool

function tagHumanoid(humanoid, player)
	local creator_tag = Instance.new("ObjectValue")
	creator_tag.Value = player
	creator_tag.Name = "creator"
	creator_tag.Parent = humanoid
end

function untagHumanoid(humanoid)
	if humanoid ~= nil then
		local tag = humanoid:findFirstChild("creator")
		if tag ~= nil then
			tag.Parent = nil
		end
	end
end

Try this

game.Players.PlayerAdded:Connect(function(plr)
	local currency_holder = Instance.new("Folder")
	currency_holder.Name = "currency"
	currency_holder.Parent = plr
	
	local cash = Instance.new("IntValue")
	cash.Name = "currency_value"
	cash.Value = 0
	cash.Parent = currency_holder
	

	plr.CharacterAdded:Connect(function(char)
		local humanoid = char:FindFirstChild("Humanoid")

		humanoid.Died:Connect(function(killed)
			local tag = humanoid:FindFirstChild("creator")
			local killer = tag.Value
			if tag and killer then
				game.Players:FindFirstChild(killer).currency:FindFirstChild("currency_value").Value +=  5
			end
		end)
	end)
	
end)

Well, this is how I store my playerData:
image
The PlayerData folder is a child of ReplicatedStorage.
When a player joins, a folder with their ID is created.
The script goes through the table stored in the Player’s Datastore and stores them as IntValue objects.
My DataStoreTable looks something like this: {Currency={},Inventory={}}.
When the player leaves, the script runs through the data in the Player’s DataFolder.
Once the data is saved, the Player’s DataFolder is deleted.

(As the Data is read by a server-script, it is naturally exploit-proof)

There is a problem with my script, where Inventory is made an object in Currency, which I am working on resolving. But if you are storing only Currency for example, it should work fine.

The script if you need a point of referance.
local RepStore = game:GetService("ReplicatedStorage")
local SvrStore = game:GetService("ServerStorage")
local DatStore = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PlayerDataFolder = RepStore.PlayerData

local InfoStore = DatStore:GetDataStore("PlayerData")
local ToCall = game.ServerStorage.Events.DataCall

local ServerStore = DatStore:GetDataStore("ServerStore")

local CurFormat = {"Level","Token","Xp","Coin","Playtime","Streak"}
local Conversions = {Score="Xp"}

function UnloadPlayerData(Player)
	
	local IDList = ServerStore:GetAsync("IDlist")
	if not IDList then IDList = {} end
	if not table.find(IDList,Player.UserId) then
		table.insert(IDList,Player.UserId)
		ServerStore:SetAsync("IDlist",IDList)
	end
	local PlayerID = Player.UserId
	local suc, err = pcall(function()
		local PlayerData = InfoStore:GetAsync(PlayerID)
		if not PlayerData then
			warn("data empty")	
			PlayerData = {}
			PlayerData.Inventory = {}
			PlayerData.Currency = {}
			local Currency = PlayerData.Currency
			local Inventory = PlayerData.Inventory
			for i, v in pairs(CurFormat) do
				Currency[v] = 0
			end
		end
		local PlayerFolder = Instance.new("Folder")
		local CurrencyFolder = Instance.new("Folder")
		local InventoryFolder = Instance.new("Folder")
		PlayerFolder.Name = PlayerID
		PlayerFolder.Parent = PlayerDataFolder
		CurrencyFolder.Name = "Currency"
		CurrencyFolder.Parent = PlayerFolder
		InventoryFolder.Name = "Inventory"
		InventoryFolder.Parent = PlayerFolder
		
		if not PlayerData.Currency and PlayerData.Inventory then
			PlayerData.Currency = {}
			PlayerData.Inventory = {}
		end
		local Currency = PlayerData.Currency
		local Inventory = PlayerData.Inventory
		
		
		for i, v in pairs(PlayerData) do
			if table.find(CurFormat,i) then
				local suc, err = pcall(function()
					Currency[i] = v
					PlayerData[i] = nil
				end)
			end
		end
		
		for i, v in pairs(CurFormat) do
			if not Currency[v] then
				Currency[v] = 0
			end
		end
		
		
		
		for i, v in pairs(Currency) do
			if Conversions[i] then
				local Conv = Conversions[i]
				Currency[Conv] = v
				Currency[i] = nil
			end
			if not table.find(CurFormat,i) then
				PlayerData[i] = nil
			end
		end
		
		for store, data in pairs(Currency) do
			local IntHolder = Instance.new("IntValue")
			IntHolder.Name = store
			IntHolder.Value = data
			IntHolder.Parent = CurrencyFolder
		end
		for object, amount in pairs(Inventory) do
			local IntHolder = Instance.new("IntValue")
			IntHolder.Name = object
			IntHolder.Value = amount
			IntHolder.Parent = InventoryFolder
		end

	end) if not suc then warn(err) end
end

function PackPlayerData(Player)
	local PlayerID = Player.UserId
	if PlayerID then
		local PlayerFolder = PlayerDataFolder:FindFirstChild(PlayerID)
		local success, err = pcall(function()
			if PlayerFolder then
				local PlayerData = {}
				
				local CurrencyFol = PlayerFolder:FindFirstChild("Currency")
				local InventoryFol = PlayerFolder:FindFirstChild("Inventory")
				
				PlayerData.Currency = {}
				PlayerData.Inventory = {}
				
				local CurrencyV = PlayerData.Currency
				local InventoryV = PlayerData.Inventory

				for i, v in pairs(CurrencyFol:GetChildren()) do
					CurrencyV[v.Name] = v.Value
				end
				for i, v in pairs(InventoryFol:GetChildren()) do
					InventoryV[v.Name] = v.Value
				end

				InfoStore:SetAsync(PlayerID,PlayerData)
			end
		end)
		if success then
			PlayerFolder:Destroy()
		else
			warn(err)
		end
	end
end

function TranslateCall(callData)
	local suc, err = pcall(function()
		for i, v in pairs(callData) do
			local PlrId = v.PlrId
			local Ttype = v.Type
			local value = v.Value
			local LPlrFol = PlayerDataFolder[PlrId]
			local SVal = LPlrFol.Currency[Ttype]
			SVal.Value += value
		end
	end) if not suc then warn(err) end
end

Players.PlayerAdded:Connect(UnloadPlayerData)
Players.PlayerRemoving:Connect(PackPlayerData)
ToCall.Event:Connect(TranslateCall)
3 Likes

An alternative would be just to have a folder under the Player object in Players, but that can make it a bit harder to go through Data, as it is not in an collective space.

  • Use local functions in your script.
  • If convenient, use attributes in place of ValueBase objects for holding the currency data.

I have solved the currency part but how do I make it so the game finds who killed someone and give them money?

If your weapon hits someone, who dies right after, you can send to the Server via RemoteEvent, but that can be vanruable.

When a player hits something related to a humanoid, you change a string value in the hitter with the value of the person who got hit