Hello, I threw this clock together for decoration and thought I’d share it for anyone in need of such a thing. Feel free to suggest improvements you’d like me to make or take it for your own use.

[gif is imperfectly looped]

I’m in no way saying this is perfect and once again it’s just something I threw together pretty quickly and thought might be useful for someone else.

All of this also has variable framerate so you can adapt it to your own needs in terms of optimizing, all you need to do is change the 24 on line 12 to whatever rate you wish it to run at.

(24 = 24 fps, 60 = 60 fps etc)

It works by converting local time grabbed from os.date to an alpha between 0-1 and lerping the hour/minute hand relative to their starting position.

## time alphas

[h = hour, m = minute]

[m = minute, s = second]

I also threw in a pendulum that’s animated and timed to the minute hand moving (every second) and works by converting tick() into a sine wave and alpha using it to lerp the pendulum.

## pendulum easing alpha

[t = tick()]

The way I use this in games is by calling the function from a localscript that searches through animatable models in workspace but you definitely do not need to deploy it this way, could just call it directly from a dedicated localscript without issue of course.

## script

```
local clock = script.Parent
local poleRoot = clock:WaitForChild('poleRoot')
local poleRootPos = poleRoot.CFrame
local hourRoot = clock:WaitForChild('hourRoot')
local hourRootPos = hourRoot.CFrame
local minuteRoot = clock:WaitForChild('minuteRoot')
local minuteRootPos = minuteRoot.CFrame
return function()
local last = tick()
game:GetService('RunService').RenderStepped:Connect(function()
if tick()-last < 1/24 then return end -- change (the 24) to modify rate, remove to make run on players framerate
last = tick()
local defaultHandPos = CFrame.Angles(math.rad(180),0,0)
local d = os.date("*t")
print(hourRootPos)
poleRoot.CFrame = poleRootPos:Lerp(poleRootPos*CFrame.Angles(math.rad(-30),0,0), math.sin(math.pi/2 + tick()*math.pi)/2+.5)
hourRoot.CFrame = hourRootPos:Lerp(hourRootPos*defaultHandPos, (d['hour']+d['min']/60)/12*2)
minuteRoot.CFrame = minuteRootPos:Lerp(minuteRootPos*defaultHandPos, (d['min']+d['sec']/60)/60*2)
end)
end
```

Here’s the model for anyone interested: