Giter Club home page Giter Club logo

zoneplus's Introduction

zoneplus's People

Contributors

1foreverhd avatar howmanysmall avatar imezx avatar lucke0051 avatar medallyon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

zoneplus's Issues

ZoneController.getTouchingZones confusion in the document page

I had an issue with getting touching zones, that I made a comment in the discussion thread. (link) I eventually found how to fix it, (link) as the thing needed the humanoidrootpart instead of the player, while in the website it looks that it needs the player.
image
I would suggest changing this to say "HumanoidRootPart" instead of "Player" to avoid future confusion.

Add warnings/errors about zoneParts not using the default collision group

Fully account for Streaming

  1. Ensure :getRandomPoint() returns nil instead of recurring infinitely if zone parts are 0, e.g. if all streamed all:
function Zone:getRandomPoint()
	local region = self.exactRegion
	local size = region.Size
	local cframe = region.CFrame
	local random = Random.new()
	local randomCFrame
	local success, touchingZoneParts
	local pointIsWithinZone
	local totalPartsInZone = #self.overlapParams.zonePartsWhitelist.FilterDescendantsInstances
	if totalPartsInZone <= 0 then
		-- Its important we return if there are no parts within the zone otherwise the checks below will recur infinitely.
		-- This could occur for example if streaming is enabled and the zone's parts disappear on the client
		return nil
	end
	repeat
		randomCFrame = cframe * CFrame.new(random:NextNumber(-size.X/2,size.X/2), random:NextNumber(-size.Y/2,size.Y/2), random:NextNumber(-size.Z/2,size.Z/2))
		success, touchingZoneParts = self:findPoint(randomCFrame)
		if success then
			pointIsWithinZone = true
		end
	until pointIsWithinZone
	local randomVector = randomCFrame.Position
	return randomVector, touchingZoneParts
end
  1. line 87 of tracker so that it accounts for parts being streamed in:
local function playerAdded(player)
	local function charAdded(character)
		local function trackChar()
			local hrp = character:WaitForChild("HumanoidRootPart", 0.1)
			local humanoid = character:WaitForChild("Humanoid", 0.1)
			local head = character:WaitForChild("Head", 0.1)
			if hrp == nil or humanoid == nil or head == nil then
				return
			end
			updatePlayerCharacters()
			self:update()
			for _, valueInstance in pairs(humanoid:GetChildren()) do
				if valueInstance:IsA("NumberValue") then
					valueInstance.Changed:Connect(function()
						self:update()
					end)
				end
			end
		end
		local hrp = character:FindFirstChild("HumanoidRootPart")
		if hrp then
			task.delay(0.1, trackChar)
		else
			character.ChildAdded:Connect(function(child)
				if child.Name == "HumanoidRootPart" and child:IsA("BasePart") then
					task.delay(0.1, trackChar)
				end
			end)
		end
	end
	if player.Character then
		charAdded(player.Character)
	end
	player.CharacterAdded:Connect(function(char)
		charAdded(char)
	end)
	player.CharacterRemoving:Connect(function(removingCharacter)
		self.exitDetections[removingCharacter] = nil
	end)
end

[Bug] "attempt to index nil with 'item'"

Getting this error on stopping the game in Studio;

16:39:30.400  ReplicatedStorage.Modules.Zone.ZoneController.Tracker:135: attempt to index nil with 'item'  -  Server
16:39:30.400  Stack Begin  -  Studio
16:39:30.400  Script 'ReplicatedStorage.Modules.Zone.ZoneController.Tracker', Line 135  -  Studio
16:39:30.400  Script 'ReplicatedStorage.Modules.Zone.Signal', Line 37 - function acquireRunnerThreadAndCallEventHandler  -  Studio
16:39:30.400  Script 'ReplicatedStorage.Modules.Zone.Signal', Line 48 - function runEventHandlerInFreeThread  -  Studio
16:39:30.400  Stack End  -  Studio

I believe it is linked to the fact that Zone:untrackItem cleans up itemDetail and then calls Fire on Tracker.itemRemoved:

function Zone:untrackItem(instance)
	local itemDetail = self.trackedItems[instance]
	if itemDetail then
		itemDetail.janitor:destroy()
	end
	self.trackedItems[instance] = nil

	local Tracker = require(trackerModule)
	Tracker.itemRemoved:Fire(itemDetail)
end

This uses .item in the handler, which has been cleaned up:

Tracker.itemRemoved:Connect(function(itemDetail)
	self.exitDetections[itemDetail.item] = nil
	updateItem(itemDetail, nil)
end)

API reference mix up two functions names

The API documentation for Zone+ seems to mix up two functions name, which makes it confusing for new users who read the API documentation and get confused on why their code doesn't seem to be working when copied from the example code snippets.

Was this intentional or not?

Consider white/blacklists (call them deny and allow lists) for zone detection, especially part detection

Consider using the terms 'allowlist' and 'denylist' or 'permitonlylist' and 'ignorelist'

Methods

  • zone:setDenylist(array)
  • zone:addToDenylist(instance)
  • zone:removeFromDenylist(instance)
  • zone:setAllowlist(array)
  • zone:addToAllowlist(instance)
  • zone:removeFromAllowlist(instance)

Properties

  • zone.denylistDictionary
  • zone.allowlistDictionary
  • zone.denylistArray
  • zone.allowlistArray

To do:

  • When adding instances to a list...
    • If isA basePart, then add instance to dictionary
    • Iterate over descendants. If descendant is a basePart, also add that to dictionary
  • Repeat same when removing from list
  • If the allowlist is greater than 0, only permit instances (and their descendants) within that dictionary
  • Consider also providing denylistArray and allowlistArray properties as these may be needed for the zone whitelist/blacklist
  • Update documentation
  • Change version and write up release notes

Deferred SignalBehaviour support

For ZonePlus specifically, ensure you don't just copy over the new Signal module, adapt to work with the specifically modified zoneplus Signal.

Spelling mistake in documentation

Hey there, found a little spelling mistake in the API reference section.

image

I'm pretty sure it's supposed to be "Constructors", not "Construtors"

Explore memory issues

  • Consider sharing a checker part between all zones.
    • Explore whether a zone check can be performed in 2 locations at the same time
    • Then either do ZoneController or Zone getCheckerPart
  • Also, why does checkerpart still work outside of worksapce?
  • Move checkerPart to ReplicatedStorage/worldModel
  • Tracker
    • Fix leak
    • Consider only listening and updating changes instead of everything
    • Consider only constructing a tracker (such as player) only when needed
  • Consider a specific item entered and item exited signal / promise
    • Explore if Signals are CGd if no reference of them remains, otherwise use Promise
    • zone:onItemEnter(characterOrBasePart, callbackFunc)
    • zone:onItemExit(characterOrBasePart, callbackFunc)
    • Technicals
      • If first callback item in dictionary, Determine if item is already being tracked, note this down,
      • Record callback functions in dictionary with the item as the key (allow multiple callbacks)
      • Form a connection with the zone (zone.itemEntered/Exited) which listens for these changes. Only form 1 connection per zone.
      • When item exits/enters, check for callback stuff, then call these if present
      • If the item was originally untracked, call zone:untrackItem
    • Add example to docs and thread
  • Explore: https://devforum.roblox.com/t/zoneplus-v310-construct-dynamic-zones-and-effectively-determine-players-and-parts-within-their-boundaries/1017701/270?u=foreverhd

Consider adding selene and stylua for contributors

This would help standardize contributions and allow for better error checking

I am specifically asking for stylua/selene to be added to foreman.toml (which I can PR in), run stylua in init.lua and ZoneController

[Security] Workflow PublishAssets.yml is using vulnerable action actions/checkout

The workflow PublishAssets.yml is referencing action actions/checkout using references v1. However this reference is missing the commit a6747255bd19d7a757dbdda8c654a9f84db19839 which may contain fix to the some vulnerability.
The vulnerability fix that is missing by actions version could be related to:
(1) CVE fix
(2) upgrade of vulnerable dependency
(3) fix to secret leak and others.
Please consider to update the reference to the action.

Setup ZonePlus v2

Main

  • have a Zone module then a ZoneController as a child
  • once again have :update and. updated for calculating the zones min and max bounds and region, but completely scrap the 'cluster system'
  • in addition to a container (folder, model, etc), also accept baseparts
  • when a zone instance changes (size or position), call update on zone
  • for zone, support both players and parts
  • have methods like :getPlayers, :getLocalPlayer, :getParts, :checkPlayerInZone, :checkLocalPlayerInZone, :checkPartInZone
  • have events which automatically initiate a loop when connected to - .playerEntered, playerExited, partEntered, partExited, localPlayerEntered, localPlayerExited
  • for players, dynamically change between region3 + raycasting and solely raycasting depending upon factors such as total volume across all zones, number of players in server, localPlayer loop, etc
  • to optimise region3s, ensure it is on the voxel grid by setting its coordinates to multiples of 4s
  • when :update is called, perform a region3 check with math.huge as number of parts, then set recommended partstocheck to this value + 20
  • handle logic, decision making and even raycasting within the controller
  • for ZoneController, remove create/remove methods entirely and just have ZoneController.getZones()
  • parent utility modules like Signal and Maid under the Zone module
  • add :destroy and Destroy upper case alias
  • introduce enum.Accuracy with items such as 'Precise', 'High', 'Medium', 'Low' and a zone.accuracy property
  • verify the 'zone then raycast' check of player checks works (i.e. make char bigger)
  • important - there appears to be a memory leak - investigate and squash (may be to do with big chars/studio)
  • for localplayer and player related detection, now have the corresponding zones call .entered and .exited
  • complete zone:getPlayers()
  • here is the old part-detection in case the new property method doesnt work as intended: https://prnt.sc/wkuftd
  • for part-detection:
    • when listening for .partEntered/exited add a touched connection to all zone parts (when update is called make sure to update this connection). also design so it could be implemented for the player methods maybe in future
    • when a zone part touched, set touching parts 'CanTouch' property to false and begin tracking
    • for all tracking parts every heartbeat connection (based upon .accuracy):
      • fire a raycast from top to bottom of part with whitelist of all zones group parts
      • if raycast fails then perform a rotated region 3 check
      • if this fails then remove from tracking list and set 'CanTouch' to true again
      • run tests such as adding parts to zone, changing size etc
  • utilise enum.Accuracy to determine how many checks (and the type of checks) per second
  • complete zone:getParts()
  • introduce :getRandomPoint again but this time do purely a while loop with completely random casting
  • have an additional child module called 'TopbarPlus' which gets parented to ReplicatedStorage and when required will return the Icon module. if an item called 'TopbarPlus' already exists in ReplicatedStorage then dont add and produce a warning informing application may not work fully
  • test all public methods
  • test all events/connections under varying conditions (few/lots of players, client/server, small/big zone volumes, rotated items, union items, meshparts, cylinder/spheres, adding/removing parts to zone, changing size/position etc)
  • test destroy
  • setup playground
  • complete 'PaintZone' within Playground- at the moment it appears parts (like body parts) pop in and out
  • meshparts and unionoperations are inaccurately detected via the region checks - consider performing an additional raycast check for these classes (for players, parts and getrandompoint)

[Bug] Players with an applied HumanoidDescription do not fire player events

Hey! I recently spent a while debugging why my code wouldn't react to the playerEntered and playerExited events, and after a bit of digging, I found out that when I applied a HumanoidDescription to the player, the player was not recognized by any zones on the server (possibly the client too).

A repro game is linked below:
https://www.roblox.com/games/8699903286/ZonePlus-Repro
Comment out line 15 in CharacterSetup in ServerScriptService to make the zone work again.

This bug is reproducible on the latest version of ZonePlus, v3.2.0.

zone:relocate(customLocation)

Currently defaults to ReplicatedStorage (if client) or ServerStorage (if server). Consider providing a parameter which if specified relocates the container under a specific instance.

attempt to index nil with Instance

Hi, I am getting an error when using zone:trackItem I have not tampered with the Zone Module
Error

ReplicatedStorage.Zone:738: attempt to index nil with Instance  -  Server - Zone:738
  14:52:46.712  Stack Begin  -  Studio
  14:52:46.712  Script 'ReplicatedStorage.Zone', Line 738 - function trackItem  -  Studio - Zone:738
  14:52:46.713  Script 'ServerScriptService.Zone', Line 8  -  Studio - Zone:8
  14:52:46.713  Stack End  -  Studio

Sever Script

local zone = require(game.ReplicatedStorage.Zone)
local zonec = require(game.ReplicatedStorage.Zone.ZoneController)
local TeleportsSmile  = {game.Workspace.Map.Zones.TelportSmile.TeleportSmile}
local TeleportsSmileZone = zone.new(TeleportsSmile)
workspace:WaitForChild("Smile")
zone:trackItem(workspace:WaitForChild("Smile").PrimaryPart)
TeleportsSmileZone.itemEntered:Connect(function(item)
	if item.Name == "Smile" or item.Parent.Name == "Smile" then	
	else	
	end
end)

Zone Module Error Lines

function Zone:trackItem(instance)
	local isBasePart = instance:IsA("BasePart")
	local isCharacter = false
	if not isBasePart then
		isCharacter = instance:FindFirstChildOfClass("Humanoid") and instance:FindFirstChild("HumanoidRootPart")
	end

	assert(isBasePart or isCharacter, "Only BaseParts or Characters/NPCs can be tracked!")
	print(instance)
	if self.trackedItems[instance] then
		return
	end
	if self.itemsToUntrack[instance] then
		self.itemsToUntrack[instance] = nil
	end

	local itemJanitor = self.janitor:add(Janitor.new(), "destroy")
	local itemDetail = {
		janitor = itemJanitor,
		item = instance,
		isBasePart = isBasePart,
		isCharacter = isCharacter,
	}
	self.trackedItems[instance] = itemDetail

	itemJanitor:add(instance.AncestryChanged:Connect(function()
		if not instance:IsDescendantOf(game) then
			self:untrackItem(instance)
		end
	end), "Disconnect")

	local Tracker = require(trackerModule)
	Tracker.itemAdded:Fire(itemDetail)
end

๐Ÿ› ZonePlus running in infinite error loop due to this

This error led to the module being in a neutral state whereas it no longer fires the itemEntered event and other events.
image

I'd like to address this major issue because one time when I was restoring the map in Adonis, I saw that the folder ZonePlusServerContainer was destroyed in the Workspace. The module constantly kept trying to reparent the folder; as a result, it made countless errors, filling up the console with errors and less debug prints.

Support parts outside of workspace

  • World Model
    • ZoneController.worldModel - a worldmodel instance called 'ZonePlusWorldModel' which is parented under ReplicatedStorage when created
    • ZoneController.collectiveWorldModel - a table/metetable which takes all the zone world models, calls the passed function, then returns all the values as a single table
      • update all workspace:methodName with collectiveWorldModel:methodName
  • zone:relocate()
    • rename zoneGroup and zone.group to container
    • creates a secondary property called relocationContainer which is the container is the container is an Instance, otherwise creates a Folder and parents all zone.zoneParts under this, then sets this new folder as the relocationContainer
    • add the relocationContainer (with the third param) to the janitor
    • move relocationContainer under the ZoneController.worldModel
    • See following for more details:
      https://devforum.roblox.com/t/introducing-overlapparams-new-spatial-query-api/1435720/102?u=foreverhd
  • Create a new constructor ``Zone.fromRegion(cframe, size)
    • Check for max size of part, if exceeds limit (about 2040, 2040, 2040) then split into smaller cuboids
    • Call :relocate()

Setup a dedicated tags system (e.g. to easily indicate 'read only')

  • have properties do local propertyType = zone.propertyName --[default: 'false']
  • setup tags like below

Implement features 'tags' similar to evaera's Promise API (https://eryn.io/roblox-lua-promise/lib/) (https://raw.githubusercontent.com/evaera/roblox-lua-promise/061c3a8659d97360df0a001a7143506cf907e21d/lib/README.md), when writing documentation with mkdocs and material (https://squidfunk.github.io/mkdocs-material/),

This may be achievable with material 'metadata'? https://squidfunk.github.io/mkdocs-material/extensions/metadata/?

image

Some players are not detected

Using the latest version of ZonePlus, I noticed that when some of my friends join the game, Some newer accounts don't fire the playerEntered (in their localscript) event, I havent figured out why 100% yet because I have trouble reproducing the issue, But it could be related to a longer UserId?
Here's how I Managed to reproduce this issue a few times:

  • Join A server with ZonePlus in a localscript that will print something whenever a player enters
  • Have your friend join the same server as me, My friends userId is: 4151523582

If I walk into the zone, The value prints for both me and my friend
If my friend walks into the zone, The value will sometimes print for me but not print for my friend
If I then leave the game and my friend tries again after I left the game, The value will print for him

I hope this is enough information, I havent completely figured out how to reproduce this as of now

Wally support

Packages Managers are great alternative to git sub modules and copying/pasting source code.

Detection options

  • setup an enum 'Detection' with members 'Automatic', 'WholeBody' and 'Centre'
  • for enums, have it so you can do enum = Zone.enum.EnumName.EnumMember
  • convert others enums to do this
  • property zone.enterDetection = Zone.enum.Detection.Automatic
  • property zone.exitDetection = Zone.enum.Detection.Automatic
  • property zone._currentEnterDetection = zone.enterDetection
  • property zone._currentExitDetection = zone.enterDetection
  • method zone:setDetection(detectionName, enterOrExitOrBoth)
  • Consider moving all of above to ZoneController
  • reconfigure the following so they differ depending upon _currentEnter/ExitDetection
    • players (localplayer and player), events and methods
    • parts (touch triggers), events and methods
  • run some tests to see the maximum volume size rotatedregion3 can comfortably work with. set a constant property
  • dynamically change ._current to centre (if above) or wholebody (if below) BUT consider how this works for part volumes???
  • dynamically adapy for
    • players
    • parts
  • update docs
    • zone API enter and exit detection properties
    • methodology and explain the automatic system
  • let Lobestone and R_alatch know of update

Fix race condition within Tracker

A race condition between AncestryChanged and a new replacement Head being swapped in on the same frame.

To fix, change line 208 from self:update() to task.defer(self.update, self).

Zone:_partTouchedZone(part) is not used

I was looking through the code for partExited and partEntered and I found that Zone:_partTouchedZone(part) was not used. Is the feature still a work in progress?

Remove Third Parties example as no longer necessary

  • Test and ensure Zone module handles all of this internally
  • Test with 2 different packages, require both separately, then alternate the delays between requires
  • Test for both server and client, and server and client combined
  • Remove 'Third Parties' example

Complete documentation and automation

  • about
  • explain second reason why region checking is primarily used over raycasting (raycasts canmot be fired within)
  • consider a similar volume comparrison for touched parts. If tracking parts total volume is greater than the zones, only check the zone, else use current method
  • when a part enters, consider performimg a region check right away, and only when that succeeds call .entererd
  • if this check fails twice within a second, block requests for that part for 1 second
  • explain how that prevents touched sploofing
  • update docs to explain all above
  • method
    • region3 vector grid 4x4
    • 3 sections
      • localplayer
      • player
      • parts
    • additional raycast checks for special baseparts
    • consideration of also adopting touched for players going forward
  • installation
    • docs/instructions
    • setup nanoblox model
    • have main branch auto publish to this model
  • modules
    • setup automated module -> docs when committed to master (see brandons messages)
    • zone
    • zonecontroller
  • contributing
    • setup github contributing file
    • have this auto publish to docs file
  • changelog/releases
  • fix discord webhooks (issues being classes as pull requests, etc)
  • fix image and video scaling on mobile

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.