How expensive are the spatial-querying methods?

How expensive is it to constantly run a sparial query method every frame, such as :GetPartBoundsInBox() with all the character’s limbs included? Is there a major difference between just using a .Touched event, or are there other methods that are superior than what I originally mentioned?

1 Like

It searches through all descendants in the workspace so it very very expensive like oil

2 Likes

you can mitigate this somewhat by making it only check for a certain collision group, so in a huge map for example you’d most likely want to create a collision group specific for the players if you want to make hitboxes with it

If the space is large enough, you could just use Octrees or Quadtrees in order to Spatially Query for items, there’s a nice Octree API already on the platform. If you’re interested or have any questions let me know!

Thank you.

3 Likes

Where did you get that information? I just tested this, and from my testing it appears to be false, the script’s resource usage was dependant not on how many parts there are in the workspace, but how many parts there are in the radius with 2000 parts tested.

EDIT: Tested it with 72000 parts now, still 0% activity for the script using this command when the parts are out of radius, when they reach the radius, the game freezes.

1 Like

i just made that information up for no reason

Table Slam GIFs | Tenor

5 Likes

Any spatial query will always be relatively expensive. Overlap detection is a hard problem. That said, these are usually optimized quite a bit. Generally speaking programs tend to put objects that can be queried into an acceleration structure that lets it only consider objects near enough to what you are checking to have possibly collided. These are bvh, octree and the like. They basically divide the world into cells that hold objects and when you check if something is colliding it only checks the cells the object is in. This removes the vast majority of the work. The next step is usually to do a quick bounding box check as that’s very fast just comparing each axis together to see if they even could overlap. If a box around the 2 models aren’t overlapping then it can’t be touching. That gets rid of the more expensive direct model comparison when they can’t collide. If it passes that broad phase test (box or sphere are the most common), then it may be colliding or it may not, so it runs the most expensive collision function. Overall these can be surprisingly fast, but consider them slow operations to be safe.

The .touched event just basically notes if the physics engine had them collode and tells your script about it if it was registered. It’s generally cheaper because it just uses work the physics engine already did and will only run your code when it should. The only problem with .Touched is I find it can be a bit finicky around the edges so works best for invisible trigger parts larger than the zone. And don’t use it for a toggle. This may be fixed but in the past the touched and touchended events have not always fired one for one.

As for if you can write something faster? Only if you are checking like 1-3 things per frame and just doing a magnitude check. Otherwise robloxs built in higher performance spatial query will almost always beat out any system you can write. Still don’t go overboard with them but a few per frame should be feasible. And use the include filter type in overlap params if you can. That tends to be the cheapest, but anything you can remove from calculating in the overlap params can be helpful so long as you aren’t building a giant list before every check (build overlap params once if you can, looping through a lot of objects to conditionally build one may be slower than just letting the broad phase handle it.)

2 Likes

.Touched indeed works in a weird way, which is explained here. Especially with parts that have different network ownership, the two different networks owners can fire .Touched for both parts, causing .Touched to fire twice per part, even though there was only 1 collision

There was also a bug fix in the release notes about ensuring that .TouchEnded now fires after .Touched

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.