Skip to content
Development
Skill

/roblox-physics

Implement Roblox physical simulation and queries with assemblies, anchoring, constraints, collision groups, CanCollide/CanTouch/CanQuery, raycasts and overlap queries, mass, impulses, forces, velocity, moving assemblies, cleanup, and network ownership. Use for Roblox collisions,

From plugin
awesome-gamedev-agent-skills
6.3k77 skills

Claude Code

$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill roblox-physics --agent claude-code

SKILL.md

roblox-physics.SKILL.md
name: roblox-physics
description: >
  Roblox physics and spatial queries: assemblies, constraints, collision groups, Raycast and
  Shapecast, and network ownership. Use when parts fall through or jitter, Touched is unreliable,
  a ray hits the shooter, or BodyMovers need replacing. Not for hit legitimacy
  (`roblox-networking`), Humanoid movement (`roblox-characters`) or engine-neutral tuning
  (`physics-tuning`).

Roblox physics

Simulation, character control, hit detection and visual-only motion are different jobs. Pick the mechanism first, then the API. Whether a hit counts is a server validation decision owned by `roblox-networking`; this skill supplies the queries it uses.

Decide the mechanism

| Goal | Mechanism | |---|---| | sustained physical interaction | unanchored assembly plus modern constraints or forces | | one-off physical change | `ApplyImpulse` / `ApplyAngularImpulse` | | kinematic platform or path | scripted pivot or CFrame with an explicit passenger policy | | character locomotion | Humanoid or Character Controller Library (`roblox-characters`) | | hit test | server raycast, shapecast, or overlap with explicit filters | | cosmetic trail or recoil | local visual motion; no gameplay authority |

Workflow

1. **Inspect the mechanism.** In Studio, turn on the assembly, constraint and network-owner visualizations; or read `part.AssemblyRootPart`, `part.AssemblyMass`, `part.Anchored` and `part:GetNetworkOwner()` from code. Identify the assembly root and who should own it. 2. **Write the interaction policy.** A collision-group matrix, then `CanCollide`, `CanTouch` and `CanQuery` decided separately per role. Register groups once with `Workspace:RegisterCollisionGroup()` and `CollisionGroupSetCollidable()` (or the Collision Groups editor), from a single script so assignment never races registration. 3. **Choose simulation or query.** A ray for a line, a shapecast for a moving volume, an overlap for a static volume, and simulation contacts only when a physical response is wanted. `.Touched` is neither reliable nor secure as a hit detector. 4. **Apply motion at assembly level.** Forces on any part act on the whole assembly. Use `LinearVelocity`, `AngularVelocity`, `VectorForce`, `AlignPosition` and `AlignOrientation`; migrate BodyMovers when you touch that system. 5. **Set ownership deliberately.** Server-own gameplay-critical loose assemblies when needed; client ownership improves response but never authorizes results. 6. **Bound cost and lifetime.** Reuse query params, cap query frequency and result counts, and destroy temporary constraints, attachments and connections together. 7. **Check from code.** With the Studio MCP server connected, start play and use `execute_luau` on the `Server` datamodel to print the facts the change depends on: `AssemblyRootPart`, `AssemblyMass`, `GetNetworkOwner()`, `workspace:CollisionGroupsAreCollidable(a, b)`, and the result of one test query; then read `get_console_output`. Without MCP, ask the user to run the same snippet from the Command Bar during play and paste the Output. Fast movers, ownership hand-off and two-client interaction need a Server & Clients run.

Pattern: filtered server raycast

local Workspace = game:GetService("Workspace")

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {shooterCharacter}
params.IgnoreWater = true
params.CollisionGroup = "WeaponQuery"

local direction = aimDirection.Unit * MAX_RANGE   -- direction length is the range
local result = Workspace:Raycast(muzzlePosition, direction, params)
if result then
    local model = result.Instance:FindFirstAncestorOfClass("Model")
    local humanoid = model and model:FindFirstChildOfClass("Humanoid")
    if humanoid and serverCanDamage(shooter, model, result.Position) then
        humanoid:TakeDamage(serverWeaponDamage(shooter))
    end
end

`muzzlePosition` and `aimDirection` must come from server-known character and weapon state. A raycast from a client-supplied origin is not validation (see `roblox-networking`).

Pattern: overlap volume with explicit policy

local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {sourceCharacter}
params.CollisionGroup = "DamageQuery"
params.MaxParts = 64

local seen: {[Model]: boolean} = {}
for _, part in Workspace:GetPartBoundsInBox(hitboxCFrame, hitboxSize, params) do
    local model = part:FindFirstAncestorOfClass("Model")
    if model and not seen[model] then
        seen[model] = true
        validateAndApplyHit(model)
    end
end

Bounds queries test bounding boxes and return several parts per target, so deduplicate by model. `WorldRoot:GetPartsInPart()` is exact but costs more. `OverlapParams.RespectCanCollide` switches the query from `CanQuery` to `CanCollide`; set it on purpose or it silently overrides the flag policy.

Assemblies, force, and ownership

  • Welded parts form one rigid assembly; force, impulse, velocity, mass and ownership act on the

assembly. One anchored part anchors the whole assembly.

  • Tune forces and impulses from intended acceleration times `AssemblyMass`, not by trial values.
  • Automatic ownership moves nearby unanchored assemblies to clients. Call `SetNetworkOwner(nil)`

for critical objects, then measure the server cost and responsiveness. Re-check ownership after anchoring changes; it is not always kept.

  • A client owner can fake physical results and `.Touched` events. The server validates

consequential hits, positions, timing and permissions independently.

  • If `Workspace.AuthorityMode` is `Server`, the server owns simulation and clients predict nearby

assemblies with rollback. Drive predicted forces and constraints from `RunService:BindToSimulation()` on both sides, not from `Heartbeat` or client-only scripts, and expect custom physics scripts to need cha

Read more
@gamedev-skills
Ships withawesome-gamedev-agent-skills

<img src="docs/assets/awesome-gamedev-agent-skills-banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.

Stars on GitHub

Momentum

stars in total
6.3k
Star history of gamedev-skills/awesome-gamedev-agent-skills on GitHub, a chart by star-history.com

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills12d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about roblox-physics.

Which coding agents can use roblox-physics?
roblox-physics installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.