diff --git a/Robust.Shared/Physics/Components/PhysicsComponent.Physics.cs b/Robust.Shared/Physics/Components/PhysicsComponent.Physics.cs
index 4e620399b2c..2e9732a092f 100644
--- a/Robust.Shared/Physics/Components/PhysicsComponent.Physics.cs
+++ b/Robust.Shared/Physics/Components/PhysicsComponent.Physics.cs
@@ -221,6 +221,12 @@ public sealed partial class PhysicsComponent : Component
Other = AccessPermissions.Read)]
public float LinearDamping = 0.2f;
+ ///
+ /// This is a set amount that the body's linear velocity is reduced by every tick when the body is off-grid.
+ ///
+ [DataField, Access(typeof(SharedPhysicsSystem), Friend = AccessPermissions.ReadWriteExecute, Other = AccessPermissions.Read)]
+ public float OffGridLinearDamping = 0.05f;
+
///
/// This is a set amount that the body's angular velocity is reduced every tick.
/// Combined with the tile friction.
diff --git a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Island.cs b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Island.cs
index e06d70cdf52..21ec4b06005 100644
--- a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Island.cs
+++ b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Island.cs
@@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.ObjectPool;
using Robust.Shared.GameObjects;
+using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Dynamics;
@@ -716,12 +717,14 @@ private void SolveIsland(
var angles = ArrayPool.Shared.Rent(bodyCount);
var offset = island.Offset;
var xformQuery = GetEntityQuery();
+ var mapGridQuery = GetEntityQuery();
for (var i = 0; i < island.Bodies.Count; i++)
{
var body = island.Bodies[i];
+ var xform = xformQuery.GetComponent(body.Owner);
var (worldPos, worldRot) =
- _transform.GetWorldPositionRotation(xformQuery.GetComponent(body.Owner), xformQuery);
+ _transform.GetWorldPositionRotation(xform, xformQuery);
var transform = new Transform(worldPos, worldRot);
var position = Physics.Transform.Mul(transform, body.LocalCenter);
@@ -744,7 +747,12 @@ private void SolveIsland(
angularVelocity += body.InvI * body.Torque * data.FrameTime;
- linearVelocity *= Math.Clamp(1.0f - data.FrameTime * body.LinearDamping, 0.0f, 1.0f);
+ var onGrid = xform.GridUid != null || mapGridQuery.HasComp(xform.MapUid);
+ var linearDamping = onGrid
+ ? body.LinearDamping
+ : body.OffGridLinearDamping;
+
+ linearVelocity *= Math.Clamp(1.0f - data.FrameTime * linearDamping, 0.0f, 1.0f);
angularVelocity *= Math.Clamp(1.0f - data.FrameTime * body.AngularDamping, 0.0f, 1.0f);
}