CCL quick start

In the Character Controller Library (CCL), traditional character abilities (run, climb, jump, swim, etc.) are easily configurable through scripting. For custom character mechanics such as dashing, aiming, wall‑jumping, and more, see custom abilities.

Enable CCL

The CCL is opt-in through Studio's Avatar Settings window. To enable it:

  1. Enable the CCL beta through File ⟩ Beta Features ⟩ AvatarAbilities Character Controller Library.

  2. From the Avatar tab, open Avatar Settings.

    Avatar Settings indicated in Studio's toolbar
  3. Select the Movement tab on the left side of the window and, in the Abilities section, select Character Controller Library.

    Character Controller Library toggle in the Avatar Settings window
  4. All of the standard abilities like Running, Jumping, and Climbing are enabled by default. To disable any of them at runtime, uncheck the associated box.

Configuration

Through a script that runs from ServerScriptService, you can experiment with the built‑in ability attributes. You can also modify specific controllers to adjust the physical simulation of the character and its interaction with the environment, such as the character's base movement speed.

Attributes

At runtime, CCL exposes each built-in ability as a Configuration in the character's Abilities folder. This folder usually lives under AbilityManagerActor, but it can live directly under the character in setups without an actor. Use AvatarAbilities.getAbilityConfigurationForCharacter() to access an ability configuration from either setup.

Each ability contains easy-to-configure attributes such as those noted in the table below. Some attributes correspond to legacy Humanoid properties. This relationship identifies equivalent settings, not bidirectional synchronization. The compatibility layer copies changes from these Humanoid properties to the corresponding ability attributes. Jumping attributes initially use the corresponding StarterPlayer character properties.

AbilityAttributes
Climbing
Crouching
Dead
FallingDown
Freefall
  • SpeedMultiplier — Multiplier to the AirController.MoveSpeedFactor property when character is free‑falling. Note that the effect may be subtle when the character free‑falls for a very short duration.
GettingUp
Jumping
NoLocomotion
Running
Sitting
Slipping
Sprinting
Swimming
  • EnableFastRise — Rise to surface more quickly by holding the jump input.
  • SpeedMultiplier — Multiplier to the SwimController.MoveSpeedFactor property when character is swimming.
Turning
  • UseLookDirectionInput — Uses look-direction input instead of movement input to determine the character's facing direction.

To set ability configurations for all characters through a script:

  1. Create a new server-side Script within ServerScriptService and rename it to AbilitiesScript.

  2. Copy and paste the following code into the new script. This example multiplies the base movement speed for the Running ability by 2. Feel free to adjust other ability attributes such as those described in the table above.

    Script in ServerScriptService
    local Players = game:GetService("Players")
    local AvatarAbilities = require("@rbx/AvatarAbilities")
    local function waitForAbilityConfiguration(character, abilityName, timeout)
    local deadline = time() + timeout
    while character.Parent and time() < deadline do
    local ability = AvatarAbilities.getAbilityConfigurationForCharacter(character, abilityName)
    if ability then
    return ability
    end
    task.wait()
    end
    return nil
    end
    local function onCharacterAdded(character)
    local running = waitForAbilityConfiguration(character, "Running", 10)
    if running then
    -- Double base movement speed
    running:SetAttribute("SpeedMultiplier", 2)
    end
    end
    local function onPlayerAdded(player)
    if player.Character then
    onCharacterAdded(player.Character)
    end
    player.CharacterAdded:Connect(onCharacterAdded)
    end
    Players.PlayerAdded:Connect(onPlayerAdded)
    for _, player in Players:GetPlayers() do
    onPlayerAdded(player)
    end

Controllers

In the CCL, a core ControllerManager instance within the character model, alongside child controllers such as a GroundController, handle the physical simulation of the character and its interaction with the environment. Abilities then interact with the ControllerManager and its descendants to modify controller behaviors or switch between controllers.

Properties for the ControllerManager and its controller descendants are summarized in the tables below, although these tables are not exhaustive; please consult the API classes documentation for additional property options.

PropertyDescription
BaseMoveSpeedThe base linear movement speed used by all controllers. Controllers individually customize movement speed through their MoveSpeedFactor property.
BaseTurnSpeedThe base angular turning speed used by all controllers to align the character to face the desired direction. Some controllers individually customize turn speed through their TurnSpeedFactor property.
UpDirectionVector3 which indicates the upward-facing vector for the ControllerManager.RootPart.

To set controller configurations for all characters through a script:

  1. Create a new server-side Script within ServerScriptService and rename it to ControllerScript.
  2. Copy and paste the following code into the new script. This example increases ground‑based moving/turning speed as well adds a slight acceleration and deceleration time. Feel free to adjust other properties such as those described in the tables above or for each class as documented (ControllerManager; GroundController; AirController; ClimbController; SwimController).
Script in ServerScriptService
local Players = game:GetService("Players")
local AvatarAbilities = require("@rbx/AvatarAbilities")
local function waitForAbilityConfiguration(character, abilityName, timeout)
local deadline = time() + timeout
while character.Parent and time() < deadline do
local ability = AvatarAbilities.getAbilityConfigurationForCharacter(character, abilityName)
if ability then
return ability
end
task.wait()
end
return nil
end
local function waitForChildOfClass(parent, className, timeout)
local deadline = time() + timeout
local child = parent:FindFirstChildOfClass(className)
while not child and parent.Parent and time() < deadline do
task.wait()
child = parent:FindFirstChildOfClass(className)
end
return child
end
local function onCharacterAdded(character)
-- Running provisions the ground controller when it registers
if not waitForAbilityConfiguration(character, "Running", 10) then
return
end
local controllerManager = waitForChildOfClass(character, "ControllerManager", 10)
if controllerManager then
local groundController = waitForChildOfClass(controllerManager, "GroundController", 10)
if groundController then
-- Double the move and turn speeds
groundController.MoveSpeedFactor *= 2
groundController.TurnSpeedFactor *= 2
-- Add slight acceleration and deceleration
groundController.AccelerationTime = 0.2
groundController.DecelerationTime = 0.4
end
end
end
local function onPlayerAdded(player)
if player.Character then
onCharacterAdded(player.Character)
end
player.CharacterAdded:Connect(onCharacterAdded)
end
Players.PlayerAdded:Connect(onPlayerAdded)
for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end
©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.