Collision Filter Module

This module provides a CollisionFilter class for managing collision filtering parameters along with a CollisionCategoryRegistry class that handles the creation and lookup of named collision categories.

Features:
  • Named category creation via a registry.

  • Methods that accept multiple categories at once.

  • Operator overloading (|) for combining CollisionFilter instances.

  • Introspection support (list_categories) for debugging.

  • Optional auto-creation of categories when unknown strings are encountered.

Example usage:
>>> # With auto_create enabled, new categories are defined automatically:
>>> filter_a = CollisionFilter(category="player", mask="enemy", group=0)
>>> filter_a
CollisionFilter(category=0x1, mask=0x2, group=0)
class box2d.collision_filter.CollisionCategoryRegistry(auto_create: bool = False)[source]

A registry to manage named collision categories.

Each category is automatically assigned a unique bit. The valid bits run from 0x0001 to 0x8000, which gives up to 16 unique categories.

By default, auto_create is disabled (False) so that category names must be explicitly defined. This prevents typos from inadvertently creating new categories. However, the default registry below is created with auto_create=True for easier prototyping.

define(name: str) int[source]

Define a new collision category with a unique bit, or return the existing bit if already defined.

Parameters:

name – The name of the collision category.

Returns:

The bitmask value assigned to this category.

Raises:

ValueError if the maximum number of categories (16) is exceeded.

Example

>>> reg = CollisionCategoryRegistry()
>>> reg.define("player")
1
>>> reg.define("player")
1
get(name: str) int[source]

Get the bitmask for a named category.

Parameters:

name – The name of the collision category.

Returns:

The bitmask associated with the category.

Raises:

ValueError if the category has not been defined.

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> reg.define("player")
1
>>> reg.get("player")
1
list_categories() dict[source]

Return a copy of the defined categories.

Returns:

A dictionary mapping category names to their bitmask values.

Return type:

dict

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> reg.define("player")
1
>>> reg.list_categories()
{'player': 1}
parse(cat) int[source]

Convert a category provided as a string (name) or integer into an integer bitmask. When auto_create is enabled, automatically define new categories that haven’t been defined.

Parameters:

cat – A collision category as a name or a bitmask.

Returns:

The corresponding bitmask.

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> reg.parse("enemy")
1
>>> reg.parse("player")
2
>>> reg.parse(4)
4
class box2d.collision_filter.CollisionFilter(category: int | str | list[int | str] | tuple[int | str] = 1, mask: int | str | list[int | str] | tuple[int | str] = 65535, group: int = 0, registry: CollisionCategoryRegistry = None)[source]

A helper class for managing Box2D collision filtering parameters.

category

Bitmask representing the collision categories that this shape belongs to. It is used in combination with the mask to determine which collisions occur.

Type:

int

mask

Bitmask representing which collision categories this shape is allowed to interact with. When the bitwise AND of one shape’s category and another shape’s mask is nonzero, a collision is possible (subject to group filtering).

Type:

int

group

Collision group index for this shape. The group overrides normal category/mask filtering:

  • A value of 0 (the default) means no grouping; collision is determined solely by category and mask.

  • If both shapes share a nonzero group:
    • A positive value forces them to always collide.

    • A negative value forces them to never collide.

  • If the group values differ (or only one is nonzero), the standard category/mask rules are applied.

Type:

int

The API is chainable and accepts categories (and masks) as either integers or names (resolved via a registry). The group is strictly an integer.

Examples (Fluent Interface):
>>> f1 = CollisionFilter("player").allow_collision_with("enemy")
>>> f2 = CollisionFilter("enemy").allow_collision_with("player")
>>> f3 = CollisionFilter("ally").allow_collision_with("enemy")
>>> f1 & f2 # checks if two collision filters would collide
True
>>> f1 & f3
True
>>> f1 = f1.block_collision_with("ally")
>>> f1 & f3
False
__init__(category: int | str | list[int | str] | tuple[int | str] = 1, mask: int | str | list[int | str] | tuple[int | str] = 65535, group: int = 0, registry: CollisionCategoryRegistry = None)[source]

Initialize a new CollisionFilter.

Parameters:
  • category (int or str or list) – The collision category bitmask, name, or list of names/bitmasks. If string(s) are provided, they are resolved via the registry. If a list is provided, all categories are combined with bitwise OR.

  • mask (int or str or list) – The collision mask bitmask, name, or list of names/bitmasks. Similarly, string(s) are resolved via the registry. If a list is provided, all masks are combined with bitwise OR.

  • group (int) –

    The collision group index. * 0 indicates no grouping; standard category/mask rules apply. * A nonzero value overrides the usual filtering, as follows:

    • If both shapes have the same nonzero positive group, they always collide.

    • If both shapes have the same nonzero negative group, they never collide.

  • registry (CollisionCategoryRegistry, optional) – The registry used for resolving category names. Defaults to the module-level default.

Returns:

A new instance with the specified filtering parameters.

Return type:

CollisionFilter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> filter_a = CollisionFilter(category=0x1, mask=CollisionFilter.ALL, group=0, registry=reg)
>>> filter_a
CollisionFilter(category=0x1, mask=0xFFFF, group=0)
>>> filter_b = CollisionFilter(category=["player", "ally"], mask=["enemy", "projectile"], registry=reg)
>>> filter_b
CollisionFilter(category=0x3, mask=0xC, group=0)
add_category(*cats) CollisionFilter[source]

Add one or more collision categories to this filter.

Parameters:

*cats – One or more collision categories (int or str) to be added.

Returns:

Self, to allow chaining.

Return type:

CollisionFilter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> filter_a = CollisionFilter(category="player", registry=reg)
>>> filter_a.add_category("ally", "powerup")
CollisionFilter(category=0x7, mask=0xFFFF, group=0)
allow_collision_with(*cats) CollisionFilter[source]

Allow collisions with one or more categories by including them in the mask.

Parameters:

*cats – Collision categories (int or str) to allow.

Returns:

Self, to allow chaining.

Return type:

CollisionFilter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> # Start with a filter whose mask is initially 0.
>>> filter_a = CollisionFilter(category="player", mask=0, registry=reg)
>>> filter_a.allow_collision_with("enemy")
CollisionFilter(category=0x1, mask=0x2, group=0)
property b2Filter

Convert this CollisionFilter into a Box2D b2Filter C structure.

Returns:

A newly created b2Filter structure with the appropriate category, mask, and group values.

Return type:

b2Filter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> c_filter = CollisionFilter(category="player", mask="enemy", group=0, registry=reg).b2Filter
>>> c_filter.categoryBits == 1
True
>>> c_filter.maskBits == 2
True
>>> c_filter.groupIndex == 0
True
property b2QueryFilter

Convert this CollisionFilter into a Box2D b2QueryFilter C structure. The group is not included in the query filter.

Returns:

A newly created b2QueryFilter structure with the appropriate category and mask values.

Return type:

b2QueryFilter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> c_filter = CollisionFilter(category="player", mask="enemy", group=0, registry=reg).b2QueryFilter
>>> c_filter.categoryBits == 1
True
>>> c_filter.maskBits == 2
True
block_collision_with(*cats) CollisionFilter[source]

Block collisions with the specified categories.

This method updates the filter so that it does not allow collisions with the given categories. Unlike allow_collision_with(), which adds categories to the list of permitted collisions, this method marks the provided categories as blocked. In other words, it prevents interactions with those categories regardless of previous settings.

Parameters:

*cats – One or more collision categories (int or str) to block.

Returns:

Self, to allow chaining.

Return type:

CollisionFilter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> filter_a = CollisionFilter(category="player", mask=0xFFFF, registry=reg)
>>> filter_a.block_collision_with("enemy")
CollisionFilter(category=0x1, mask=0xFFFD, group=0)
remove_category(*cats) CollisionFilter[source]

Remove one or more collision categories from this filter.

Parameters:

*cats – Collision categories (int or str) to remove.

Returns:

Self, to allow chaining.

Return type:

CollisionFilter

Warning

A warning is emitted if a category that is not set is attempted to be removed.

Example

>>> import warnings
>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> filter_a = CollisionFilter(category="player", registry=reg)
>>> filter_a.remove_category("player")
CollisionFilter(category=0x0, mask=0xFFFF, group=0)
set_group(group: int) CollisionFilter[source]

Set the collision group index for this filter.

Parameters:

group (int) –

The collision group index. * 0: No overriding group filtering—the standard category/mask rules apply. * Nonzero: Overrides the default filtering when both shapes share the same group.

  • Positive values force an always collide scenario.

  • Negative values force a never collide scenario.

Returns:

Self, to allow chaining.

Return type:

CollisionFilter

Example

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> filter_a = CollisionFilter(category="player", registry=reg)
>>> filter_a.set_group(5)
CollisionFilter(category=0x1, mask=0xFFFF, group=5)
box2d.collision_filter.filters_collide(filter_a: CollisionFilter, filter_b: CollisionFilter) bool[source]

Determine if two collision filters would allow a collision.

Collision is determined as follows:
  1. Group filtering: If both filters share the same nonzero group:

    • A positive group forces collision.

    • A negative group prevents collision.

  2. Otherwise, collision occurs if: (filter_a.category & filter_b.mask) != 0 and (filter_b.category & filter_a.mask) != 0

Parameters:
Returns:

True if the filters would allow a collision, False otherwise.

Return type:

bool

Examples

>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> f1 = CollisionFilter(category="player", mask="enemy", group=0, registry=reg)
>>> f2 = CollisionFilter(category="enemy", mask="player", group=0, registry=reg)
>>> filters_collide(f1, f2)
True
>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> f3 = CollisionFilter(category="player", mask="enemy", group=3, registry=reg)
>>> f4 = CollisionFilter(category="enemy", mask="player", group=3, registry=reg)
>>> filters_collide(f3, f4)
True
>>> reg = CollisionCategoryRegistry(auto_create=True)
>>> f5 = CollisionFilter(category="player", mask="enemy", group=-2, registry=reg)
>>> f6 = CollisionFilter(category="enemy", mask="player", group=-2, registry=reg)
>>> filters_collide(f5, f6)
False