#How to best synchronize server and client?

1 messages · Page 1 of 1 (latest)

safe star
#

Imagine a crate spin -
a normal crate spin is predetermined on the server using RNG and will show an animation on the client rolling through a bunch of items ranging from common to legendary and if you're lucky you will get something good.

Now imagine a crate game -
this crate spin will allow you to press 'STOP' when you see an item you like (if you're fast enough)

the problem with the crate game (or any GUI games) is securing it from exploits. As i still have to run the tweens on the client i also have to send the information back to the server the exact position i pressed 'stop' without just firing the winning item via an unsecured remote

so far i have this
--player buys crate
the server randomly selects 50 items to put into a roll frame

--player clicks start
i run the tween on the client
at the exact same time the server runs a counter for every item that passes

--player clicks stop
the client tween pauses
the server counter stops

--the server rewards player with the item the tween is paused on
the server does this by getchildren() of all items in roll frame
and selects the item using the index set to the counter (+1 or 2 due to UiListLayout etc)

how do i ensure that the counter is always align with the tween on the client due to lag or slight positioning issues such as the rollframe cursor stopping in the middle between 2 different items? OR another way to do this altogether?

#

i will show code when its required

#

btw theres also a 5 second counter so it will never go past the 50 items that it selects for the roll frame

obtuse dagger
#

ig you can use remote events

safe star
#

i did but when there was multiple people trying to use the crate (i tested in team test) it would start lagging extra hard due to multiple fire server remotes from multiple players sending started breaking the game for some reason - btw i have only been scripting for like 6 months so that could be my fault

#

i did it by literally setting the position of the roll frame (instead of tween) and when it gets to specific position it would fireserver the counter that 1 frame had passed - since its going really fast its like 10 fireservers a second

#

not that fast but you get what i mean

obtuse dagger
safe star
#
    while isRolling.Value == true do
        for i = 1, 5 do
            if isRolling.Value == true then
                rollFrame.Position -= UDim2.new(0.05, 0, 0, 0)
                --print(rollFrame.Position)
                print(i)
                task.wait(0.02)
            else 
                return
            end
            
        end
        crateEvent:FireServer("updateframe")
    end
#

here i have this commented out since it failed so bad lol

obtuse dagger
#

crateEvent:FireServer("updateframe") youre firing this 10 times per second per player it causes alot of lag

safe star
#

i know

#

instead currently the server is just counting (without remotes) and hoping its aligning

#

sometimes it will work but as it goes along it starts getting innacurate

#

like if it was in the middle between 2 frames but slightly on the left it would give me the one next to it

obtuse dagger
#

yeah server isnt trying to guess it decides. I recommend you to make the client run the animation and the server picks the winning item or whatever youre rolling

safe star
#

how do i communicate to the server that the player pressed stop and what item it stopped on?

obtuse dagger
#

this what youre doing is very unreliable and causes alot of lag

safe star
#

i can easily do it completely client sided

#

but that would be very unsecure

#

insecure*

obtuse dagger
#

you dont need to send the item or the position at all to the server. You basically just tell the server that the player clicked stop and the server tells which item they got

safe star
#

yes - correct - how does the server know which item? because it can never know exactly what item the tween stopped on

#

i am currently just doing this

#

hold onm

obtuse dagger
#

the server doesnt need to know what tween it stopped on it already decides the winning item before the player presses stop

safe star
#

oh

#

damn thats sneaky

obtuse dagger
safe star
#

the partial reason for this is cus in australia (where im from) the crate spins arent allowed. so it has to be a 'skill' based game

#

client

local tween1 = TweenService:Create(rollFrame, TweenInfo.new(16, Enum.EasingStyle.Linear), {Position = UDim2.new(-8, 0, 0.5, 0)})

local function clientRollfunction()
  rollFrame.Position = UDim2.new(8, 0, 0.5, 0)
  tween1:Play()
end

server

local function serverRollfunction()
  timeFrame.Value = 3 -- index 1 is UiListLayout, and index 2 and 3 are not counted

  while isRolling.Value == true do
    timeFrame.Value += 1
    print(timeFrame.Value)
    task.wait(0.25)
  end
end
obtuse dagger
#

oh

obtuse dagger
safe star
#

i mean i can make money off crate spins easily but i cant view them on my own game XD

safe star
obtuse dagger
#

just make a shared timing system that maps time

#

and item index

#

this is the onkly solution i can think of

safe star
#

can the server read positions of client sided tweens?

obtuse dagger
#

no

safe star
obtuse dagger
#

best explanation i can give

cosmic crater
#

I don't think that'll fix your security issues though

cosmic crater
obtuse dagger
safe star
#

i have thought about getservertimenow() but i never understood how it works

cosmic crater
#

It gives you the time since the server started

safe star
#

it uses linux time or something

#

ohh

cosmic crater
#

Wait now I'm not sure

#

well it doesnt matter what time it gives you

#

the main point is that it's synced between client and server

safe star
#

yes^

cosmic crater
#

if the client stops receiving updates it will adjust the timer itself using its own clock

safe star
#

i still not too sure how to use it - the only time i saw it used was to make a sun/moon cycl;e

cosmic crater
#

local itemNumber = math.floor(workspace:GetServerTimeNow() % itemCount)

safe star
#

cuz it would for some reason sync both client and server

safe star
plush jewelBOT
#

studio** You are now Level 10! **studio

cosmic crater
#

Since it always relies on the client receiving and reacting

safe star
#

ohh okay cuz i have script from someone who tried to help me earlier but i barely understand it cuz im pretty dumb

#

here if you can understand what he was trying to do?

#
--client
.MouseButton1Click:Connect(function()
Local SelectedCase = ui:GetAttribute("SelectedCase")
local ItemWon = RF:InvokeServer("OpenCase", SelectedCase)
print("Won item; " .. ItemWon
end)


--server
local CaseData = {"Item 1", "Item 2", "Item 3"} -- Casedata should be a module script. If you want to randomize order every time you need to make a server side function to do so

local IsSpinning = {} -- UserID: SpinTick
local TimePerItem = 0.5

local function SpinCase(Player:Player, CaseData)
      local TotalItems = #CaseData
       
      if not IsSpinning[Player.UserId] then
        print("IsSpinning")
        IsSpinning[Player.UserId] = tick()
      else
        local SpinTime = IsSpinning[Player.UserId]
         local SpinDuration = tick() - SpinTime

          local CycleTime = TotalItems * TimePerItem
          local TotalTime = SpinDuration % CycleTime
          local IndexItem = math.round(TotalTime / TimePerItem) % TotalItems + 1
           print("StoppedSpinning. Indexed Time; " .. TotalTime .. " Won Item; " .. CaseData[IndexItem] )
          IsSpinning[Player.UserId] = nil
end)

RF.OnServerInvoke = function(Player, Event, Data) -- Data should be string for this event
  if Event == "OpenCase" and Data then
    -- Check if enough coins or whatever
    SpinCase(Player, Data)
  end
end
#

the stupid ```lua ``` thing is broken