Adjusting the TimeScale of the Client

You can control the client's animation speed, movement speed, and physics speed using [UtilLogic](/apiReference/Logics/UtilLogic)'s `SetClientTimeScale()`. You can create a more immersive world by controlling the camera effect or animation speed with this method.

##### Reference Guide

  * [UtilLogic](/apiReference/Logics/UtilLogic)



## SetClientTimeScale

Adjust the time of the entire world by changing the value delivered to `Update(deltaTime)` from the client through `SetClientTimeScale()`. The default value is 1, and any value between 0–100 can be used. Negative numbers can't be used. Even if the deltaTime value changes with `SetClientTimeScale()`, the Update call frequency remains the same. For example, if there are 60 frames per second, if the TimeScale value is set to 3, the frames per second won't be tripled to 180, but rather, the `deltaTime` value delivered from each frame will be tripled. So the server will not be affected by the new value, and only the client and entity will have their second increased at triple speed.

[gif](1774245408714fb25081cef3b4c9eac5b7ef7c52a4194)

The `SetClientTimeScale()` method affects the time of the entire world, so APIs that have properties or functions that are related to time or speed will be affected. For example, writing the following means that, since `OnBeginPlay()` will be executed in the server and client, `Wait()` will be active in both, while `SetClientTimeScale()` will only function in the client.
    
    
    @Component
    script TimeScaleSetter extends Component
        method void OnBeginPlay()
        log("Current Time")
        wait(10)
        _UtilLogic:SetClientTimeScale(2)
        log("Current Time")
        end
    end
    

Log values triggered in the server happen in exact 10-second intervals, so following the first log at 20:24:33, the next log will be output at 20:24:43. However, since the client's TimeScale has been doubled, the client's log value will first be output at 20:24:33 and again at 20:24:38.

[png](17740064823740459c88eb7b44ffda3289c1801959301)

### Affected API

The following is a list of what is affected by `UtilLogic:SetClientTimeScale()`.

[{"Name":"AIComponent","Desc":"The Delta of OnBehave() changes by the amount multiplied by TimeScale. Affected when the AIComponent component's UpdateAuthority is the Client."},{"Name":"BackgroundComponent","Desc":"Animations in the background are affected if the type is Template."},{"Name":"CameraComponent","Desc":"ZoomTo() is affected."},{"Name":"ChatBalloonComponent","Desc":"Only properties related to time are affected."},{"Name":"DamageSkinComponent","Desc":"All properties and methods are affected."},{"Name":"PlayerControllerComponent","Desc":"All methods related to movement are affected."},{"Name":"SpriteRendererComponent","Desc":"Affected if the SpriteRUID is an AnimationClip."},{"Name":"TimerService","Desc":"Affected if executed from the client environment script."},{"Name":"TweenLogic","Desc":"Affected if executed from the client environment script."},{"Name":"Material","Desc":"Materials that have TimeScale properties related to time are affected. For example, if the material's TimeScale value is 2 and SetClientTimeScale value is 2, 4x will be applied."},{"Name":"Physical","Desc":"PhysicsRigidbodyComponent', 'PhysicsColliderComponent', 'RevoluteJointComponent', 'PrismaticJointComponent', 'PulleyJointComponent', 'WeldJointComponent', and 'WheelJointComponent are affected. All are affected during the Client Only state."},{"Name":"Movement","Desc":"RigidbodyComponent', 'KinematicBodyComponent', and 'SideViewBodyComponent are affected."},{"Name":"Particle","Desc":"AreaParticleComponent', 'BasicParticleComponent', 'BaseParticleComponent', and 'SpriteParticleComponent are affected."}]

### Unaffected API

The following is a list of what is unaffected by `UtilLogic:SetClientTimeScale()`.

[{"Name":"ScreenMessageLogic","Desc":"Displaying the notification message isn't affected by TimeScale."},{"Name":"ScreenTransitionService","Desc":"Screen transition effect duration isn't affected by TimeScale."},{"Name":"SoundComponent","Desc":"Sound effect play speed isn't affected by TimeScale. The speed is controlled through the Pitch property."},{"Name":"UtilLogic","Desc":"ElapsedSeconds isn't affected by TimeScale, and time flows consistently."},{"Name":"WebViewComponent","Desc":"Webview screen isn't affected by TimeScale."},{"Name":"YoutubePlayerWorldComponent, YoutubePlayerGUI","Desc":"Video play speed isn't affected by TimeScale. The speed is controlled with PlaySpeed."}]

## When Clients Have Differing TimeScale Values

When multiple clients each have different TimeScale values, each client follows their own world speed. Let's assume Player A is in an area where the TimeScale value gets faster while Player B is in an area where the TimeScale value gets slower. Even though Player A's TimeScale is faster, Player B's movement will look very slow. This is because the speed change for Player B's position information is determined by Client B's TimeScale. When Client B's speed is slow, then Player B's movement and position changes will be applied slowly in Client A as well. Since the play speed of multi-jumping, attacks, AnimationClip, etc. are processed by each client individually, Player B's animation in Client A will look normal, but its actual change in position will be processed at a lower speed.

[gif](17742417136167a4ceb01859b4b059c1936b1fe7218f8)

### Example

Let's make it so that the TimeScale value increases in the orange ray area and decrease in the green ray area. You can see that the flow of time for the entire world changes based on the TimeScale value changes. Let's add an entity to the map and designate material to see the changes in the TimeScale. Refer to [Implementing Materials](/docs?postId=1323) on how to designate materials.

[gif](17740068053871043ed1e8999496aaf514e14390eff88)

  1. Create a new SpeedUpLight entity on the map and add a TriggerComponent.
  2. Create a trigger area that's similar in size as the sprite by pressing the [Edit] button from TriggerComponent - Collider.
  3. Create a new CurrentTime logic to Workspace - MyDesk and write the following. 
         
         @Component
         script ActiveTimeScale extends Component
         property number NowTimeScale = 1
         end
         



    
    
    4. Create a new **ChangeSpeed** component to **Workspace - MyDesk**.
    5.  Add a **ChangeSpeed** component to the **SpeedUpLight** entity.
    6.  Write the following into the **ChangeSpeed** component.
    
        ```lua
    @Component
    script PlayerTimeScaleAdjuster extends Component
        @Sync
        property number ChangeRate = 0
    
        @ExecSpace("ClientOnly")
        method void ChangeScale()
        _CurrentTime.NowTimeScale = _CurrentTime.NowTimeScale + self.ChangeRate
        _CurrentTime.NowTimeScale = math.clamp(_CurrentTime.NowTimeScale,0.36, 5)
        _UtilLogic:SetClientTimeScale(_CurrentTime.NowTimeScale)
        end
    
        @EventSender("Self")
        handler HandleTriggerStayEvent(TriggerStayEvent event)
        --------------- Native Event Sender Info ----------------
        -- Sender: TriggerComponent
        -- Space: Server, Client
        ---------------------------------------------------------
    
        -- Parameters
        -- local TriggerBodyEntity = event.TriggerBodyEntity
        ---------------------------------------------------------
    
        if self:IsClient()  then
            if  _UserService.LocalPlayer.Name == event.TriggerBodyEntity.Name then
                self:ChangeScale()
            end
        end
        end
    end
    

  7. Enter 0.5 for ChangeRate in the property window.
  8. Copy the SpeedUpLight entity and change its name to SpeedDownLight.
  9. Change the SpeedDownLight entity's ChangeRate value to -0.03.



## Warning

The client may randomly control the time multiplier and affect the world negatively. So the time multiplier should be created so it will not affect the world's main functions or paid content. Also, adding an authentication logic to detect abnormal inputs will help.