Live Redeemable Codes

Alright so I decided to work out this problem without using an external services

--Disclaimer the dates are in UTC time

local Codes = {
	["Code1"] = {
		["StartingInformation"] = {
			["year"] = 2019; --Year the code will start in
			["month"] = 5; --Month the code will start in
			["yday"] = 124; --Day of the year the code will start on
		};
		["EndingInformation"] = {
			["year"] = 2019; --Year the code will end in
			["month"] = 5; --Month the code will end in
			["yday"] = 125; --Day of the year the code will end on
		};
	};
}

function OnCode(Player, Code) --Pretend this is the function that filters codes from players
	--Check to see if the code is valid
	if Codes[Code] then
		--I will just be coding the time functions
		local Date = os.date("!*t")
		--First we will make sure the year is valid
		if Date["year"] >= Codes["Code1"]["StartingInformation"]["year"] and Date["year"] <= Codes["Code1"]["StartingInformation"]["year"] then
			--The year is valid!
			--Now we will validate the month
			if Date["month"] >= Codes["Code1"]["StartingInformation"]["month"] and Date["month"] <= Codes["Code1"]["StartingInformation"]["month"] then
				--The month is valid!
				--We will now validate the day!
				if Date["yday"] >= Codes["Code1"]["StartingInformation"]["yday"] and Date["yday"] <= Codes["Code1"]["StartingInformation"]["yday"] then
					--The date is also valid!
					--You know know the code is valid!
				end
			end
		end
	end
end

You can add more details time dates if you want, you can find more detailed time variables here

1 Like

You see though, here’s the thing; these aren’t necessarily the kind of live that OP wants to achieve. You will still have to hard code in codes and what kind of reward they should assign. This therefore doesn’t make this any different than updating your game with a code for use in new servers and removing it when the time period is over.

What OP wants to be able to do is register and remove codes for use in-game without updating the actual game and shutting down all servers or wait for old servers to phase out for such changes to take effect.

You don’t need to remove it when it’s over, it auto detects the time and the code won’t work after the time expires.

I don’t think you quite understand what I meant. You still have to manually add and remove codes to the system, which doesn’t make this any better than simply adding a code to your game and shutting down.

The most your code does is reject a code if it’s not entered within a specified time frame via os.date(). It doesn’t achieve the use case OP is looking for, which is to add/remove codes without hard coding them or shutting down the game. This still requires a shut down or server phase out - the Codes table is hard coded into the script.

Please go over my response again.

Server’s more often than not usually do not last more than 2-3 days at the very most, giving you more than enough time to add new codes. All you would have to do is publish the update, you don’t even need to shutdown the server because when a new server starts up it will have the new update with the new codes! I’m not quite sure how you can get more OP than this, a pastebin is nice and all but there are chances of HTTP requests failing, pastebin servers going down, this is a 100% reliable method to a live code system.

Here you can find pastebin’s official API limits
https://pastebin.com/api_scraping_faq

“Your whitelisted IP should not run into any issues as long as you don’t abuse our service. We recommend not making more than 1 request per second, as there really is no need to do so. Going over 1 request per second won’t get you blocked, but if we see excessive unnecessary scraping, we might take action.”

So what are you going to do when you have a ton of servers, with a ton of people all requesting codes at the exact same time.

And if you really want it to be “live” then use a DataStore, it’s literally a live server, no need to go external

You can use a table to store codes with time and date information and then save the table through DataStores, then in-game the new DataStores will be called. The method @Complextic suggested does work as long as its elaborated on more than just a simple time window.

Edit: As for a saving method without hard coding, you can use a command in the command bar to manually save it.

2 Likes

I actually wrote a function which requires a module without caching! Here it is:

local VersionCache = {}

return function(id)
    if type(id) ~= "number" then return end
    local succ, err = pcall(function()
    local LatestVersionOfAsset = game:GetService("InsertService"):GetLatestAssetVersionAsync(id)
    if VersionCache[tostring(id).."|"..tostring(LatestVersionOfAsset)] then
        return require(VersionCache[tostring(id).."|"..tostring(LatestVersionOfAsset)])
    else
        asset = game:GetService("InsertService"):LoadAssetVersion(LatestVersionOfAsset)
        end)
        if not succ then return "error" end
        local module = asset:FindFirstChildOfClass("ModuleScript")
        if not succ or module == nil then return "error" end
        asset:Destroy()
        VersionCache[tostring(id).."|"..tostring(LatestVersionOfAsset)] = module
        return require(module)
    end
end
2 Likes

Inserting an asset is also a great way to get the latest codes. Similar to the DataStore solution, but all you have to do is update the module. Although there is no time window for this one, so I guess you would manually have to change the codes after they expire?

2 Likes

Yes but you still aren’t understanding my point. This doesn’t achieve OP’s end goal. They aren’t looking to wait for servers to phase out, for shutdowns to be made or to update the game. Read the OP.

Shutdowns imply the need to spin up new servers for the changes to take effect. Hard coding it is not what OP wants to achieve.

That being said, Pastebin is an acceptable alternative (I guess?) since it’s an external service - the most you’d need to update is the paste, but set up your ingame code to be flexible to read codes and assign rewards based on the data returned from the raw paste. An external service is a completely acceptable alternative because it achieves what OP is looking for. Hard coding does not.

No? You can store the expiration date in the module script. Like:

return {
    ["TEST"] = {
        Func  = function()
              print("test")
        end;
        ExpirationDate = 1556956000
    }
}

And in a serverscirpt you could check if os.time() > the expiration data before redeeming. You could use an epoch converter to get an accurate date.

2 Likes

The two most viable solutions I am seeing are DataStores and inserting a module via AssetService. Using external services can be faulty. If Pastebin, for example, were to fail, the codes wouldn’t even be able to be used in the first place. DataStores and AssetService will not only do what the OP requested but it also has less flaws than an external service.

1 Like

Thanks, it is probably the simplest one. I actually made a topic about the function I made, but since I do not have Member permissions I DMed a lead top contributor but they declined my request. All you have to do is update a module with the new codes and that is all. Made sure there was no memory leak in the function.

1 Like

External services are as prone to faults as DataStores or AssetService (or InsertService), since those items are as well a web call. The difference is that Roblox’s uptime for its web services is more reliable than a third party which is an unknown variable you have to account for. Any web call, internal or not, has the grounds to fail. In Roblox’s case, it would be the endpoints responsible behind these services.

That being said, I do agree that keeping things in house would be more appropriate and desirable as much as possible, wherever possible. Roblox services are less likely to be something that you need to cover for over an external service you can’t look into.

Typically, if ROBLOX’s web services aren’t working then chances are you won’t even be able to connect to the game, so I would say ROBLOX services are probably much more reliable.

1 Like

That depends on what kind of services you’re referring to. Games are still able to run while various endpoints encounter issues - for example, the GamePersistence endpoint. DataStores may encounter issues but that doesn’t affect the overall connectivity to games.

DataStores don’t usually encounter live issues where the DataStoreService just stops working. It’s almost always a quick loss of data, but after the data loss, the service works like normal again.

1 Like

Not in all cases. The endpoints are still capable of receiving an outage more than just a “quick loss of data” and there are enough instances of that happening around.

But that doesn’t happen as often as it may with an external service.

Nevertheless, we’re getting slightly off-topic and I think the OP already has his 3 best options for a live redeemable code system: DataStores, AssetService, or an external service called using HttpService.

You could even store your codes in data store. You can chat something (similar to HD admin modules) and update a table held in DataStore service… The values in DSS can have their own prizes or whatever they’re for.

I’m confused why this is becoming so complicated;

Why can’t you just save codes in a datastore and have each server check for new codes every ~15 minutes?

This way you can add a code into the datastore in studio (if you have datastores enabled in Studio), and after 15 minutes you know that every server will have that code available, thus you can announce the code and not have to worry about shutting down anything.

I know it doesn’t seem super technical, but it used to work fine for me when I offered Twitter codes.

A better option would be to use MessagingService when it is released as you could easily update codes on every server with a <1s delay. (This feature is not enabled in-game yet, sadly)

5 Likes