Hey folks,
We’re adding a simpler and more flexible set of APIs to supersede FilterDescendantsInstances for raycasts, shapecasts, and other spatial queries:
RaycastParams.ExcludeInstances: {Instance}?
RaycastParams.IncludeInstances: {Instance}?
OverlapParams.ExcludeInstances: {Instance}?
OverlapParams.IncludeInstances: {Instance}?
New Filters
Previously, FilterDescendantsInstances forced you to choose either a whitelist or a blacklist. The new APIs allow for flexible filters that weren’t possible before without performing multiple raycasts:
Example: Whitelist with exceptions
params.ExcludeInstances = {Tree}
params.IncludeInstances = {Folder}
Folder (include me)
| House
| Tree (...but exclude me)
| Bench
Example: Blacklist with exceptions
params.ExcludeInstances = {Folder}
params.IncludeInstances = {Tree}
Folder (exclude me)
| House
| Tree (...but include me)
| Bench
Example: Include nothing
params.IncludeInstances = {}
Folder (exclude everything including me)
| House
| Tree
| Bench
Example: Include everything
params.IncludeInstances = nil
Folder (include everything including me)
| House
| Tree
| Bench
Note that IncludeInstances = nil and IncludeInstances = {} are opposites - The former is the most permissive possible filter (includes everything), whereas the latter is the most restrictive possible filter (include nothing).
(Note: If an instance happens to be in both lists, the exclusion takes priority as the tiebreaker).
Algorithmic Details
For those interested, the behavior of the new filters can be emulated like this:
function isIncludedByFilter(inst: Instance, exclude: {Instance}?, include: {Instance}?)
repeat
if exclude and table.find(exclude, inst) then
return false
end
if include and table.find(include, inst) then
return true
end
inst = inst.Parent
until inst == nil
return include ~= nil
end
Performance
The new APIs are much faster than FilterDescendantsInstances. This was enabled by a large internal rewrite[1] of how we handle filters for raycast and overlap queries:
- Fast log(n)-time lookups: We figured out a way to do log(n) lookups without making
RaycastParamsconstruction slower. The raycasts themselves are much faster when using these when you have a large filter list. - Reduced memory thrashing: We carefully tuned the reflection code so setting these properties repeatedly (e.g., dynamically adding parts to the list) has excellent performance.[2]
[1] Besides being faster, this allows us to iterate more quickly internally on new types of spatial queries and filtering APIs.
[2] We also shipped this specific optimization for FilterDescendantsInstances so that existing games run faster with no changes. However, we won’t be able to ship the first optimization for FilterDescendantsInstances, so there is a strong performance benefit for using the new APIs.
Migration
Of course, FilterDescendantsInstances and FilterType will always exist for backwards compatibility. However, we plan to deprecate them eventually in lockstep with community adoption of the new APIs. For you, this only means that continuing to use the old APIs will eventually produce a script analysis warning, and we will prioritize bug fixes and performance optimizations for the new APIs moving forward.
Known Issues
Due to a release delay, between 1% and 2% of Roblox clients on Windows and Android may not have this API yet as of 4/8. We will provide an update when it has 100% availability.
-The Physics Team

