local HP = script.Parent.Parent.ScientistHP
local MaxHP = script.Parent.Parent.ScientistMaxHP
local Defense = script.Parent.Parent.ScientistDefenses
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Defense = 666
local Chance = math.random(1,17)
local DefenseProtocol = false
local CheckOne = false
local CheckTwo = false
if Chance == 14 then
Defense = 0.25
else
Defense = 2
end
print(Defense)
print(Chance)
local function Tween()
HealthFrame:TweenSize(UDim2.new(HP.Value / MaxHP.Value, 0,1,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 2.5, false)
end
local function Shake()
script.Parent.Parent.scientistFrame.Position = UDim2.new(script.Parent.Parent.scientistFrame.Position.X.Scale + 0.4, script.Parent.Parent.scientistFrame.Position.Y.Scale, 0)
task.wait(0.25)
script.Parent.Parent.scientistFrame.Position = UDim2.new(script.Parent.Parent.scientistFrame.Position.X.Scale - 0.4, script.Parent.Parent.scientistFrame.Position.Y.Scale, 0)
task.wait(0.25)
script.Parent.Parent.scientistFrame.Position = UDim2.new(script.Parent.Parent.scientistFrame.Position.X.Scale, 0, script.Parent.Parent.scientistFrame.Position.Y.Scale + 0.27, 0)
end
script.Parent.MouseButton1Click:Connect(function()
script.Parent.Visible = false
script.Parent.Parent.attackedLabel.Text = "You attacked!"
script.Parent.Parent.attackedLabel.Visible = true
task.wait(1.5)
if Humanoid then
HealthFrame.Parent.Visible = true
local DmgValue = math.random(45,65)
if HP.Value < MaxHP.Value / 2 and DefenseProtocol == false then
DmgValue /= 2
elseif HP.Value < MaxHP.Value / 2 and DefenseProtocol == true then
DmgValue = math.random(65,85)
end
local Damage = DmgValue / Defense
print(Damage)
HP.Value -= Damage
script.slash:Play()
script.Parent.Parent.scientistFrame.ImageColor3 = Color3.new(1,0,0)
Tween()
Shake()
task.wait(3)
script.Parent.Parent.scientistFrame.ImageColor3 = Color3.new(1, 1, 1)
task.wait(0.4)
if HP.Value <= 190 and HP.Value > 120 and CheckOne == false then
CheckOne = true
script.Parent.Parent.attackedLabel.Text = "We still have long ways to go..."
task.wait(4)
HealthFrame.Parent.Visible = false
script.Parent.Parent.attackedLabel.Text = "You were attacked!"
task.wait(2)
Humanoid.Health -= math.random(5,15)
task.wait(3)
script.Parent.Visible = true
script.Parent.Parent.attackedLabel.Visible = false
elseif HP.Value <= 120 and HP.Value > 50 and CheckTwo == false then
CheckTwo = true
script.Parent.Parent.attackedLabel.Text = "We're close to beating her! keep going!"
task.wait(6)
HealthFrame.Parent.Visible = false
script.Parent.Parent.attackedLabel.Text = "You were attacked!"
task.wait(2)
Humanoid.Health -= math.random(5,15)
task.wait(3)
script.Parent.Visible = true
script.Parent.Parent.attackedLabel.Visible = false
elseif HP.Value < 50 and DefenseProtocol == false and HP.Value > 0 then
DefenseProtocol = true
script.Parent.Parent.attackedLabel.Text = "Uh oh! her defenses were raised"
script.Parent.Parent.scientistFrame.ImageColor3 = Color3.new(0,0.69,0)
Defense += 0.5
task.wait(5)
script.Parent.Parent.attackedLabel.Text = "Your attack raised!"
script.Parent.Parent.scientistFrame.ImageColor3 = Color3.new(1,1,1)
task.wait(3)
script.Parent.Parent.attackedLabel.Text = "You were attacked!"
task.wait(2)
Humanoid.Health -= math.random(5,15)
task.wait(3)
Humanoid.Health += 45
script.Parent.Visible = true
script.Parent.Parent.attackedLabel.Visible = false
elseif HP.Value > 0 and DefenseProtocol == true and CheckOne == true and CheckTwo == true then
task.wait(2)
HealthFrame.Parent.Visible = false
script.Parent.Parent.attackedLabel.Text = "You were attacked!"
task.wait(2)
Humanoid.Health -= math.random(5,15)
task.wait(3)
script.Parent.Visible = true
script.Parent.Parent.attackedLabel.Visible = false
elseif HP.Value <= 0 then
task.wait(5)
HealthFrame.Parent.Visible = false
task.wait(1)
script.Parent.Parent.attackedLabel.Text = "You defeated the Scientist!"
task.wait(5)
local X = script.Parent.Parent.scientistFrame.Position.X.Scale
local Y = script.Parent.Parent.scientistFrame.Position.Y.Scale
script.scream:Play()
task.wait(0.8)
script.scream.Ended:Wait()
task.wait(2)
script.Parent.Parent.scientistFrame:TweenPosition(UDim2.new(X, 0, Y + 50, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 30)
script.wooshhh:Play()
else
task.wait(2)
HealthFrame.Parent.Visible = false
script.Parent.Parent.attackedLabel.Text = "You were attacked!"
task.wait(2)
Humanoid.Health -= math.random(5,15)
task.wait(3)
script.Parent.Visible = true
script.Parent.Parent.attackedLabel.Visible = false
end
end
end)```
Your script should be optimized. Always. Unless you’re one of those game owners who try to crash the client’s game on purpose, then don’t.
But a lot of your values are being changed with paths and not variables. I recommend making everything that is used at least twice to be put into a variable so, for next time, it’s not as strenuous on yourself and it’s better to refer back to if you need to edit it in any way.
The amount of task.wait() is scary! You should definitely optimize this code, if not for performance, but for readability and flexibility, which will help you out in the future.
First of all, I would put all UI/tween/shake logic in another file (local script?) and only deal with health/powerup logic here, sending events to the client after player health or state changes.
Second, make more functions! Like IsHumanoidAlive() or PlayerHasDefenseBuff() and etc. If you will want to change the damage ranges in the future, you will have to replace built in numbers in 5 places! Improve your quality of life with:
function GetDamage()
return math.random(5, 15)
end
you mean math.random or NumberRange? Anyways, I agree. task.wait always slows your game down. At least it’s not in multiple threads.
Yes, should’ve been random! Edited my post.Thanks.
maybe your code is unoptomized, but that’s not really your biggest problem here. Focus on making your code more readable and maintainable. There’s a TON of stuff thrown into your MouseButton1Click callback. You’ve got damage decisions, visual and sound effects, and a LONG elseif chain in there.
Furthermore, decode the following:

script.parent.parent.parent
script.parent.parent.parent.parent.parent
script.parent.parent.parent.parent
script.parent
script.parent.parent
(Answer: you should use variables for repeatedly referenced things because its hard to read script.parent.parent.parent)
Breaking up different tasks into their own functions and using variables will help DRAMATICALLY with managing this script for future edits.
After (not before, but after) youve fixed maintainability issues, ask yourself whether you actually need to optimize this code. Does it actually lag? Does it actually contain memory leaks or run when it’s not supposed to? If not, don’t stress too much about optimization. There’s a frequently quoted saying in programming that goes, “premature optimization is the root of all evil.” This is because if you make microoptimizations that don’t actually matter, you will sacrifice readability and maintainability.
If you ask yourself this question and decide that yes, you do need to optimize this code, make sure it abides by these general rules:
- Don’t do twice what you can get away with doing once (i.e. if you have to format data or something, and the data doesnt change, don’t reformat it)
- Don’t do things that you dont need to do (as in, remove extraneous steps)
- When you’re done using what you stored, get rid of it (lua does this automatically with garbage collection, but there are some nuances that can lead to memory leaks if youre not careful. I’d definitely recommend reading up on that)
- Don’t send anything across the client-server boundary that you don’t need to send (don’t spam remotes if you don’t have to, don’t send a 100-entry table when you just need two keys from that table)