Global Price Changing System

So I’m having an issue developing a system similar to a cryptocurrency.

What needs to happen is that every 30 minutes, the price of the currency randomly changes.

The issue is I don’t know how to make this happen globally, and then if every server shuts down, how to make it save until another starts.

Currently I just have a module of the stats for each currency and a module that just has DataStoreService, MessagingService, and HTTPService imported.

The module contains each currencies name,baseprice, commission (how much is lost upon selling), and the max it can change every 30 minutes

I know it would involve datastore and cross server messaging, I just have never worked with messagingservice.

I have all my code below

MainModule

local DataStoreService = game:GetService("DataStoreService")
local MessagingService = game:GetService("MessagingService")
local HTTPService = game:GetService("HttpService")

local module = {}

return module

KnownCryptos (module)

local cryptos =  {
	{
		["Name"] = "TestingCoin",
		["BasePrice"] = 1200,
		["Commission"] = 10,
		["MaxChange"] = 15,
		["OwnerID"] = 153249041 -- // @yodahe
	}
}

return cryptos
1 Like

You could just make the price a function of time if you just need it to be random / not able to change it manually.

Is there any way I can just have one server change it than synchronize the price to all other servers?
I don’t want people to be able to swap servers and sell for a different price.

Can you just use the real time from the real world?

That would be consistent across all servers in the same time zone:

local function formatTime(use12Hour, t )
	local t = t or tick()

	local hours = math.floor(t / 3600) % 24
	local mins = math.floor(t / 60) % 60
	local secs = t % 60

	local isPm = hours > 12
	local amOrPm = isPm and "pm" or "am"

	--convert to 12 hour time if we want to use 12 hour time instead of 24: 
	if use12Hour then
		hours = isPm and hours - 12 or hours
		return string.format("%d:%02d:%02d"..amOrPm, hours, mins, secs)
	else
		return string.format("%d:%02d:%02d ", hours, mins, secs)
	end
end

print(formatTime(true))

Wouldn’t that make it so there’s a set path and not a random change every 30 minutes?

I meant you can reference the real world time so it is consistent across servers.

At 12:00 change currency
at 12:30 change currency
etc.
etc.

Wouldn’t each server generate a different number than each other since it’s random?

I’m pretty sure I’d have to use something like MessagingService to make sure every server has the same value?

Couldn’t it also be a more apparent issue when the game is going to have like 9 currencies all randomly changing?

EDIT: Forgot to mention, please correct me if I’m wrong, I know that random is never truly random, but I still think that it would be an issue.

I think the script gets the current time and is consistent for all servers located in the same time zone.

When I test it, the time was exact to the second for my time zone.

Well the issue I see is it’s multiplying its value by a random percent, and I can see an issue with every server just adding a different value.

Another thing I thought of is if all servers shut down, wouldn’t it revert to the base value since there’s nothing saving it?

There’s no issue with time, I just need every thirty minutes every single server gets the same exact value.

Hello!

I have found a solution, it can be improved heavily, but it works quite well. If you have any ideas to improve, please post them below. It even syncs across all servers!

Code:

local DataStoreService = game:GetService("DataStoreService")
local HTTPService = game:GetService("HttpService")

local Cryptos = require(script.KnownCryptos)

local DataStore = DataStoreService:GetDataStore("Cryptos")

local module = {}

local lasts = {}

function module.getCryptoTable()
	return lasts
end

function module.init()
	for i, v in Cryptos do
		local last = v.BasePrice
		local data
		local err = pcall(function()
			data = DataStore:GetAsync(v.Name)
		end)
		if data == nil or data == "nil" then
			warn("No data for crypto \""..v.Name.."\", reverting to default value of: "..tostring(v.BasePrice)..".")
		else
			last = data
		end
		lasts[v.Name] = last
		DataStore:SetAsync(v.Name, lasts[v.Name])
	end
	
	while task.wait(1) do
		local t = tick()
		local hours = math.floor(t / 3600) % 24
		local mins = math.floor(t / 60) % 60
		local secs = math.floor(t % 60)
		
		if secs == 0 or secs == 30 then
			for i, v in Cryptos do
				local data
				local err = pcall(function()
					data = DataStore:GetAsync(v.Name)
				end)
				if data == "nil" or data == nil then
					warn("NO DATA")
				elseif data == lasts[v.Name] then
					local randomPercent = math.random(-v.MaxChange, v.MaxChange) / 100
					lasts[v.Name] = math.floor(lasts[v.Name] * (randomPercent+1))
					if lasts[v.Name] < 100 then
						lasts[v.Name] = 100
					end
					
					DataStore:SetAsync(v.Name, lasts[v.Name])
				else
					lasts[v.Name] = data
				end
				print(v.Name..": "..tostring(lasts[v.Name]))
			end
		end
	end
end

return module

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.