Hello folks! So I'm probably 2-3x older than the average developer here (pushing 50) and have zero scripting or programming experience. By even asking this question I’ll expose how much I have to learn:
My game is an obby/puzzle style that times your run to rescue the main character.
I'm currently working through a very odd issue with the timer. If the game is being played solo, it works perfectly: You cross a starting line (touching a brick called "TimerStarter"), and the timer begins counting up 1 second at a time; however, if two people are in the game when a player crosses the start line, the timer starts for that player but increases at 2x the rate it should. If three people are in the game, it increases at 3x the rate. The 2nd or 3rd players are unable to start their timers if this ‘timing multiplier’ has occurred. If the first person leaves, or if only one person is in the game and starts their timer before a 2nd joins, the timer works just fine
The timer functions by referencing a value called “TimerRunning” that is in the player (Set up similar to a leaderstat, but not in the leaderstats folder).
Here is my timer script: (again, please have mercy... )
local Players = game:GetService("Players") local TouchPart = game.Workspace.TimerStarter local TimerEndPart = game.Workspace.TimerEnder local debounce = false TouchPart.Touched:Connect(function(touched) if touched.Name == "UpperTorso" then local Player = Players:GetPlayerFromCharacter(touched.Parent) if Player then Player.leaderstats.Timer.Value = 0 Player.TimerRunning.Value = true if not debounce then debounce = true while Player.TimerRunning.Value == true do wait(1) Player.leaderstats.Timer.Value = Player.leaderstats.Timer.Value +1 end debounce = false end end end end)
And this snippet of my leaderstats and datastore script adds the value "TimerRunning." to the players. (I left out other unrelated
game.Players.PlayerAdded:Connect(function(player) local TimerRunning = Instance.new("BoolValue") TimerRunning.Name = "TimerRunning" TimerRunning.Value = false TimerRunning.Parent = player end)
Sorry for the long first post. I appreciate any guidance.
First, I would like to say welcome! I hope you have fun in our little cozy community of developers.
Second, lets talk a bit about why your script (probably) isn't working. At first, I had a bit of trouble finding out what's wrong with it, but after reading the comments, I came to a conclusion. You most likely have the server script in StarterCharacterScripts. The issue is with this, not with the script. You need to place the script either in ServerScriptService
or as a child of the part. I'll explain why:
StarterCharacterScripts creates a clone of each script inside, and sets it's parent to the character of any players that join. This creates duplicate scripts for each new player (meaning you're handling the .Touched
on every player, even for other players, which gives the multiplication effect). You're basically doing something everytime the part is touched, but you're doing it on a new script everytime someone joins.
With that being said, make sure to make it a ServerScript (and not a LocalScript) when putting it in ServerScriptService or as a child of the part.
You also use debounce
, which is server wide in this case, so I would use a dictionary.
local dict = {};
Then, check if the character is already in the dictionary:
if(dict[h.Parent]) then -- first time they have touched it, start timer here dict[h.Parent] = true; end
Implemented with your script:
local Players = game:GetService("Players") local TouchPart = game.Workspace.TimerStarter local TimerEndPart = game.Workspace.TimerEnder local dict = {}; TouchPart.Touched:Connect(function(touched) if touched.Name == "UpperTorso" then local Player = Players:GetPlayerFromCharacter(touched.Parent) if Player then Player.leaderstats.Timer.Value = 0 Player.TimerRunning.Value = true if not dict[Player] then dict[Player] = true while Player.TimerRunning.Value == true do wait(1) Player.leaderstats.Timer.Value = Player.leaderstats.Timer.Value +1 end dict[Player] = false end end end end)