SimpleZone | A simple, fast and new Zone module!

Hello, as i also mentioned for fearfant I wouldn’t use the parallel constructor for now as it hasn’t been updated in a while and I don’t have access to update it since my laptop is dead, for now I’d recommend simply using the .fromPart() constructor for hitboxes

Okay, thank you for your quick response. I hope you’re able to get a new computer soon, because this resource is amazing even as it is so far.

1 Like

I’ve figured out the problem with params (partially). PART_QUERY_JUMP isn’t passing the params through it in some places. I’ve only managed to get it working for ItemEntered/Exited but until the module can be updated in places where PART_QUERY_JUMP is called just add the params into it.

example:

current

local function zone_fromPart(part: BasePart, queryOp: QueryOptions?): Zone
	return zone_new(queryOp, function(_, params: OverlapParams)
		if part:IsA("Part") then
			return = PART_QUERY_JUMP(part.Shape.Name, part)
		end
		
		return workspace:GetPartsInPart(part, params)
	end)
end

working

local function zone_fromPart(part: BasePart, queryOp: QueryOptions?): Zone
	return zone_new(queryOp, function(_, params: OverlapParams)
		if part:IsA("Part") then
			return = PART_QUERY_JUMP(part.Shape.Name, part, params)
		end
		
		return workspace:GetPartsInPart(part, params)
	end)
end
2 Likes

I will pin this to the main post for those who need it :heart: My laptop probably wont be fixed for a few weeks so its gonna take a while :frowning: It infuriates me!!!

1 Like

Hey athar i would want to thank you for all useful resources you make I wish you get your laptop soon
where can i donate to you?

2 Likes

If you want to donate 10 robux it’s in the main post, however it’s unlikely that it’s gonna make my laptop being fixed come any sooner :sweat_smile: , honestly a likely outcome is that it wont get fixed until my birthday, which is in May… so yeah :frowning:

Id want to donate 3k robux :money_mouth_face:

I unfortunately do not know how to set that up :sob:

When i use .frompartparallel it causes more lag, I have around 12-15 zones

Yeaaa thats probably the parallel overhead of it, I’ll add part metadata for .fromParts() like .fromBoxes() so you can create one big zone just with seperate metadata for each part. Probably will be removing/deprecating .fromPartParallel() once I can because it isn’t really better than any of the other part constructors imo

ya, this is one of the two things holding this library back for me. Has some great API, looks really well made, but it’s limited to the roblox eco system. If you got a wally port up, I’d probably use it, it’s got some type solver issues, but nothing a !nocheck can’t fix

1 Like

image
am i using the module correctly? because when I open the script tab in developer console my script uses 95% activity so I’m just worried about lag

Here i would use zone.fromParts() instead of creating a new zone for every part, especially since youre just doing the same thing for each one (making player leave duty when they exit)

So like this:

zone.fromParts(workspace.DutyZones:GetChildren())

Also, i would pass an OverlapParams to BindToHeartbeat that only includes player characters.

I would also enable ThrottlingEnabled in the QueryOptions and set UpdateInterval to 1/30 or higher like 1/10 (this isnt really a type of zone that requires super precise detection so this will reduce lag)

3 Likes

I should probably add a “Best Practices” section to the main post so people know about these optimizations they can do, I can imagine alot of people are confused why this module is laggier than, say, ZonePlus, when in reality its because they don’t know about the things they have to specify/do :sob:

Added!

1 Like

Heyo
I found your module because I was struggling with a bug with ZonePlus. But I just realised your module seems to have the same bug…
Most likely its something on my side though :sweat:

Any idea why this is happening?
This is the module I’m calling your Zone from

function MusicRegions.init()
	local MusicRegionsFolder = ReplicatedStorage:WaitForChild("MusicRegions")

	-- I only added this because ChatGPT assumed maybe the issue was coming from the character not loading, but it didnt fix anything
	if not LocalPlayer.Character then LocalPlayer.CharacterAdded:Wait() end

	for _, zonePart in MusicRegionsFolder:GetDescendants() do
		if not zonePart:IsA("BasePart") then continue end

		local songName = zonePart.Parent.Name
		local intensity = zonePart.Name
		local regionCFrame = zonePart.CFrame
		local regionSize = zonePart.Size

		local zone = Zone.fromBox(regionCFrame, regionSize)
		zone:BindToHeartbeat()
		zone:ListenTo("Player", "Entered", function(player: Player)
			print("entered!")
			if player ~= LocalPlayer then return end
			changeSong(songName, intensity)
		end)
		print("setup zone: ", zone)
	end
end

This modulescript is located inside of StarterPlayerScripts.
I call this MusicRegions.init function from my LocalScript located In StarterPlayer/StarterPlayerScripts/Initializer (it just calls all my modules in the right order)
My ReplicatedStorage.MusicRegionsFolder has 2 models, each with 4 parts

Heres the weird thing
The setup zone: always prints (all 8 times)
But the entered! log doesn’t always print…
Randomly, sometimes it just doesn’t work

One thing I noticed is that whenever StreamingEnabled is disabled, it always works perfectly
But why?!?
I’m so confused :sweat:

1 Like

Also, I do want to point out that I do wish I could use fromBoxes or fromParts, but I need to also know what part/section was touched, and the only way I’ve noticed I’m able to do that is this way…

This is because with StreamingEnabled you have to wait for the parts to be streamed/loaded into the client, to get around this i would store all your music zones under a Model and set ModelStreamingMode to Persistent

Also, when listening to a zone created from SimpleZone.fromBoxes(), the 2nd argument is actually the box where the item is located. For example:

local zone = SimpleZone.fromBoxes(boxes)

zone:BindToHeartbeat(
zone:ListenTo("LocalPlayer", "Entered", function(plr, box)
	print("Local player in box "..box.cframe)
end)
1 Like

Hmm, strangely enough, even when there are no folders, and its all just models, it still doesn’t work

So, at the moment my setup is
Replicated Storage (I also tried with it being in workspace, but that changes nothing) > MusicRegions (model) > 2 different models grouping each zone > parts of the zone
All models had the property ModelStreamingMode set to Persistent

I’m not too surprised that that didn’t fix it because in any case, it would always log out the setup zone: all 8 times with zone props containing the right CFrames

Also, I haven’t transitioned to the fromBoxes constructor yet cuz:

  1. Although you send the CFrame, you don’t send what part name it is (I know that I could fix that by using a dictionary, but there’s also another reason why I wont end up using it)
  2. I now realise that if I were to do that, you’d treat the fromBoxes as one big zone, and I don’t want that
    I want each individual zone to trigger a “Entered” event

P.S.
I just realised I was Listening to Player instead of LocalPlayer
But even when I made the change, it still kept having issues

1 Like

I decided to test it out some more. I only have 1 part, I add the zone and listen to it

I added some more prints and I realised that if I have too many parts inside of the zone, it prints a lot of those parts, and it never even receives a player instance

This is especially confusing because when the player moves around, I see his parts being logged (like his feet or whatever)… But the actual player Instance never gets triggered

That all being said… if the player respawns… the zone goes back to working…

	return self[`Item{mode}`]:Connect(function(item: Instance?, metadata)
		if datatype == "LocalPlayer" and item ~= Players.LocalPlayer then
			print("bad1", item) -- added this
			return
		end
		print(item) -- and added this
		if datatype ~= "LocalPlayer" and not item:IsA(datatype) then
			return
		end

		fn(item, metadata)
	end)

Hmm, I wonder if it is a problem with how PlayerLookup.onPlayerAdded handles characters… I don’t know though, the last time i checked it worked, if you can send the PlayerLookup code here ill inspect it because my laptop is broken right now, sorry for the inconvenience :grimacing:

Though, I would check if your package version is the latest (47), I completely reworked the PlayerLookup so maybe thatd fix your issue?

1 Like