roblox-physics
Skill92 starsChanged 47 days agoMITView on GitHub
Physics and spatial queries - Raycast/Blockcast/Spherecast, overlap queries, collision groups, Touched pitfalls, collision summaries (impact point/normal/speed), assemblies and welds, mover constraints replacing BodyMovers, mechanical constraints, network ownership, CFrame math, vehicles/projectiles, and server authority (BindToSimulation, prediction, rollback). Use when moving parts, detecting hits, building vehicles or projectiles, or fixing jitter, flinging, or ownership bugs.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- gamedev-skills/awesome-gamedev-agent-skillstheir own version, first seen Oct 23, 2026
- TabooHarmony/roblox-braintheir own version, first seen Sep 23, 2026
- nonlooped/roblox-suitetheir own version, first seen Sep 19, 2026
- szlay/roblox-basetheir own version, first seen Jul 24, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- gamedev-skills/awesome-gamedev-agent-skills★ 6.4ksame name
- TabooHarmony/roblox-brain★ 150same name
- nonlooped/roblox-suite★ 25same name
- szlay/roblox-base★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository25 other files it gives its agents.
- AGENTS.mdAGENTS.md
- docs/agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- roblox-analytics-liveopsSkill
- roblox-architectureSkill
- roblox-audioSkill
- roblox-characters-animationSkill
- roblox-code-reviewSkill
- roblox-data-storesSkill
- roblox-game-systemsSkill
- roblox-inputSkill
- roblox-luauSkill
- roblox-monetizationSkill
- roblox-networkingSkill
- roblox-npc-aiSkill
- roblox-open-cloudSkill
- roblox-performanceSkill
- roblox-securitySkill
- roblox-studio-mcpSkill
- roblox-teleport-matchmakingSkill
- roblox-testingSkill
- roblox-text-chatSkill
- roblox-toolingSkill
- roblox-uiSkill
- roblox-world-buildingSkill
The file
We split this skill into the rules it gives an agent
5 rules. 0 are common, 0 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 94
No summaries for CanCollide = false parts or between two sleeping parts.
- Very specific: line 142
Read/set physics via AssemblyLinearVelocity/AssemblyAngularVelocity, part:ApplyImpulse(), ApplyAngularImpulse(), AssemblyMass.
- Very specific: line 159
All need an Attachment (Attachment0).
- Very specific: line 188
Don't cache AnimationTracks.
- Very specific: line 189
Read a player's camera on the server with player:GetCameraState() (CFrame, FieldOfView, ViewportSize).
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Roblox physics and spatial queries
Spatial queries (use these, not Touched, for gameplay decisions)
--!strict
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {} -- e.g. { character } of the shooter
params.IgnoreWater = true
local function castRay(origin: Vector3, direction: Vector3): RaycastResult?
-- direction's length is the max distance
return workspace:Raycast(origin, direction, params)
end
local result = castRay(Vector3.new(0, 50, 0), Vector3.new(0, -100, 0))
if result then
print(result.Instance, result.Position, result.Normal, result.Material, result.Distance)
end
-- Swept volumes: thick bullets, melee arcs, ground checks with width.
local sphereHit = workspace:Spherecast(Vector3.new(0, 10, 0), 2, Vector3.new(0, 0, 50), params)
local boxHit = workspace:Blockcast(CFrame.new(0, 10, 0), Vector3.new(4, 4, 4), Vector3.new(0, 0, 50), params)
-- Volume overlap: explosions, hitboxes, zone checks.
local overlap = OverlapParams.new()
overlap.FilterType = Enum.RaycastFilterType.Exclude
overlap.MaxParts = 50
local partsInBox = workspace:GetPartBoundsInBox(CFrame.new(0, 5, 0), Vector3.new(10, 10, 10), overlap)
local partsInSphere = workspace:GetPartBoundsInRadius(Vector3.zero, 15, overlap)
print(sphereHit, boxHit, #partsInBox, #partsInSphere)- Reuse params objects; update
FilterDescendantsInstances(orparams:AddToFilter(instance)) instead of allocating per call. - Newer filters:
params.ExcludeInstances/IncludeInstances(can be combined; exclude wins) supersedeFilterType+FilterDescendantsInstancesfor new code. RespectCanCollide = trueto ignore non-collidable parts;CollisionGroup = "Name"to query as a group.- Shapecasts (October 2026):
params.Margininflates/rounds the cast shape (aRaycastwith a margin acts as a spherecast — use a thin one where rays slip through seams);params.SizeGradientgrows/shrinks it along the cast (0.5ends 50% larger,-1shrinks to nothing) for cones and funnels;workspace:Shapecast(part, direction, params, cframeOverride?, sizeOverride?)casts a part from any pose/size without moving it (placement previews). Debug: Studio Visualization Modes → Physics → Shapecasts. GetPartsInPart(part, params)does exact geometry overlap (costlier);GetPartBoundsIn*use bounding boxes.- Deprecated:
FindPartOnRay*,Ray.new,FindPartsInRegion3*→ use the APIs above. - Client queries only see streamed-in parts; authoritative checks run on the server.
Touched: know its limits
Touched fires from the physics engine, only for parts that physically contact, is fired by whoever
simulates the part (clients can spoof or suppress it for parts they own), and can fire many times per
contact. Use it for triggers (pads, pickups) with a debounce and server-side validation; use spatial
queries for hit detection and zones.
--!strict
local Players = game:GetService("Players")
local pad = Instance.new("Part")
pad.Anchored = true
pad.Parent = workspace
local recently: { [Player]: boolean } = {}
pad.Touched:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
if not player or recently[player] then
return
end
recently[player] = true
print(`{player.Name} stepped on the pad`)
task.delay(1, function()
recently[player] = nil
end)
end)Collision summaries (impact data)
For how parts hit (impact FX, impact audio, damage by impact speed), use
BasePart:BindToCollisionSummaries(callback) instead of Touched. Once per frame after the physics step,
the callback gets every contact of that part: Part0 (the bound part), Part1, Point, Normal (points
away from Part0), RelativeVelocity (before the solver resolves the hit), Area, and Time.
- Fires only where the part is simulated (its network owner); nothing replicates. Send what others need through your own remote, validated on the server.
- No summaries for
CanCollide = falseparts or between two sleeping parts; non-convex parts can produce several summaries per pair. Cost scales with bound parts, not total collisions.
--!strict
local function bindImpacts(part: BasePart, onImpact: (point: Vector3, speed: number) -> ()): RBXScriptConnection
return part:BindToCollisionSummaries(function(summaries: { any })
for _, summary in summaries do
local speed = math.abs(summary.RelativeVelocity:Dot(summary.Normal)) -- head-on impact speed
if speed > 10 then
onImpact(summary.Point, speed)
end
end
end)
end
return bindImpactsCollision groups
--!strict
-- Collision group APIs now live on WorldRoot (workspace); the PhysicsService versions are superseded.
workspace:RegisterCollisionGroup("Players")
workspace:RegisterCollisionGroup("Ghosts")
workspace:CollisionGroupSetCollidable("Players", "Ghosts", false)
local ghost = Instance.new("Part")
ghost.CollisionGroup = "Ghosts" -- assign by name (CollisionGroupId/SetPartCollisionGroup are deprecated)
ghost.Parent = workspaceRegister groups once at server start (max 32, see workspace:GetMaxCollisionGroups()). CanCollide = false removes all collisions;
CanQuery = false hides a part from raycasts; CanTouch = false disables Touched (saves CPU);
NoCollisionConstraint disables collision between two specific parts.
MeshPart collision shape: CollisionFidelity Box/Hull (cheap), Default, PreciseConvexDecomposition
(costly), or Tunable with a CollisionPrecision slider (set in Studio; scripts can't write it) to trade
precision for performance per mesh.
Assemblies and joints
- An assembly = parts rigidly connected (welds,
WeldConstraint,Motor6D, rigid constraints). It simulates as one body; the root part (part.AssemblyRootPart) determines network ownership. - Anchor static geometry. Unanchored + welded to an anchored part = anchored assembly.
- Weld at edit time with
WeldConstraint(keeps current offset); in code setPart0/Part1and parent. - Move whole models with
model:PivotTo(cframe). Moving many parts at once:workspace:BulkMoveTo. - Read/set physics via
AssemblyLinearVelocity/AssemblyAngularVelocity,part:ApplyImpulse(),ApplyAngularImpulse(),AssemblyMass.Velocity/RotVelocityare deprecated. CustomPhysicalProperties = PhysicalProperties.new(density, friction, elasticity, frictionWeight, elasticityWeight).- Units: 1 stud ≈ 0.28 m,
workspace.Gravitydefault 196.2 studs/s².
Mover constraints (replace BodyMovers)
| Goal | Constraint | Replaces |
| Hold/drive a velocity | LinearVelocity (VelocityConstraintMode Vector/Plane/Line) | BodyVelocity |
| Move toward a position | AlignPosition (Mode = OneAttachment + Position, Responsiveness, MaxForce) | BodyPosition |
| Rotate toward an orientation | AlignOrientation (CFrame/LookAtPosition) | BodyGyro |
| Constant force | VectorForce (RelativeTo = World) | BodyForce, BodyThrust |
| Spin | AngularVelocity | BodyAngularVelocity |
| Pull toward point | LineForce | RocketPropulsion |
| Torque | Torque | — |
All need an Attachment (Attachment0). Set MaxForce/MaxTorque realistically (not math.huge
unless intended) or objects fling. Mechanical constraints: HingeConstraint (Motor/Servo actuators for
wheels, doors), PrismaticConstraint (sliders, elevators), SpringConstraint (suspension),
RopeConstraint, RodConstraint, BallSocketConstraint, CylindricalConstraint (wheel + steering),
UniversalConstraint, RigidConstraint.
Vehicle and projectile recipes, CFrame cookbook: references/recipes.md.
Network ownership
- The server auto-assigns ownership of unanchored assemblies to a nearby client (smooth for that client, exploitable by it). Characters are owned by their player.
part:SetNetworkOwner(nil)= server simulates (secure, laggier for players);SetNetworkOwner(player)for a vehicle driver;SetNetworkOwnershipAuto()to restore. Call on the root part, server-side, after the assembly is inWorkspace. Anchored parts have no owner.- Ownership changes cause hitches; don't flip it every frame. Visualize with the viewport's Visualization options → Network owners toggle.
Server authority (competitive games)
Workspace AuthorityMode = Server makes the server simulate everything while clients predict a few
frames ahead and roll back/resimulate on mispredictions. Requirements: NextGenerationReplication,
PlayerScriptsUseInputActionSystem, SignalBehavior = Deferred, UseFixedSimulation, StreamingEnabled
(setting AuthorityMode sets these). Core rules:
- Game logic lives in functions bound with
RunService:BindToSimulation(fn)inside a ModuleScript required by both server and client. - Clients affect the game only through Input Actions (InputContexts parented under the
Player), notUserInputServiceevents. - Sync custom state through attributes on predicted instances, written only inside simulation callbacks.
- Don't cache
AnimationTracks; queryAnimator:GetTrackByAnimationId()each step. - Read a player's camera on the server with
player:GetCameraState()(CFrame,FieldOfView,ViewportSize); the old cameraInputActionreplication no longer syncs.
Fully released (opt-in) since July 2026. Details and patterns: references/server-authority.md.
Stability tips
- Jitter: conflicting ownership, constraints fighting, huge mass ratios (> 1:100), or setting CFrame on unanchored parts every frame (use constraints instead).
- Flinging:
MaxForce = math.hugeon light parts, overlapping collisions at spawn, NaN/huge velocities. - Sleeping assemblies stop simulating until disturbed — wake with a small impulse if needed.
- Adaptive timestepping (
Workspace.PhysicsSteppingMethod = Adaptive) saves CPU; use fixed for precise mechanisms.
Related skills
roblox-security (ownership exploits), roblox-characters-animation, roblox-networking,
roblox-performance, roblox-input.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

