Very Long Lighting Code, May Need Shortening

• What does the code do and what are you not satisfied with?
The code operates how a light works. Changes intensity and color using randomization.
• What potential improvements have you considered?
I am not sure, I just started coding a week or two ago in Lua.
• How (specifically) do you want to improve the code?
Perhaps make the code shorter, is there something that can be done to optimize the code? The code looks ridiculously long for all that it’s doing and I am not sure if that’s normal because I am new. This code is being run on 8 lights in my disco module and I am concerned that if I added more it could slow the game down.
``````local pointLight = script.parent
pointLight.Brightness = 0
pointLight.Range = 0
pointLight.Color = Color3.fromRGB(0,0,0)
local x = 0
local y = 0
local z = 0
local redColorAdd = 0
local greenColorAdd = 0
local blueColorAdd = 0
local redColor = 0
local greenColor = 0
local blueColor = 0
local range = 0
local brightness = 0
local addbrightness = true
local addrange = true
local addRed = true
local addGreen = true
local addBlue = true
while true do
wait(0.1)
local random = Random.new()
if redColor < 127 then
x = (redColor+1)^(0.25)
end
if redColor > 127 then
x = (256-redColor)^(0.25)
end
if greenColor < 127 then
y = (greenColor+1)^(0.25)
end
if greenColor > 127 then
y = (256-greenColor)^(0.25)
end
if blueColor < 127 then
z = (blueColor+1)^(0.25)
end
if blueColor > 127 then
z = (256-blueColor)^(0.25)
end
local redColorAdd = math.floor(random:NextNumber(x*0.15,x*7))
local greenColorAdd = math.floor(random:NextNumber(y*0.15,y*7))
local blueColorAdd = math.floor(random:NextNumber(z*0.15,z*7))
if addRed == true then
redColor = redColorAdd + redColor
if redColor > 255 then
redColor = 255-(redColor-255)
end
end
if addGreen == true then
greenColor = greenColorAdd + greenColor
if greenColor > 255 then
greenColor = 255-(greenColor-255)
end
end
if addBlue == true then
blueColor = blueColorAdd + blueColor
if blueColor > 255 then
blueColor = 255-(blueColor-255)
end
end
if addRed == false then
redColor = redColor - redColorAdd
if redColor < 0 then
redColor = -redColor
end
end
if addGreen == false then
greenColor = greenColor - greenColorAdd
if greenColor < 0 then
greenColor = -greenColor
end
end
if addBlue == false then
blueColor = blueColor - blueColorAdd
if blueColor < 0 then
blueColor = -blueColor
end
end
local randomizer1 = math.random()*4
local randomizer2 = math.random()*3
if addbrightness == true then
brightness = brightness + randomizer1
if brightness > 40 then
brightness = 40-(brightness-40)
end
end
if addbrightness == false then
brightness = brightness - randomizer1
if brightness < 5 then
brightness = 10-(brightness-10)
end
end
if addrange == true then
range = range + randomizer2
if range > 60 then
range = 60-(range-60)
end
end
if addrange == false then
range = range - randomizer2
if range < 15 then
range = 15-(range-15)
end
end
pointLight.Color = Color3.fromRGB(redColor,greenColor,blueColor)
pointLight.Brightness = brightness
pointLight.Range = range
end
``````

Note: What to do if value is 127,127,127

``````local pointLight = script.parent
pointLight.Brightness = 0
pointLight.Range = 0
pointLight.Color = Color3.fromRGB(0,0,0)
local x = 0
local y = 0
local z = 0
local redColorAdd = 0
local greenColorAdd = 0
local blueColorAdd = 0
local redColor = 0
local greenColor = 0
local blueColor = 0
local range = 0
local brightness = 0
local addbrightness = true
local addrange = true
local addRed = true
local addGreen = true
local addBlue = true
while wait(0.1) do
local random = Random.new()
if redColor < 127 then
x = (redColor+1)^(0.25)
elseif redColor > 127 then
x = (256-redColor)^(0.25)
end
if greenColor < 127 then
y = (greenColor+1)^(0.25)
elseif greenColor > 127 then
y = (256-greenColor)^(0.25)
end
if blueColor < 127 then
z = (blueColor+1)^(0.25)
elseif blueColor > 127 then
z = (256-blueColor)^(0.25)
end
local redColorAdd = math.floor(random:NextNumber(x*0.15,x*7))
local greenColorAdd = math.floor(random:NextNumber(y*0.15,y*7))
local blueColorAdd = math.floor(random:NextNumber(z*0.15,z*7))
redColor = redColorAdd + redColor
if redColor > 255 then
redColor = 255-(redColor-255)
end
else
redColor = redColor - redColorAdd
if redColor < 0 then
redColor = -redColor
end
end
greenColor = greenColorAdd + greenColor
if greenColor > 255 then
greenColor = 255-(greenColor-255)
end
else
greenColor = greenColor - greenColorAdd
if greenColor < 0 then
greenColor = -greenColor
end
end
blueColor = blueColorAdd + blueColor
if blueColor > 255 then
blueColor = 255-(blueColor-255)
end
else
blueColor = blueColor - blueColorAdd
if blueColor < 0 then
blueColor = -blueColor
end
end
local randomizer1 = math.random()*4
local randomizer2 = math.random()*3
brightness = brightness + randomizer1
if brightness > 40 then
brightness = 40-(brightness-40)
end
else
brightness = brightness - randomizer1
if brightness < 5 then
brightness = 10-(brightness-10)
end
end
range = range + randomizer2
if range > 60 then
range = 60-(range-60)
end
else
range = range - randomizer2
if range < 15 then
range = 15-(range-15)
end
end
pointLight.Color = Color3.fromRGB(redColor,greenColor,blueColor)
pointLight.Brightness = brightness
pointLight.Range = range
end
``````
2 Likes

Good catch, I’ll make it a greater or equal to instead of just greater than. Thank you!

Edit: whoops, just noticed the code you attached with the reply. Will update my script.

1 Like

One tip is that you can define all of your variables on one line. For example,

`local varname1, varname2 = varvalue1, varvalue2`

This chunk:

``````local x = 0
local y = 0
local z = 0
local redColorAdd = 0
local greenColorAdd = 0
local blueColorAdd = 0
local redColor = 0
local greenColor = 0
local blueColor = 0
local range = 0
local brightness = 0
local addbrightness = true
local addrange = true
local addRed = true
local addGreen = true
local addBlue = true
``````

Can be changed into this chunk:

``````local x, y, z, redColorAdd, greenColorAdd, blueColorAdd, redColor, greenColor, blueColor, range, brightness, addbrightness, addrange, addRed, addGreen, addBlue = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, true, true, true, true
``````
2 Likes

It can get messy if the line becomes too long. Better for organizing.

2 Likes

I didn’t know that, thanks! I will do that for the different color variables in groups of three and also for
x, y, z.

1 Like

You should use `else if ` instead of creating a new statement each time.

2 Likes

I noticed that but he has a lot of embedded if statements so that may not work too well.

1 Like

There are a few things in your script that could be improved.

The first thing I would remove is the `while true` loop and replace it with heartbeat from RunService.

From reading your original code I get the impression that you have put that script inside each individual light, the code below does not need to be placed under each object, instead it needs 1 copy inside `ServerScriptService`. This is good practice for multiple reasons; to start this method is a lot more performant especially if you have lots of lights. The next reason is improved maintainability, should you want to modify the code, you only have to change the 1 script not all of them. This also extends to if you start wanting to use Rojo or something similar, those tools really are not designed to have code scattered around the workspace randomly.

To remove the requirement for it to be placed under every object, I am using CollectionService to find all of the lights then looping though that list to modify them individually. I would recommend using the TagEditor plugin to make tagging the lights to a collection much easier. To make each light ‘unique’ each individual light stores data inside itself using attributes, the code below requires 2 boolean attributes called `addRange` and `addBrightness` I would recommend randomising there starting state to make the lights less in sync. Should you wish for even more randomness you could add the speed variable as an attribute and modify the code accordingly.

The first if statement `if tick() >= lastUpdate + speed then` is used to only run the following code every `speed` seconds.

To avoid the necessity for the messy nested if statements in the original code to clamp the values I have replaced them with `math.min/max`.

The next thing that I would change simply for aesthetics is having random colours picked, this is because you are very likely to end up with ugly colours choses (brown, grey etc.) which will not look good for lights. In the code below I have created a table with a selection of different light colours that can be chosen.

To make the transitions of the variables smooth I have also incorporated TweenService, feel free to play around with `tInfo` to make it transition however you would like it to.

``````local runService = game:GetService("RunService")
local collectionService = game:GetService("CollectionService")
local tweenService = game:GetService("TweenService")

local allPointLights = collectionService:GetTagged("DiscoLights") -- Negates the need to have this script in every light and makes adding lights easier (Get tag editor plugin)

local lightColours = { -- Ensures lights only have 'good' colours, e.g. no brown / grey lights
Color3.fromRGB(255, 0, 0),
Color3.fromRGB(0, 255, 0),
Color3.fromRGB(0, 110, 255),
Color3.fromRGB(187, 19, 230),
Color3.fromRGB(241, 184, 26),
}

local speed, lastUpdate = 1, tick()

runService.Heartbeat:Connect(function(dt) -- Replaces the while true loop
if tick() >= lastUpdate + speed then -- Only updates every second (set by variable above)
for i = 1, #allPointLights do
-- Colour
local targetColour = lightColours[math.random(1, #lightColours)]

-- Brightness
local addBrightness = allPointLights[i]:GetAttribute("addBrightness") -- Bool attribute
local randomBright = math.random()*4
local targetBright

targetBright = math.max(40, allPointLights[i].Brightness + randomBright)
else
targetBright = math.min(15, allPointLights[i].Brightness - randomBright)
end

-- Range
local addRange = allPointLights[i]:GetAttribute("addRange") -- Bool attribute
local randomRange = math.random()*3
local targetRange

targetRange = math.max(40, allPointLights[i].Range + randomRange)
else
targetRange = math.min(15, allPointLights[i].Range - randomRange)
end

-- Tween changes to make it look nice (Could also lerp)
local tInfo = TweenInfo.new(speed, Enum.EasingStyle.Cubic)
local goal = {
Color = targetColour,
Brightness = targetBright,
Range = targetRange
}
tweenService:Create(allPointLights[i], tInfo, goal):Play()
end
end
end)
``````
3 Likes

Wow. I greatly appreciate this answer, and also the extra explanation behind each function! There is clearly a lot I have to learn about coding in Lua.