Zone+ v1 (deprecated) | Retrieving players within an area/zone

Can you explain on how to make this Zone+ for a gamepass only Zone. I have little understanding when it comes down to this kind of scripting. For instance, where do I put in ID of gamepass? How big can Zone be?

  1. Setup a dictionary which will be used to record who in a server has the gamepass.

  2. When a player joins the server, use UserOwnsGamePassAsync to verify they own the gamepass, and add them to the dictionary if they do.

  3. Setup PromptGamePassPurchaseFinished to check for when a gamepass is purchased. If the gamepass matches your desired gamepass, add them to the dictionary.

  4. Use the zone.playerAdded event to check for when a player enters your exclusive zone. If they are not within the dictionary previously defined, remove or block them from the zone (e.g. teleport away, kill, etc). You can find more about setting up zones here: https://1foreverhd.github.io/HDAdmin/projects/zoneplus/about/#example-server-sided

3 Likes

I have small experience when it comes to scripting. For step 1, how would I setup a dictionary? Also, when setting this up which script would it go into out of these 3? image

For instance would I have to add the Marketplaceservice script myself or is it already added?

echt geil, werde ich in zukunft mal gebrauchen können :slight_smile: !!!

I notice the code uses GetTouchingParts, would this not be making your code a little outside server use? I believe you create a Touched event to make GetTouchingParts to work so it could create a server side risk even if it only supports the rest of the module.

Or maybe I am mistaken or was seeing an outdated version.

Hey dude @ForeverHD!

Roblox added a new feature New RaycastParams Property, Deprecating Old Raycast Functions

You should definitely update the module~

1 Like

GetTouchingParts is used to form ‘clusters’ within a zone when its constructed, not to detect players/parts within that zone. While not necessary, clusters provide more precise sub-areas within a zone, which enables more efficient point generation using getRandomPoint(). Touched events aren’t used alongside GetTouchingParts for this. The cluster system may be removed entirely going forwards as I explore further ways to generate random points.

2 Likes

You can learn more about tables, dictionaries and arrays here, and can view coded examples of Zone+ here. For everything else, I recommend becoming more familiar with lua and the Roblox API and asking further questions within Help and Feedback.

1 Like

Nice, I’ve replaced the deprecated method with the new ones:

1 Like

Will this work for jumpscares?

This helped a lot, thank you!
(30 chars)

1 Like

I really love Zone +, but for some reason it isn’t working for me:

local RP = game:GetService("ReplicatedStorage")
local ZP = require(4664437268)
local ZS = require(ZP.ZoneService)
local zonePart = game.Workspace.ZonePart
local zone = ZS:createZone("Zone", zonePart)

--------------------------------------------------------

local playersInZone = zone:getPlayers()

zone.playerAdded:Connect(function(plr)
	
	print(plr.Name.." Joined!")
	
end)

zone.playerRemoving:Connect(function(plr)
	
	print(plr.Name.." Left!")
	
end)

zone:initLoop()

Nothing will print, and I won’t get any errors (ZonePart is a Part with CanCollide off)

I think the zonePart variable has to be a folder or model. Either one should work.

2 Likes

Thank you so much!!! I spent hours trying to find my mistake and just couldn’t, you’re a life saver!

1 Like

Hi, what are the best practices for setting up a zone / the limitations of this?

Currently I had just set up multiple zones, building on from the first one I had implemented as a test.
Here’s what they look like in studio (color-coded)

Having all these zones enabled with a basic playerAdded and initLoop shoots my server Script Activity usage up to 25-30%. (I’m assuming this from the MicroProfiler as well as disabling/enabling)

The same amount of zones works fine on the client without any significant frame drops.

Is the problem the number of parts the zones are over? Should I create flat zones under the map and use the height parameter? I’m wondering if I can find a solution to this, for now I’ve temporarily disabled them on the server. Any help is appreciated :slightly_smiling_face:

Good question, I’ve included a Best Practises section to cover all your points and some additional:

In short, for your situation, use Zone+ on the client, minimise the height (therefore volume) of your zones where possible, and specify a longer delay for the loop, such as :initClientLoop(3).

If a collection of zone parts have a height of 10, while another has a height of 9 and an additionalHeight of 1, then they both effectively have the same height (and volume). Reducing any zones total height though will improve its performance (this is negligible for small zones).

3 Likes

Hello, Great Zone+
If you keep the zone area 200x200x200 or less, on average how many zones can you have and not see performance issues?

10, 20, 50 , 100?

Thanks!

This depends on a few factors you’ll need to determine yourself:

  • Whether the zone is on the server or client (and calling initClientLoop)
    If the latter, a zones volume can be as large as you like with minimal-no impact on performance as it only performs raycast checks. Otherwise if server, then you will notice performance impacts the greater a zones volume due to additional Region3 checks.

  • How often checks are performed
    You could construct 1000 zones of size 1000x1000x1000 and be perfectly fine. It’s when you begin to call :getPlayer() and :getPlayers() frequently (which initLoop() does 600 times per minute per zone unless you specify a greater delay such as initLoop(3)) for lots of zones where things become extremely intensive. For instance, if you have 100 zones of size 200x200x200 and call initLoop() on all of these without specifying a delay, you’ll be performing 60,000 Region3 and Raycast checks over a volume of 800,000,000 studs cubed per minute. That’s going to hurt.

On the server, If you intend to setup lots of zones on the server with large volumes, or if your zones cover your entire map, you’ll honestly be better off setting up your own detection system which fires a raycast from every players HRP every interval.

Zone+ events on the server are primarily optimised and intended for servers with lots of players with zones that do not cover a large proportion of the map.

4 Likes

Just wanted to point out that the current code doesn’t seem to support wedges or parts at odd angles. Only partial workaround this is by unioning said parts.

1 Like

I’m having an issue where it only makes a zone for one part in the model I am making a zone out of. This is my code:

local serverStorage = game:GetService("ServerStorage")

local zonePlus = require(4664437268)
local zoneService = require(zonePlus.ZoneService)

local zoneParts = workspace:WaitForChild("ZoneParts")
local zone = zoneService:createZone("ArenaZone", zoneParts)

local items = serverStorage:WaitForChild("Items")

zone.playerAdded:Connect(function(player)
	if player.Character then
		items:FindFirstChild(serverStorage.PlayerData[player.Name].EquippedItem.Value):Clone().Parent = player.Backpack
	end
end)

zone.playerRemoving:Connect(function(player)
	if player.Character then
		player.Character:FindFirstChildOfClass("Humanoid"):UnequipTools()
		
		local item = player.Backpack:FindFirstChild(serverStorage.PlayerData[player.Name].EquippedItem.Value)

		if item then
			item:Destroy()
		end
	end
end)

zone:initLoop()
1 Like