FiveM routing buckets: SetPlayerRoutingBucket, instances and voice

How FiveM routing buckets work: SetPlayerRoutingBucket, SetEntityRoutingBucket, population and lockdown settings, bucket 0, use cases and what happens to voice.

The symptom: two groups of players share the same location and you want them separated, or players in a minigame see a world full of other people's cars and pedestrians.

Routing buckets are FiveM's version of dimensions or instances. Entities and players in different buckets do not see each other. They are the tool behind apartments, minigames and character selection screens, and they are managed on the server. This article covers each native and the mistakes to avoid.

What a routing bucket is

A bucket is a number. Every player and every entity belongs to exactly one bucket, and the default is 0. Two things in different buckets are invisible to each other: players do not see the other bucket's players, vehicles or props, and they do not interact. They still share the same map, so the coordinates stay the same.

This only works on a server with OneSync, which current servers use. See enabling OneSync if you are not sure.

The core natives

All of these run on the server:

lua
-- put a player in a bucket, and read it back
SetPlayerRoutingBucket(source, 50)
local bucket = GetPlayerRoutingBucket(source)

-- put an entity (vehicle, ped, object) in a bucket
SetEntityRoutingBucket(vehicle, 50)
local entityBucket = GetEntityRoutingBucket(vehicle)

-- back to the default world
SetPlayerRoutingBucket(source, 0)

SetPlayerRoutingBucket takes the player's server id and a bucket number. SetEntityRoutingBucket takes the entity handle. Entities you create on the server after the player moved start in bucket 0 unless you move them, so set the bucket right after creating them:

lua
local veh = CreateVehicle(`sultan`, 0.0, 0.0, 70.0, 0.0, true, true)
SetEntityRoutingBucket(veh, 50)

Pick bucket numbers on purpose. A common habit is to reserve ranges, for example one range for houses, one for minigames, so two features never reuse a number by accident.

Warning: these natives are server-only. Calling them from a client script does nothing useful. Send an event to the server and let the server move the player, after it has checked the request.

Population and lockdown

Each bucket can have its own rules:

lua
-- no ambient pedestrians or traffic in bucket 50
SetRoutingBucketPopulationEnabled(50, false)

-- who may create entities in bucket 50
SetRoutingBucketEntityLockdownMode(50, 'strict')
  • SetRoutingBucketPopulationEnabled(bucket, false) turns off ambient NPCs and traffic in that bucket. It is useful for instances, because an empty interior or a minigame does not need cars driving through it. Bucket 0 keeps its normal population.
  • SetRoutingBucketEntityLockdownMode(bucket, mode) controls entity creation. The modes are 'strict', 'relaxed' and 'inactive', and 'inactive' is the normal behaviour, with 'strict' being the tightest. Check the native's documentation for the exact difference before you rely on one.

Setting a new bucket's rules once, when it is first used, is enough. They stay for the life of the server.

Use cases

  • Apartments and houses: one bucket per property, so identical interiors do not overlap. The full pattern is in housing and instances.
  • Minigames and events: put the participants in a private bucket with population off, so nothing outside interferes.
  • Character selection and creation: put the player in a private bucket while they pick a character, so they are not seen standing in the world, and move them to 0 when they spawn.
  • Tutorials and admin spaces: a quiet bucket to explain things without the rest of the server.
  • Testing: try a script away from players.

Voice in buckets

Because players in different buckets are not near each other from the game's point of view, proximity voice generally follows the same separation. Voice resources such as pma-voice are built around OneSync and work per bucket, so players in a house do not hear the street. If you want people in different buckets to talk, use the voice resource's own channel or call features instead of fighting the buckets. If voice is silent after you move players, see pma-voice not working. Test it with two real players, not only with one.

A reusable instance helper

Keep the bucket logic in one place, so every exit path resets it:

lua
local instances = {}   -- [source] = bucket

function EnterInstance(src, bucket)
    instances[src] = bucket
    SetPlayerRoutingBucket(src, bucket)
end

function LeaveInstance(src)
    instances[src] = nil
    SetPlayerRoutingBucket(src, 0)
end

AddEventHandler('playerDropped', function()
    instances[source] = nil
end)

Call LeaveInstance on exit, on death, and when your resource stops:

lua
AddEventHandler('onResourceStop', function(resource)
    if resource ~= GetCurrentResourceName() then return end
    for src in pairs(instances) do
        SetPlayerRoutingBucket(src, 0)
    end
end)

Without that last handler, a script restart leaves players alone in an empty bucket.

Common problems

  • A player is stuck alone: they were never moved back to 0. Reset on every exit path and on resource stop.
  • A vehicle is missing for the passenger: the player and the vehicle ended up in different buckets. Move both.
  • Spawned entities appear in the wrong world: new server-side entities start in bucket 0.
  • Different features reuse the same number and players land in each other's instance: reserve ranges.
  • Calling the natives on the client: they belong on the server.

Checklist

Symptom Fix
Players see the wrong world Check GetPlayerRoutingBucket for both players
Player alone after a restart Reset buckets on onResourceStop
Vehicle not visible to the driver's friends Set the vehicle's bucket too
Traffic inside an instance SetRoutingBucketPopulationEnabled(bucket, false)
Cannot hear anyone Same bucket, then check the voice resource
Nothing happens on the client The natives are server-side

Quick answers

What is the default routing bucket?

Bucket 0. Every player and entity starts there unless a script moves it.

Can a client change its own routing bucket?

No. The natives are server-side. The client asks, and the server decides and moves the player.

Do vehicles move with the player when I change the bucket?

Do not rely on it. Move the vehicle explicitly with SetEntityRoutingBucket, and check the result in your own tests.

Scripts that skip this problem

Arcade MachinesSeven playable arcade games in real cabinets, with leaderboards and bets.View script →CCTV Security CamerasPlaceable cameras, a live multi-view tablet and printed evidence photos.View script →

Keep reading