Here’s the trick
Step #1: You’ll want to save a value for each player, this value will be the iteration of their randomized stat. This will make sense later, but for now just assign the value to 0. This will be used instead of saving the actual “rolled modifier”
Additionally, if you’re implementing multiple weapons into your game and want them to always be random you can implement certain randomization to each one. This will make more sense later.
Tool.ModifierRandomization = math.random(1, os.time())
Tool.ModifierIteration = 0
Step #2: Within your reroll code on the client, you’ll essentially want to predict and randomize the enchant ENTIRELY on the client & server simultaneously! We’ll be able to do this with Random.new()
On the client, you’ll iterate up this ModifierIteration
for every reroll that you do.
Once you do that, a function can be ran which iterates +1 on your random.
local RNG = Random.new(ModifierRandomization)
local Iteration = 0
local function Reroll()
local Result = RNG:NextInteger(1, 1000)
Iteration += 1
if (Result < 750) then
return "Basic"
else
return "Uncommon"
end
-- Logic can be implemented here to give rewards based off certain numbers or ranges being hit with the Result
end
Reroll()
Now with the way that Random works, it’s IDENTICAL to the way Minecraft seeds or anything similar to that works. That means if you were to use Random 10 times in a row, you will ALWAYS receive the same results in a row. But this can be randomized by using different seeds within the Random parameters.
So the idea is to save how many times into that Random we go, so that when we’re happy with our result the server can do it all as one transaction.
So when the player rolls whatever they’d like we’d fire that iterated number to the server, and it’d complete a full transaction:
local function CompleteTransaction(Player, IteratedInto)
-- Obtain the data somehow... In this example we'll just have it
local RNG = Random.new(ModifierRandomization)
local RolledItem = nil
for Index = 1, IteratedInto do
local Result = RNG:NextInteger(1, 1000)
if (Result and Index == IteratedInto) then
-- Logic can be implemented here to give rewards based off certain numbers or ranges being hit with the Result
-- MAKE SURE THAT IT'S IDENTICAL TO THE CLIENT RNG LOGIC
if (Result < 750) then
RolledItem = "Basic"
else
RolledItem = "Uncommon"
end
end
end
print(Player, "rolled ".. (RolledItem or "nothing...?")
-- Remove coins based off of IteratedInto, or any other sort of logic you'd like! :D
end