- Roblox added on October 6, 2026. It hands your code the contact point, unit normal, relative velocity, and contact area for every collision your part had in a frame, data that the
Code: Select all
BasePart:BindToCollisionSummaries(callback)event does not carry.Code: Select all
Touched - It is a separate API from . Roblox explicitly says it is not meant to be called from inside a
Code: Select all
BasePart.Touchedevent.Code: Select all
Touched - The callback runs at most once per frame, after the physics step finishes. Processing cost scales with how many parts you subscribe, not with how many collisions happen in the scene.
- Summaries are generated where physics runs and nothing is replicated. If another client needs to know, you process the summary and fire your own remote event.
- The old workarounds still have their place. remains the cheap signal that something happened, and raycasts or velocity checks stay useful when you only need an approximation and want no subscription overhead.
Code: Select all
Touched
The October 6 announcement from the Roblox Physics Team frames the problem bluntly: until now you had two choices if you wanted to know how two parts collided.
Code: Select all
TouchedCode: Select all
BindToCollisionSummariesThe official
Code: Select all
BasePartCode: Select all
BasePart.TouchedThe Callback Signature and Summary Fields
The call takes one argument, a function, and returns an
Code: Select all
RBXScriptConnectionCode: Select all
BasePart:BindToCollisionSummaries(callback: (summaries: {CollisionSummary}) -> ()) -> RBXScriptConnection- Time (number): simulation time, in seconds, of the physics substep that produced this summary. Use it to order multiple summaries delivered in one callback.
- Part0 (BasePart): the subscribed part, the one you called the method on.
- Part1 (BasePart): the other part in the pair, which may be Terrain.
- Point (Vector3): contact point in world space, averaged across the points in the patch.
- Normal (Vector3): unit contact normal for the patch, oriented relative to the subscribed part.
- RelativeVelocity (Vector3): velocity of Part1 relative to Part0 at the contact point.
- Area (number): estimated contact patch area in square studs. It reads 0 for a patch of fewer than three points, such as an edge or corner contact.
The
Code: Select all
NormalCode: Select all
Part0Code: Select all
RelativeVelocityCode: Select all
NormalCode: Select all
NormalCode: Select all
AssemblyMassReading Impact Speed and Detecting Glancing Hits
The example Roblox shipped is impact-based visual effects. Dot the relative velocity against the normal, compare it to a threshold, and spawn sparks at the contact point:
Code: Select all
local function onCollision(summaries)
for _, s in summaries do
local impactSpeed = s.RelativeVelocity:Dot(s.Normal)
if impactSpeed > 10 then
spawnSparks(s.Point, s.Normal, impactSpeed)
end
end
end
local connection = car.Chassis:BindToCollisionSummaries(onCollision)
-- and when you are done with it:
connection:Disconnect()The Limits, Because They Change How You Design Around Them
The documentation lists the constraints in detail, and several of them are design decisions rather than footnotes.
- Contact recording is enabled only while at least one subscription exists anywhere in the , and the cost scales with the number of subscribed parts rather than the total number of collisions in the scene.
Code: Select all
Workspace - Contacts between two sleeping parts produce no summaries. A part that is asleep stops reporting until it wakes again.
- Parts with produce no summaries.
Code: Select all
CanCollide = false - Physics may run several substeps per frame, so a pair that stays in contact across several of them produces up to one summary per patch per substep, all delivered in the same callback invocation. Sort or sum by if the ordering matters to you.
Code: Select all
Time - Non-convex collision geometry produces one summary per pair of touching convex hulls, and terrain contact is split further by contact normal, so either can yield several summaries for the same pair within one substep.
- Nothing is replicated. Each client generates summaries for the collisions it owns.
- Destroying the part disconnects its subscriptions automatically.
- The method throws an error if the callback is nil, or if the part is not a descendant of .
Code: Select all
Workspace
This is the part the announcement leads into indirectly and that most scripts get wrong on the first try. Summaries are generated on the network owner where the physics simulation executes, client or server, and nothing is replicated across the network. If another client needs to know about a collision, you process the summary and fire your own remote event with just what you need.
Roblox distributes physics between the server and connected clients, and it assigns network ownership of simulated
Code: Select all
BasePartThat gives you two failure modes to design against.
If the colliding part is owned by a client, your summary fires on that client, not the server. A server-side damage script listening for summaries on a player-owned part will simply never see them.
The opposite problem is worse for security. Roblox states that clients can exploit client ownership by sending bad data to the server, for instance teleporting a
Code: Select all
BasePartCode: Select all
BasePart.TouchedCode: Select all
TouchedCode: Select all
BindToCollisionSummariesHow It Compares to the Older Approaches
The three options are not interchangeable, and picking the wrong one is how you end up with either a laggy feel or a silent bug. Side by side:
- Touched, what you get: the other part, and the start and end of contact. Nothing about where or how hard.
- Touched, what it costs: nothing to leave in place, but it is tied to network ownership, so a client can fire it for a part it owns.
- Velocity checks and raycasts, what you get: a position, a hit, or a number you derive yourself. No contact point, no normal, no true impact energy.
- Velocity checks and raycasts, what they cost: whatever you spend each frame in the loop, on any part regardless of ownership.
- BindToCollisionSummaries, what you get: the averaged contact point, the unit normal, the relative velocity at contact, and the estimated patch area, straight from the solver.
- BindToCollisionSummaries, what it costs: one subscription per part you care about, and Roblox states that cost scales with the subscribed parts rather than with the total collisions in the scene.
- Where each runs: Touched fires on the network owner of the part. Raycasts run wherever you call them. Collision summaries run on the network owner of the physics simulation, and nothing is replicated.
- Trust boundary: all three are untrusted on a client-owned part. Roblox says to check the validity of events fired by clients, and that warning covers collision summaries as much as it covers Touched.
- Pick Touched when: a trigger zone only needs to know something touched it.
- Pick raycasts or velocity checks when: you need a cheap approximation and the part may be owned by anyone.
- Pick BindToCollisionSummaries when: you need the contact point, the normal, or a real impact speed, and you can subscribe the part that matters.
A Practical Migration Checklist
- Decide which side of the network needs the data. If it is the server and the part is client-owned, you are processing summaries on the client and firing a remote event yourself.
- Call on the parts you care about and keep the returned
Code: Select all
BindToCollisionSummariesso you can disconnect it.Code: Select all
RBXScriptConnection - Handle multiple summaries per callback. Sort by if you need substep ordering.
Code: Select all
Time - Use for head-on impact speed, and the tangential component for glancing or sliding contact.
Code: Select all
RelativeVelocity:Dot(Normal) - Treat as an edge or corner contact, not as a missing value.
Code: Select all
Area = 0 - Do not rely on the callback for anything that must be trusted. Validate on the server.
- Disconnect subscriptions when a part is destroyed or no longer needed. Destroying the part already disconnects them, but explicit cleanup keeps the count of subscribed parts predictable.
Can I call BindToCollisionSummaries inside a Touched event?
No. Roblox states the API is not designed to be called from within a
Code: Select all
TouchedDoes it replace BasePart.Touched?
No.
Code: Select all
TouchedCode: Select all
TouchedWhy did I get no callback for a part that was resting on the ground?
Contacts between two sleeping parts are not recorded. A part that goes to sleep stops producing summaries until it wakes. Parts with
Code: Select all
CanCollide = falseCan a server script read summaries for a part a client is simulating?
No. Summaries are generated where the physics simulation executes and nothing is replicated. If another client needs to know, process the summary locally and fire your own remote event with just the data you need.
Will subscribing slow my game down?
Roblox says the overhead scales with the number of subscribed parts, not with the total number of collisions in the scene. Subscribing a few hundred parts is not the same as subscribing every part in the workspace, so pick deliberately.
What does Area = 0 mean?
A contact patch of fewer than three points, such as an edge or a corner contact. It is a real contact with an estimated area below what the engine reports, not a bug in your code.
Sources
- Roblox Developer Forum: Collision Summaries API, official announcement from the Roblox Physics Team (October 6, 2026)
- Roblox Creator Hub: BasePart:BindToCollisionSummaries reference, summary field table and reporting behavior
- Roblox Creator Hub: Network ownership, the physics distribution model and the security caveats around client-owned parts
- Roblox Developer Forum: Weekly Recap October 5 to 9, 2026, listing the API among the week's announcements
- Roblox Creator Hub: Week of October 5, 2026 release notes index