Optimizing region code running on Heartbeat

I’ve been trying for a few weeks now to come up with a clean solution to efficiently detect when players enter/exit a region. Unfortunately, my best efforts have led to running some fairly heavy RotatedRegion3 methods on the game’s Heartbeat.

Since I’m currently only using this implementation for a safe zone, I’m having the clients notify the server when they’ve entered a zone, but the server still has to determine when they’ve left the zone for security reasons.

This implementation puts no load on the server when no players are in the safezones, but since the game’s spawn is a safezone in of itself, it still has to run 30 times a second, per player (at spawn) which could potentially be in the hundreds, causing the script to take up well over 20% of the server.

(my implementation is currently written in roblox-ts)

const check = () => {
    if (!this.disabled) {
        Players.GetPlayers().forEach(player => {
            const rootPart = player.Character?.FindFirstChild("HumanoidRootPart");
            let index = -1;
            if (t.instanceIsA("BasePart")(rootPart) && regions.some((region, i) => {
                index = i;
                return region.CastPart(rootPart);
            })) {
                if (inRegion.get(player) !== regions[index]) {
                    inRegion.set(player, regions[index]);
                    enteredRegion.Fire(player, this.parts[index]);
                }
            } else if (inRegion.get(player)) {
                inRegion.delete(player);
                leftRegion.Fire(player, this.parts[index]);
            }
        });
    } else
        connection.Disconnect();
}

I’m just looking for suggestions as to how I could implement serversided region detection without crashing servers.

Have you tried looking into ZonePlus v2?

I use it to detect players in a zone and haven’t ran into any issues yet.

Thanks for the suggestion, will check it out. It does also appear to rely on RotatedRegion3’s though so I’m not sure if it will provide much of a performance uplift.

Do you really need to check 30 times a second for each player?
10 times a second or even less should be more than enough.

Additionally, you can only check for players that are near the edge of the zone. Using player:DistanceFromCharacter(safeZone.Position). This should greatly reduce the amount of players you need to check.

Is it really required to use a rectangular zone? You can look into .Touched and .TouchEnded, if you’re using a part as your safe zone.

Having a spherical zone would be the simplest since you can just do distance checks, which are most likely faster.

1 Like