How Do Roblox's New Spatial Query Filters Work? ExcludeInstances and IncludeInstances Explained
Roblox has introduced ExcludeInstances and IncludeInstances as simpler, more flexible alternatives to FilterDescendantsInstances for raycasts and shapecasts, making spatial queries easier to configure and maintain.
A recent announcement on the Roblox Developer Forum introduced new spatial query filter properties that fundamentally change how developers handle raycasting and shapecasting. These new APIs—ExcludeInstances and IncludeInstances—replace the more complex FilterDescendantsInstances system with a straightforward approach that's easier to understand and maintain.
According to the DevForum post with 251 likes and 45 replies, the new system addresses common frustrations developers faced with the previous filtering approach. Instead of managing descendant hierarchies and filter types separately, you can now directly specify which instances to exclude or include in your spatial queries.
What Are the New Spatial Query Filter Properties?
The new properties add two straightforward options to RaycastParams: ExcludeInstances and IncludeInstances. ExcludeInstances lets you specify an array of instances that should be ignored during the raycast, while IncludeInstances restricts the query to only consider specific instances.
These properties work with all spatial query types, including Workspace:Raycast(), Workspace:Blockcast(), Workspace:Spherecast(), and Region3. The key advantage is simplicity—you no longer need to construct complex folder hierarchies or manage FilterDescendantsInstances logic just to exclude a few objects.
How Does ExcludeInstances Replace FilterDescendantsInstances?
ExcludeInstances provides a direct replacement for the most common use case of FilterDescendantsInstances: ignoring specific objects during raycasts. Previously, you'd set FilterDescendantsInstances to a folder containing objects to exclude, then set FilterType to Enum.RaycastFilterType.Exclude.
Now you simply assign an array of instances directly to ExcludeInstances. For example, if you want a raycast to ignore the player's character, you'd write: raycastParams.ExcludeInstances = {character}. This eliminates the need for managing separate folder structures just for filtering purposes.
The new approach is particularly valuable in combat systems and shooting mechanics where you frequently need to exclude the local player's character from hit detection. As discussed in our guide on creating secure combat frameworks, clean spatial query filtering is essential for responsive gameplay.
When Should You Use IncludeInstances Instead of ExcludeInstances?
IncludeInstances works inversely to ExcludeInstances—it restricts the raycast to only consider specified instances. This is useful when you want to detect hits against a specific set of objects rather than everything in the world minus a few exceptions.
Use IncludeInstances when you're implementing targeted interaction systems, such as highlighting interactable objects or detecting hits against specific enemy types. For instance, a scanning ability that only detects enemies would set IncludeInstances to an array of enemy models.
The include approach is more performant when you're checking against a small number of specific instances rather than excluding a few from a large world. It also makes your code's intent clearer—you're explicitly stating what you're looking for rather than what you're avoiding.
Can You Use Both ExcludeInstances and IncludeInstances Together?
You cannot use ExcludeInstances and IncludeInstances simultaneously on the same RaycastParams object.
The two properties are mutually exclusive—setting one will override the other. This design decision makes sense because the filtering logic would become ambiguous: should the raycast include only the specified instances while also excluding others from that set?
If you need complex filtering logic that requires both inclusion and exclusion, you'll need to structure your game's instance hierarchy accordingly or perform multiple raycasts with different parameters. In most cases, choosing the right property (include or exclude) eliminates the need for complex multi-step filtering.
How Do the New Filters Impact Raycast Performance?
The new filtering system offers performance benefits over FilterDescendantsInstances in certain scenarios. When excluding a small number of instances, ExcludeInstances avoids the overhead of traversing folder hierarchies to build the filter set.
Similarly, IncludeInstances can significantly improve performance when you're only interested in a small subset of objects. Rather than raycasting against the entire workspace and filtering results afterward, the spatial query engine can narrow its search space immediately.
As with other performance optimization techniques covered in our O(1) Engine guide, the actual performance gain depends on your specific use case. Games with hundreds of concurrent raycasts will see more noticeable improvements than those with occasional spatial queries.
What Happens to Existing Code Using FilterDescendantsInstances?
FilterDescendantsInstances remains fully functional—Roblox has not deprecated it. Existing code will continue to work without modification, ensuring backward compatibility for all published games.
However, the DevForum announcement positions the new properties as the preferred approach going forward. Developers should consider migrating to ExcludeInstances and IncludeInstances when updating existing systems or building new features.
The migration process is straightforward for most use cases. If you're currently excluding instances via FilterDescendantsInstances, convert the folder's children to an array and assign it to ExcludeInstances. The behavioral equivalence makes this a low-risk refactor.
How Do Spatial Query Filters Affect Game Development Workflows?
The simplified filtering API reduces the cognitive overhead of implementing common gameplay mechanics. New developers learning Roblox scripting no longer need to understand the FilterDescendantsInstances hierarchy system before creating basic raycast functionality.
For experienced developers, the change streamlines code maintenance. Instead of managing folder structures that exist solely for filtering purposes, you can define filter lists directly in your scripts alongside the spatial query logic.
This improvement aligns with Roblox's broader push toward more intuitive APIs, as seen in recent updates like the Animation Graph System and Avatar Abilities Library. The platform continues to lower the technical barriers while maintaining powerful functionality for advanced use cases.
What Are Best Practices for Using the New Spatial Query Filters?
Follow these guidelines when implementing the new spatial query filters:
- Cache your instance arrays when possible—creating new tables every frame adds unnecessary overhead
- Use IncludeInstances when checking against a small, known set of objects for better performance
- Choose ExcludeInstances for most gameplay scenarios where you need to ignore the player's character or a few specific objects
- Keep filter arrays as small as practical—larger arrays take longer to process
- Document your filtering logic with comments explaining why specific instances are excluded or included
- Consider combining spatial query filters with CollisionGroups for complex interaction scenarios
How Do These Changes Benefit AI-Assisted Game Development?
The simpler API surface makes it easier for AI tools to generate correct raycast implementations. When you ask an AI assistant to create hit detection logic, it can now produce cleaner code using ExcludeInstances rather than explaining the FilterDescendantsInstances hierarchy system.
This matters increasingly as developers use AI-powered development tools to accelerate game creation. As explored in our AI vs traditional development comparison, modern Roblox development often involves AI collaboration, and simpler APIs make that collaboration more effective.
On creation.dev, we're already seeing game ideas that leverage these improved spatial queries for more responsive mechanics. Whether you're using traditional scripting or AI-assisted development, these new filters make implementing core gameplay systems more straightforward.
Frequently Asked Questions
Do I need to update my existing raycasts to use the new filtering system?
No, FilterDescendantsInstances continues to work normally. However, migrating to ExcludeInstances or IncludeInstances offers clearer code and potential performance benefits, especially for simple filtering scenarios.
Can I exclude parts that are children of excluded instances?
Yes, when you exclude an instance, all of its descendants are automatically excluded from the spatial query. This behavior matches how FilterDescendantsInstances worked, ensuring consistency during migration.
What's the maximum number of instances I can include or exclude?
Roblox hasn't specified a hard limit, but performance degrades with larger arrays. Keep your filter lists as small as practical—if you're excluding dozens of instances, consider restructuring your game's instance hierarchy or using CollisionGroups instead.
How do these new filters work with collision groups?
Spatial query filters and collision groups are complementary systems. Use RaycastParams.CollisionGroup to define which collision groups the raycast can hit, then use ExcludeInstances or IncludeInstances for fine-grained filtering within those groups.
Do the new filters affect Workspace:GetPartBoundsInBox() and similar region queries?
The DevForum announcement indicates these filters work with all spatial query APIs, including region-based queries. This provides consistent filtering behavior across raycasts, shapecasts, and volume queries.