Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why does this incomplete Capture Point script lag so much?

Asked by 6 years ago
local redcapturemultiplier = 0
local bluecapturemultiplier = 0

script.Parent.Touched:connect(function(hit)
    local player = game.Players:FindFirstChild(hit.Parent.Name)
    local debounce = false
    if player ~= nil and debounce == false then
        if hit.Name == "Torso" then
            debounce = true
            if hit.Parent:FindFirstChild("capture") == nil and hit.Parent.Humanoid.Health > 0 then
                local CaptureValue = Instance.new("StringValue")
                CaptureValue.Name = "capture"
                CaptureValue.Parent = hit.Parent
                print("made value")
                if tostring(player.TeamColor) == "Bright red" then
                    script.Parent.Parent.RedsOnPoint.Value = script.Parent.Parent.RedsOnPoint.Value + 1
                else
                    script.Parent.Parent.BluesOnPoint.Value = script.Parent.Parent.BluesOnPoint.Value + 1
                end
            end
            debounce = false
        end
    end
end)

script.Parent.TouchEnded:connect(function(hit)
    local player = game.Players:FindFirstChild(hit.Parent.Name)
    local debounce = false
    if player ~= nil and debounce == false then
        if hit.Name == "Torso" then
            debounce = true
            if hit.Parent:FindFirstChild("capture") ~= nil then
                hit.Parent.capture:Destroy()
                if tostring(player.TeamColor) == "Bright red" then
                    script.Parent.Parent.RedsOnPoint.Value = script.Parent.Parent.RedsOnPoint.Value - 1
                else
                    script.Parent.Parent.BluesOnPoint.Value = script.Parent.Parent.BluesOnPoint.Value - 1
                end
                print("destroy value")
            end
        end
    end
end)

script.Parent.Parent.BluesOnPoint.Changed:connect(function(NewValue)
    bluecapturemultiplier = NewValue
end)

script.Parent.Parent.RedsOnPoint.Changed:connect(function(NewValue)
    redcapturemultiplier = NewValue
end)

local stop = false

while wait(0.9) do
    if script.Parent.Parent.BluesOnPoint.Value > 0 and script.Parent.Parent.RedsOnPoint.Value > 0 then
        stop = true
    end
    if stop == false then
        if script.Parent.Parent.BluesOnPoint.Value > 0 then
            if script.Parent.Parent.CaptureProgress.Value ~= -100 then
                wait(0.1)
                script.Parent.Parent.CaptureProgress.Value = script.Parent.Parent.CaptureProgress.Value + (-1 * bluecapturemultiplier)
                if script.Parent.Parent.CaptureProgress.Value == -100 then
                    script.Parent.Parent.Owner.Value = "Blue"
                    script.Parent.BrickColor = BrickColor.new(315)
                    script.Parent.Parent.Union.BrickColor = BrickColor.new(23)
                    script.Parent.Parent.Particles.ParticleEmitter.Color = ColorSequence.new(Color3.fromRGB(0,170,255))
                    print("Blue has captured the point!")
                end
                if script.Parent.Parent.CaptureProgress.Value == 0 then
                    script.Parent.Parent.Owner.Value = "Nobody"
                    script.Parent.BrickColor = BrickColor.new(1001)
                    script.Parent.Parent.Union.BrickColor = BrickColor.new(199)
                    script.Parent.Parent.Particles.ParticleEmitter.Color = ColorSequence.new(Color3.fromRGB(255,255,255))
                    print("Point has been uncaptured!")
                end
            end
        end
        if script.Parent.Parent.RedsOnPoint.Value > 0 then
            if script.Parent.Parent.CaptureProgress.Value ~= 100 then
                wait(0.1)
                script.Parent.Parent.CaptureProgress.Value = script.Parent.Parent.CaptureProgress.Value + (1 * redcapturemultiplier)
                if script.Parent.Parent.CaptureProgress.Value == 100 then
                    script.Parent.Parent.Owner.Value = "Red"
                    script.Parent.BrickColor = BrickColor.new(21)
                    script.Parent.Parent.Union.BrickColor = BrickColor.new(21)
                    script.Parent.Parent.Particles.ParticleEmitter.Color = ColorSequence.new(Color3.fromRGB(255,0,0))
                    print("Red has captured the point!")
                end
                if script.Parent.Parent.CaptureProgress.Value == 0 then
                    script.Parent.Parent.Owner.Value = "Nobody"
                    script.Parent.BrickColor = BrickColor.new(1001)
                    script.Parent.Parent.Union.BrickColor = BrickColor.new(199)
                    script.Parent.Parent.Particles.ParticleEmitter.Color = ColorSequence.new(Color3.fromRGB(255,255,255))
                    print("Point has been uncaptured!")
                end
            end
        end
    end
    stop = false
end

This is a script for an FPS I am working on - basically, its a control point that you can capture. For some reason, this server script lags the whole game whenever someone enters the the point. Is there any reason why? I can see it being linked to the while loop, but I don't know whats wrong with it.

0
Why do you have the denounce reset immediately after touch? If its the touch event that causes the lag, that would be the problem Bellyrium 310 — 6y

2 answers

Log in to vote
1
Answered by 6 years ago

Try setting some variables and functions. These both increase efficiency hugely.

Main tip for functions by the way: a function should only do one thing, and generally be a few lines long. If it needs to do more, then make two functions.

Ad
Log in to vote
1
Answered by 6 years ago

This script doesn't lag on its own (I tested it in a blank place, though I did comment out the ParticleEmitter lines). For lag, you should look at what else might be running - any other scripts that might be listening to the .Touched event of the control point, of the .Changed of any of the IntValues, etc.

On a separate note, I recommend these changes to improve the quality of your script:

  • Instead of having script.Parent and script.Parent.Parent everywhere, save those values to a local variable (like local parent = script.Parent and local data = parent.Parent, for example). It will make your script easier to work with.
  • You have lines like local debounce = false which make no sense. You don't use this variable, nor would you want to. Debounce is meant to prevent a function from running multiple times simultaneously for a length of time - but your function returns immediately (no 'wait') and isn't recursive, so 'debounce' would never come into play. Further, since you declared it 'local', its value isn't saved between function calls, so it becomes literally useless. You do have that "capture" value that you put into character models which acts like a per-player debounce -- that's a good thing; keep it (and remove the 'debounce' variable).
  • Use HumanoidRootPart instead of Torso if you want to support R15 character models (which don't have a Torso).
  • TouchEnded doesn't always fire (I found this during testing). Ideally, in your .Touched event, you should have a loop (only run it if you create that 'capture' object, and only after you've done everything else) that periodically checks to see if the player left the game, is dead, or if their HumanoidRootPart is at least 0.75capturePointSize away from the centre of the capture point (the 0.75 is an approximation of the math; math.sqrt(2)capturePointSize/2 is closer). Do those checks in that order to ensure that the HumanoidRootPart even exists.
  • Use game.Players:PlayerFromCharacter(hit.Parent) instead of local player = game.Players:FindFirstChild(hit.Parent.Name). If you have projectiles in your game, hit.Parent might be nil (which would cause an error), and PlayerFromCharacter is guaranteed to work regardless of what name the character's model is and regardless of what children happen to be in Players (though your line will probably work for your game if you really want it)
  • Consider using constants (ex "local CAPTURE_MAX = 100" near the top of the script - all capitals with underscores in between words is a suggested style for naming constants) so that if you change it later (ex maybe you want players to only have to capture to 20), you need only change it in one place. It also increases readability; compare data.CaptureProgress.Value ~= 100 to data.CaptureProgress.Value ~= CAPTURE_MAX. Specifically, it's easier to understand and verify the logic when using the constant.

Answer this question