Simple Twitter Code System for Beginners


#1

This is a relatively short overview on how to get started implementing a code system into your game. With this system, you can update and add codes in live time (short delay ~30s) so you do not have to shutdown servers!

Step 1: Create an asset
For this simple system, we will need to have an assetId handy. To do this, publish a blank model, decal, audio, or place to Roblox. Anything with an assetId that has a description will work!

Step 2: Adding our codes
To store our codes, we will need to use a method of the HttpService. Lets start to build our system:

game:GetService('HttpService')

Now lets create our table of codes that we want to turn into a JSON encoded string.

local codes = {['GEMS'] = {'Gems', 25}}

‘GEMS’ = The code
‘Gems’ = The stat we want to change
25 = The value we want to change it by

This table set up allows us to store the code we want players to use as well as two important parameters:

  1. The type of reward we want to give the player
  2. The amount of reward we want to give the player

To turn this into a JSON encoded string we can then do the following:

local codes = {['GEMS'] = {'Gems', 25}}
print(game:GetService('HttpService'):JSONEncode(codes))

If we put this into the command line we get this

{"GEMS":["Gems",25]} 

Now, to add more codes, we don’t need to repeat this process. Since it is already set up, we can just add new codes like this:

{"GEMS":["Gems",25],"COINS":["Coins",25]}

Because this is how JSON string are encoded, we can be assured that this will work. We then copy and past this into the assets description!

Step 3: Accessing our codes
We now have our codes stored in an assets description, but how do we fetch them? It is actually fairly simple. Using the MarketplaceService, we can fetch the description using the assetId like so:

local description = game:GetService("MarketplaceService"):GetProductInfo(assetId).Description

To decode the JSON string back into a table we can use:

local description = game:GetService("MarketplaceService"):GetProductInfo(assetId).Description
local codes = game:GetService('HttpService'):JSONDecode(desc)

Because we are using JSONDecode, codes is a table. We can now easily search through the codes to see if the right one was called. Here is the finished product of our code system. Remember to keep this on the server, you wouldn’t want to leak the assetId where you store your codes!

local function codes(player, code)
	local codes = game:GetService('HttpService'):JSONDecode(game:GetService("MarketplaceService"):GetProductInfo(assetId).Description)
	local stats = PLAYERS_STATS
	if(codes[code])then
		stats[codes[code][1]].Value = stats[codes[code][1]].Value + codes[code][2]
		return true
	else
		-- code doesn't exist
		return false
	end
end

Warnings:
The provided code may not fit your data structure. If you need assistance implementing the changing of stats, please feel free to send me a message!

TIPS:
If you do not feel comfortable using an asset to store codes, you can also do something more advanced without changing most of the code! Because we are decoding a JSON string, we can change our MarketplaceService call to a HttpService:GetAsync() request to a web server!

If you think I missed or overlooked anything, please feel free to send me feedback, this is my first time making a tutorial :slight_smile:


Cleaning up my codes system
#2

Very solid system! I currently use a datastore approach, however something like this is much more reliable.


#3

You could also use pastebin.com, then do

local http = game:GetService("HttpService")
local res = http:RequestAsync({ Url = "https://pastebin.com/raw/(Insert_paste_ID)" })
local codes = res.Success and http:JSONDecode(res.Body) or {}

#4

I was legitimately confused about what kind of code system this was.
At first I thought this was some kind of a code editor that does the job for you by placing elements (like Scratch :smile:)

Good tutorial, however, as this is intended for beginner scripters I recommend you to not use shortened names as this could be confusing, and just generally makes your code less readable and “beautiful”. (I know the code you provided was just as an example, but still, new scripters may find it confusing and will keep the bad habit of using shortened names).

You could probably add in the intro of your post what this code system is. I.e “This will be a short overview on how to create dynamical codes, in case you want to reward players for following you on Twitter by handing out codes” - bad example, but shows the point.

All in all, very nice :+1:


#5

Nice!

As another addition, don’t forget to implement error handling. Any external calls from the game itself (e.g. HttpService, DataStoreService, MarketplaceService, etc.) should be wrapped with pcall.


#6

Seems neat, said at the end I would use another service to manage codes as if they looked through your assets and find this table, and you have “tester” codes and if you use this for twitter it kinda defeats the purpose of making the user go to twitter. Instead they are over here looking at an asset.


#7

Here is how I go about it. Hope its well comented.

   -- This is our codes table. it includes a Code as the index and a functioin as a value.
local CodesTable = {
	
	["FREE"] = function(player)
		 --Internal function that changes Money value of player
		PlayerStatManager:ChangeCurrency(player, "Money", 250, false)
	end;
	
	["EARLY"] = function(player) -- Early Access only
		if MarketplaceService:PlayerOwnsAsset(player, 2030764761) then -- Check if player has badge
			PlayerStatManager:ChangeCurrency(player, "Gems", 50, false) -- Change value of GEMS
		else
			return false
		end
	end;
}
-- Note that sessionData[player] is where data of the player is stored. Its all saved through JSONEncode

function PlayerStatManager:RedeemCode(player, Code) -- Function that is fired through a RemoteFunction
	for i, v in pairs(sessionData[player]["UsedCodes"]) do -- Loop through codes player already used
		if v == Code then return false end -- Check if player already redeemed the code he is trying to use
	end
	
	local res = false -- Make a varable that will hold our function from CodesTable
	
	for c, func in pairs(CodesTable) do -- Loop through the table of codes
		if c == Code then res = func break end -- if Code exists assign it to the variable and break out of the loop
	end
	
	
	if res ~= false then -- Check if function was found
		sessionData[player]["UsedCodes"][#sessionData[player]["UsedCodes"] + 1] = Code -- Add the used code to player data
		local success, msg = pcall(res, player) -- Call the function from the table and handle errors
		if not success then
			print("\t Error message:",msg)
			return false -- Return false if we have an error
		else
			return true -- Return true if everything is fine
		end
	end
	
	return false -- Return false if we didn't find a function that matched our code
end

Let me know what you think.


#8

Great tutorial!


#9

I was originally going to use this approach, but I decided not to due to have to wait for new servers in order to redeem new codes. I use a method similar to the one above now. Looks good to me though


#10

I know, that is the only downside. Although you could probably just add conditions to the JSON string and make the server check for all things. Anyways nice tutorial :smiley:


#11

nice tutorial