Optimization for @Katrist’s script would be as followed.

`task.wait(0.01)`

would not specifically wait `0.01`

seconds, this is an unreliable method. So instead we are going to use `Runservice`

.

```
local RunService = game:GetService("RunService")
RunService:BindToRenderStepped("Timer", 1, function(dt)
...
end)
```

`dt`

stands for `Delta time`

also known as the change in time. How long it took to go from frame 1 to frame 2 etc.

Now we will save the time

```
local t = 0
```

And to change the time we will use:

```
t += dt
```

Now to get the miliseconds we can just use:

```
-- here we can round it off, but it doesnt make much difference
local mili = math.floor((t % 1) * 1000)
```

For the seconds we can do:

```
local sec = math.floor(t % 60)
```

And lastely for minutes we can use:

```
local min = math.floor(t/60)
```

Now a quick explaination on `%`

, also known as the remainder. Basically `X % Y`

is the same as

```
local X, Y = ...
print(X%Y)
print(((X/Y) - math.floor(X/Y)) * Y)
```

Basically you get the remainder which is left.

Example:

```
0%3 = 0; 3%3 = 0; 6%3 = 0
1%3 = 1; 4%3 = 1; 7%3 = 1
2%3 = 2; 5%3 = 0; 8%3 = 2
```

Now we turn all the values into strings with `tostring()`

, though this is not necessary, but will surely prevent any errors.

Then we will add 0s to the values until they are big enough. For example we got the string `"1"`

for seconds, we want that to become `"01"`

, so we will need to repeatedly add `0`

s to the value. Same for the milliseconds, but `"1"`

, would become `"001"`

, well because `1000`

millisecond is the same as `1`

second.

(Remember they have to be strings for this) Now we will get the length of the numbers and then add `0`

s to them until it’s not needed anymore. We can use `#`

to get the length. It would look like this:

```
min = string.rep("0", 2 - #min) .. min
sec = string.rep("0", 2 - #sec) .. sec
milli = string.rep("0", 3 - #milli) .. milli
```

Now we only have to put double collumns `:`

in between of them like so:

```
timer.Text = min .. ":" .. sec .. ":" .. milli
```

Now the code would look something like this:

```
local RunService = game:GetService("RunService")
local timer = script.Parent
local t = 0
RunService:BindToRenderStepped("Timer", 1, function(dt)
t += dt
local min, sec, milli = (math.floor(t/60)), (math.floor(t % 60)), (math.floor((t % 1) * 1000))
min, sec, milli = tostring(min), tostring(sec), tostring(milli)
min, sec, milli = string.rep("0", 2 - #min) .. min, string.rep("0", 2 - #sec) .. sec, string.rep("0", 3 - #milli) .. milli
timer.Text = min .. ":" .. sec .. ":" .. milli
end)
```

This will run every frame unlike `while true do`

as well as accurately count the time unlike `task.wait()`

.