Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Why is my remote function not returning properly?

Hello! I am having an error. Every time that I send in the proper code, I always get the "Code Failed" to return. I even copy and paste the code to the same result. I am not sure why it is doing this, and will try using the print function to debug.

Server Script:

local DataStore = game:GetService("DataStoreService"):GetDataStore("PromoCodes")
local BonusFunction = Instance.new("RemoteFunction")
BonusFunction.Name = "BonusFunction"
BonusFunction.Parent = game.ReplicatedStorage

local PlayerData = nil
local PromoCodes = {
	["MLyPtHQvSoPq"] = false,
	["YJW9vey8u6ud"] = false,
	["G9oh5RDjH3TM"] = false	
	}

function BonusFunction.OnServerInvoke(Player, Code)
	if DataStore:GetAsync(Player.userId) ~= nil then
		PlayerData = DataStore:GetAsync(Player.userId)
	else
		DataStore:SetAsync(Player.userId, PromoCodes)
		PlayerData = PromoCodes
	end
	
	for i, v in pairs(PromoCodes) do
		if i == Code then
			for g, c in pairs(PlayerData) do
				if g == Code and c == false then
					return "Code Succussful"
				elseif c == true then
					return "Code Used"
				end
				wait()
			end			
		end
		wait()
	end
	return "Code Failed"
end

Nothing is going wrong with the Local script.

1 comment

0

Although I'm still going over this, one thing you should immediately take note off is the fact that the function returned 'Code Failed' without any error. This means your conditional statements aren't being met in the for loops. It'd be useful to know how exactly you are invoking this function from the LocalScript

1 answer

There are a couple of bugs here.

First, PlayerData = PromoCodes does not copy PromoCodes, it simply sets a reference. You must loop through the PromoCodes Table and recreate it. Additionally, since PlayerData is not local to the function, simultaneous function invokes can cause some errors.

Your for loops are completely unnecessary. You can simply try and access PlayerData[Code] and see if it exists, and if it does what 'state' it is in.

local DataStore = game:GetService("DataStoreService"):GetDataStore("PromoCodes")
local BonusFunction = Instance.new("RemoteFunction")
BonusFunction.Name = "BonusFunction"
BonusFunction.Parent = game.ReplicatedStorage

local PromoCodes = {
    ["MLyPtHQvSoPq"] = false,
    ["YJW9vey8u6ud"] = false,
    ["G9oh5RDjH3TM"] = false    
}

function BonusFunction.OnServerInvoke(Player, Code)
	local PlayerData = DataStore:GetAsync(Player.userId)

    if not PlayerData then
        DataStore:SetAsync(Player.userId, PromoCodes)
        PlayerData = {}
	for code in pairs(PromoCodes) do
		PlayerData[code] = false
	end
    end

	if PlayerData[Code] ~= nil then -- `false` ~= `nil`
		if PlayerData[Code] then
			print("Code Successful")
			PlayerData[Code] = true
			--Do the promo code thing!
			DataStore:SetAsync(Player.userId, PlayerData)
		else
			print("Code Used")
		end
	else 
		return("Code Failed")
	end
end

However, using GetAsync every time this function is invoked is not very efficient and will eat up a lot of your available accesses. So, instead, let's cache them:

local DataStore = game:GetService("DataStoreService"):GetDataStore("PromoCodes")
local BonusFunction = Instance.new("RemoteFunction")
BonusFunction.Name = "BonusFunction"
BonusFunction.Parent = game.ReplicatedStorage

local PromoCodes = {
    ["MLyPtHQvSoPq"] = false,
    ["YJW9vey8u6ud"] = false,
    ["G9oh5RDjH3TM"] = false    
}

local DataStoreCache = {}

function BonusFunction.OnServerInvoke(Player, Code)
	local PlayerData = DataStoreCache[Player.userId]

    if not PlayerData then
	PlayerData = DataStore:GetAsync(Player.userId)

	if not PlayerData then
	        DataStore:SetAsync(Player.userId, PromoCodes)

	        PlayerData = {}
		for code in pairs(PromoCodes) do
			PlayerData[code] = false
		end
		DataStoreCache[Player.userId] = PlayerData
	end
    end

	if PlayerData[Code] ~= nil then -- `false` ~= `nil`
		if PlayerData[Code] then
			print("Code Successful")
			PlayerData[Code] = true
			--Do the promo code thing!
			DataStore:SetAsync(Player.userId, PlayerData)
		else
			print("Code Used")
		end
	else 
		return("Code Failed")
	end
end

This discussion is preserved as it was. New answers, comments, and votes are closed.