From c237b757e8665c1328b76378a83bca8f1f7ce869 Mon Sep 17 00:00:00 2001
From: Vaclav Elias <4528464+VaclavElias@users.noreply.github.com>
Date: Sat, 13 Dec 2025 00:36:18 +0000
Subject: [PATCH 1/3] Fix ShipComponent to manually apply drag instead of using
non-existent damping properties
---
.../Stride.BepuPhysics/ShipComponent.cs | 384 ++++++++++++++++++
1 file changed, 384 insertions(+)
create mode 100644 sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs
diff --git a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs
new file mode 100644
index 0000000000..6a597fa0cf
--- /dev/null
+++ b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs
@@ -0,0 +1,384 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
+using BepuPhysics;
+using BepuPhysics.Collidables;
+using Stride.BepuPhysics.Components;
+using Stride.BepuPhysics.Definitions;
+using Stride.Core;
+using Stride.Core.Mathematics;
+using Stride.Engine;
+using NRigidPose = BepuPhysics.RigidPose;
+
+namespace Stride.BepuPhysics;
+
+///
+/// Component for controlling a ship with atmospheric and space flight modes.
+/// Supports 2D flight with vertical thrust, horizontal acceleration, and mode-dependent physics.
+///
+[ComponentCategory("Physics - Bepu")]
+public class ShipComponent : BodyComponent, ISimulationUpdate
+{
+ private float _currentSpeed;
+ private bool _isHovering;
+
+ ///
+ /// Flight mode of the ship affecting gravity and drag behavior.
+ ///
+ public FlightMode Mode { get; set; } = FlightMode.Atmospheric;
+
+ ///
+ /// Maximum horizontal speed the ship can achieve in units per second.
+ ///
+ public float MaxSpeed { get; set; } = 50f;
+
+ ///
+ /// Rate at which the ship accelerates horizontally in units per second squared.
+ ///
+ public float Acceleration { get; set; } = 20f;
+
+ ///
+ /// Rate at which the ship decelerates when braking in units per second squared.
+ ///
+ public float BrakeDeceleration { get; set; } = 40f;
+
+ ///
+ /// Force applied for vertical thrust (W/S keys) in Newtons.
+ ///
+ public float VerticalThrustForce { get; set; } = 100f;
+
+ ///
+ /// Linear drag coefficient for atmospheric flight. Higher values = more drag.
+ /// Drag force = LinearDragCoefficient * velocity.
+ /// Only applied in Atmospheric mode.
+ ///
+ public float AtmosphericLinearDrag { get; set; } = 0.5f;
+
+ ///
+ /// Angular drag coefficient for atmospheric flight. Higher values = more rotational drag.
+ /// Drag torque = AngularDragCoefficient * angularVelocity.
+ /// Only applied in Atmospheric mode.
+ ///
+ public float AtmosphericAngularDrag { get; set; } = 0.3f;
+
+ ///
+ /// Linear drag coefficient for space flight. Lower values = less friction.
+ /// Only applied in Space mode.
+ ///
+ public float SpaceLinearDrag { get; set; } = 0.05f;
+
+ ///
+ /// Angular drag coefficient for space flight. Lower values = less rotational friction.
+ /// Only applied in Space mode.
+ ///
+ public float SpaceAngularDrag { get; set; } = 0.02f;
+
+ ///
+ /// When hovering in atmospheric mode, the ship will counteract gravity to maintain altitude.
+ ///
+ [DataMemberIgnore]
+ public bool IsHovering
+ {
+ get => _isHovering;
+ set
+ {
+ if (_isHovering == value)
+ return;
+ _isHovering = value;
+ UpdateHoverState();
+ }
+ }
+
+ ///
+ /// Current horizontal speed of the ship (can be negative for reverse).
+ ///
+ [DataMemberIgnore]
+ public float CurrentSpeed
+ {
+ get => _currentSpeed;
+ private set => _currentSpeed = MathUtil.Clamp(value, -MaxSpeed, MaxSpeed);
+ }
+
+ ///
+ /// Intended thrust direction: 1 = forward (D), -1 = reverse (A), 0 = no thrust.
+ ///
+ [DataMemberIgnore]
+ public float ThrustDirection { get; set; }
+
+ ///
+ /// Whether braking (Space) is currently active.
+ ///
+ [DataMemberIgnore]
+ public bool IsBraking { get; set; }
+
+ ///
+ /// Vertical thrust input: 1 = up (W), -1 = down (S), 0 = none.
+ ///
+ [DataMemberIgnore]
+ public float VerticalThrust { get; set; }
+
+ public ShipComponent()
+ {
+ InterpolationMode = InterpolationMode.Interpolated;
+ }
+
+ ///
+ protected override void AttachInner(NRigidPose pose, BodyInertia shapeInertia, TypedIndex shapeIndex)
+ {
+ base.AttachInner(pose, shapeInertia, shapeIndex);
+ UpdateFlightMode();
+ }
+
+ ///
+ /// Applies forward thrust (D key).
+ ///
+ public void ThrustForward()
+ {
+ ThrustDirection = 1f;
+ IsBraking = false;
+ }
+
+ ///
+ /// Applies reverse thrust (A key).
+ ///
+ public void ThrustReverse()
+ {
+ ThrustDirection = -1f;
+ IsBraking = false;
+ }
+
+ ///
+ /// Stops horizontal thrust input.
+ ///
+ public void StopThrust()
+ {
+ ThrustDirection = 0f;
+ }
+
+ ///
+ /// Activates braking (Space key).
+ ///
+ public void Brake()
+ {
+ IsBraking = true;
+ ThrustDirection = 0f;
+ }
+
+ ///
+ /// Releases brake.
+ ///
+ public void ReleaseBrake()
+ {
+ IsBraking = false;
+ }
+
+ ///
+ /// Applies upward thrust (W key).
+ ///
+ public void ThrustUp()
+ {
+ VerticalThrust = 1f;
+ }
+
+ ///
+ /// Applies downward thrust (S key).
+ ///
+ public void ThrustDown()
+ {
+ VerticalThrust = -1f;
+ }
+
+ ///
+ /// Stops vertical thrust input.
+ ///
+ public void StopVerticalThrust()
+ {
+ VerticalThrust = 0f;
+ }
+
+ ///
+ /// Switches between Atmospheric and Space flight modes.
+ ///
+ public void ToggleFlightMode()
+ {
+ Mode = Mode == FlightMode.Atmospheric ? FlightMode.Space : FlightMode.Atmospheric;
+ UpdateFlightMode();
+ }
+
+ ///
+ /// Called before physics simulation tick.
+ ///
+ public virtual void SimulationUpdate(BepuSimulation sim, float simTimeStep)
+ {
+ Awake = true; // Keep ship active
+
+ // Handle horizontal acceleration/deceleration
+ if (IsBraking)
+ {
+ ApplyBraking(simTimeStep);
+ }
+ else if (ThrustDirection != 0f)
+ {
+ CurrentSpeed += ThrustDirection * Acceleration * simTimeStep;
+ }
+ else
+ {
+ // Natural deceleration when no input
+ ApplyNaturalDeceleration(simTimeStep);
+ }
+
+ // Apply horizontal velocity (assuming X is horizontal in 2D)
+ var velocity = LinearVelocity;
+ velocity.X = CurrentSpeed;
+
+ // Handle vertical thrust
+ if (Mode == FlightMode.Atmospheric)
+ {
+ if (VerticalThrust != 0f)
+ {
+ // Active vertical thrust
+ ApplyLinearImpulse(new Vector3(0, VerticalThrust * VerticalThrustForce * simTimeStep, 0));
+ IsHovering = false;
+ }
+ else if (IsHovering)
+ {
+ // Hover mode: counteract gravity
+ var gravity = Simulation!.PoseGravity;
+ var gravityMagnitude = gravity.Length();
+ if (gravityMagnitude > 0f)
+ {
+ // Apply upward force equal to gravity
+ var mass = 1f / BodyInertia.InverseMass;
+ var counterForce = -Vector3.Normalize(gravity) * gravityMagnitude * mass;
+ ApplyLinearImpulse(counterForce * simTimeStep);
+ }
+ }
+ }
+ else // Space mode
+ {
+ if (VerticalThrust != 0f)
+ {
+ ApplyLinearImpulse(new Vector3(0, VerticalThrust * VerticalThrustForce * simTimeStep, 0));
+ }
+ }
+
+ // Apply drag to both linear and angular velocities
+ ApplyDrag(simTimeStep);
+
+ LinearVelocity = velocity;
+ }
+
+ ///
+ /// Called after physics simulation tick.
+ ///
+ public virtual void AfterSimulationUpdate(BepuSimulation sim, float simTimeStep)
+ {
+ // Update current speed from actual velocity
+ _currentSpeed = LinearVelocity.X;
+ }
+
+ private void ApplyBraking(float deltaTime)
+ {
+ if (MathF.Abs(CurrentSpeed) < 0.01f)
+ {
+ CurrentSpeed = 0f;
+ return;
+ }
+
+ var brakeAmount = BrakeDeceleration * deltaTime;
+ if (CurrentSpeed > 0f)
+ CurrentSpeed = MathF.Max(0f, CurrentSpeed - brakeAmount);
+ else
+ CurrentSpeed = MathF.Min(0f, CurrentSpeed + brakeAmount);
+ }
+
+ private void ApplyNaturalDeceleration(float deltaTime)
+ {
+ // Slower natural deceleration compared to active braking
+ var linearDrag = Mode == FlightMode.Atmospheric ? AtmosphericLinearDrag : SpaceLinearDrag;
+ var deceleration = CurrentSpeed * linearDrag * deltaTime;
+
+ if (MathF.Abs(CurrentSpeed) < 0.01f)
+ {
+ CurrentSpeed = 0f;
+ return;
+ }
+
+ if (CurrentSpeed > 0f)
+ CurrentSpeed = MathF.Max(0f, CurrentSpeed - deceleration);
+ else
+ CurrentSpeed = MathF.Min(0f, CurrentSpeed + deceleration);
+ }
+
+ private void ApplyDrag(float deltaTime)
+ {
+ // Get drag coefficients based on flight mode
+ var linearDrag = Mode == FlightMode.Atmospheric ? AtmosphericLinearDrag : SpaceLinearDrag;
+ var angularDrag = Mode == FlightMode.Atmospheric ? AtmosphericAngularDrag : SpaceAngularDrag;
+
+ // Apply linear drag: F_drag = -coefficient * velocity
+ // Using exponential decay: v_new = v_old * (1 - drag * dt)
+ // This is more stable than force-based approach
+ var linearVelocity = LinearVelocity;
+ var dragFactor = 1f - MathUtil.Clamp(linearDrag * deltaTime, 0f, 1f);
+
+ // Apply drag to Y (vertical) velocity only, X is controlled separately
+ linearVelocity.Y *= dragFactor;
+ linearVelocity.Z *= dragFactor; // Apply to Z for consistency
+
+ LinearVelocity = linearVelocity;
+
+ // Apply angular drag: T_drag = -coefficient * angularVelocity
+ var angularVelocity = AngularVelocity;
+ var angularDragFactor = 1f - MathUtil.Clamp(angularDrag * deltaTime, 0f, 1f);
+ angularVelocity *= angularDragFactor;
+
+ AngularVelocity = angularVelocity;
+ }
+
+ private void UpdateFlightMode()
+ {
+ if (Simulation == null)
+ return;
+
+ switch (Mode)
+ {
+ case FlightMode.Atmospheric:
+ Gravity = true;
+ // Drag is now applied manually in ApplyDrag() using AtmosphericLinearDrag and AtmosphericAngularDrag
+ break;
+
+ case FlightMode.Space:
+ Gravity = false;
+ // Drag is now applied manually in ApplyDrag() using SpaceLinearDrag and SpaceAngularDrag
+ IsHovering = false; // No hovering in space
+ break;
+ }
+ }
+
+ private void UpdateHoverState()
+ {
+ if (Mode == FlightMode.Space)
+ {
+ _isHovering = false; // Cannot hover in space
+ }
+ }
+}
+
+///
+/// Flight mode affecting physics behavior.
+///
+public enum FlightMode
+{
+ ///
+ /// Atmospheric flight with gravity and higher drag.
+ /// Supports hovering to maintain altitude.
+ ///
+ Atmospheric,
+
+ ///
+ /// Space flight with no gravity and minimal drag.
+ /// True Newtonian physics.
+ ///
+ Space
+}
From a31ea829bc77ef7838ad5fb6d4be47ca17392cd5 Mon Sep 17 00:00:00 2001
From: Vaclav Elias <4528464+VaclavElias@users.noreply.github.com>
Date: Sat, 13 Dec 2025 15:30:53 +0000
Subject: [PATCH 2/3] Delete
sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs (#3008)
---
.../Stride.BepuPhysics/ShipComponent.cs | 384 ------------------
1 file changed, 384 deletions(-)
delete mode 100644 sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs
diff --git a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs
deleted file mode 100644
index 6a597fa0cf..0000000000
--- a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/ShipComponent.cs
+++ /dev/null
@@ -1,384 +0,0 @@
-// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
-// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-
-using BepuPhysics;
-using BepuPhysics.Collidables;
-using Stride.BepuPhysics.Components;
-using Stride.BepuPhysics.Definitions;
-using Stride.Core;
-using Stride.Core.Mathematics;
-using Stride.Engine;
-using NRigidPose = BepuPhysics.RigidPose;
-
-namespace Stride.BepuPhysics;
-
-///
-/// Component for controlling a ship with atmospheric and space flight modes.
-/// Supports 2D flight with vertical thrust, horizontal acceleration, and mode-dependent physics.
-///
-[ComponentCategory("Physics - Bepu")]
-public class ShipComponent : BodyComponent, ISimulationUpdate
-{
- private float _currentSpeed;
- private bool _isHovering;
-
- ///
- /// Flight mode of the ship affecting gravity and drag behavior.
- ///
- public FlightMode Mode { get; set; } = FlightMode.Atmospheric;
-
- ///
- /// Maximum horizontal speed the ship can achieve in units per second.
- ///
- public float MaxSpeed { get; set; } = 50f;
-
- ///
- /// Rate at which the ship accelerates horizontally in units per second squared.
- ///
- public float Acceleration { get; set; } = 20f;
-
- ///
- /// Rate at which the ship decelerates when braking in units per second squared.
- ///
- public float BrakeDeceleration { get; set; } = 40f;
-
- ///
- /// Force applied for vertical thrust (W/S keys) in Newtons.
- ///
- public float VerticalThrustForce { get; set; } = 100f;
-
- ///
- /// Linear drag coefficient for atmospheric flight. Higher values = more drag.
- /// Drag force = LinearDragCoefficient * velocity.
- /// Only applied in Atmospheric mode.
- ///
- public float AtmosphericLinearDrag { get; set; } = 0.5f;
-
- ///
- /// Angular drag coefficient for atmospheric flight. Higher values = more rotational drag.
- /// Drag torque = AngularDragCoefficient * angularVelocity.
- /// Only applied in Atmospheric mode.
- ///
- public float AtmosphericAngularDrag { get; set; } = 0.3f;
-
- ///
- /// Linear drag coefficient for space flight. Lower values = less friction.
- /// Only applied in Space mode.
- ///
- public float SpaceLinearDrag { get; set; } = 0.05f;
-
- ///
- /// Angular drag coefficient for space flight. Lower values = less rotational friction.
- /// Only applied in Space mode.
- ///
- public float SpaceAngularDrag { get; set; } = 0.02f;
-
- ///
- /// When hovering in atmospheric mode, the ship will counteract gravity to maintain altitude.
- ///
- [DataMemberIgnore]
- public bool IsHovering
- {
- get => _isHovering;
- set
- {
- if (_isHovering == value)
- return;
- _isHovering = value;
- UpdateHoverState();
- }
- }
-
- ///
- /// Current horizontal speed of the ship (can be negative for reverse).
- ///
- [DataMemberIgnore]
- public float CurrentSpeed
- {
- get => _currentSpeed;
- private set => _currentSpeed = MathUtil.Clamp(value, -MaxSpeed, MaxSpeed);
- }
-
- ///
- /// Intended thrust direction: 1 = forward (D), -1 = reverse (A), 0 = no thrust.
- ///
- [DataMemberIgnore]
- public float ThrustDirection { get; set; }
-
- ///
- /// Whether braking (Space) is currently active.
- ///
- [DataMemberIgnore]
- public bool IsBraking { get; set; }
-
- ///
- /// Vertical thrust input: 1 = up (W), -1 = down (S), 0 = none.
- ///
- [DataMemberIgnore]
- public float VerticalThrust { get; set; }
-
- public ShipComponent()
- {
- InterpolationMode = InterpolationMode.Interpolated;
- }
-
- ///
- protected override void AttachInner(NRigidPose pose, BodyInertia shapeInertia, TypedIndex shapeIndex)
- {
- base.AttachInner(pose, shapeInertia, shapeIndex);
- UpdateFlightMode();
- }
-
- ///
- /// Applies forward thrust (D key).
- ///
- public void ThrustForward()
- {
- ThrustDirection = 1f;
- IsBraking = false;
- }
-
- ///
- /// Applies reverse thrust (A key).
- ///
- public void ThrustReverse()
- {
- ThrustDirection = -1f;
- IsBraking = false;
- }
-
- ///
- /// Stops horizontal thrust input.
- ///
- public void StopThrust()
- {
- ThrustDirection = 0f;
- }
-
- ///
- /// Activates braking (Space key).
- ///
- public void Brake()
- {
- IsBraking = true;
- ThrustDirection = 0f;
- }
-
- ///
- /// Releases brake.
- ///
- public void ReleaseBrake()
- {
- IsBraking = false;
- }
-
- ///
- /// Applies upward thrust (W key).
- ///
- public void ThrustUp()
- {
- VerticalThrust = 1f;
- }
-
- ///
- /// Applies downward thrust (S key).
- ///
- public void ThrustDown()
- {
- VerticalThrust = -1f;
- }
-
- ///
- /// Stops vertical thrust input.
- ///
- public void StopVerticalThrust()
- {
- VerticalThrust = 0f;
- }
-
- ///
- /// Switches between Atmospheric and Space flight modes.
- ///
- public void ToggleFlightMode()
- {
- Mode = Mode == FlightMode.Atmospheric ? FlightMode.Space : FlightMode.Atmospheric;
- UpdateFlightMode();
- }
-
- ///
- /// Called before physics simulation tick.
- ///
- public virtual void SimulationUpdate(BepuSimulation sim, float simTimeStep)
- {
- Awake = true; // Keep ship active
-
- // Handle horizontal acceleration/deceleration
- if (IsBraking)
- {
- ApplyBraking(simTimeStep);
- }
- else if (ThrustDirection != 0f)
- {
- CurrentSpeed += ThrustDirection * Acceleration * simTimeStep;
- }
- else
- {
- // Natural deceleration when no input
- ApplyNaturalDeceleration(simTimeStep);
- }
-
- // Apply horizontal velocity (assuming X is horizontal in 2D)
- var velocity = LinearVelocity;
- velocity.X = CurrentSpeed;
-
- // Handle vertical thrust
- if (Mode == FlightMode.Atmospheric)
- {
- if (VerticalThrust != 0f)
- {
- // Active vertical thrust
- ApplyLinearImpulse(new Vector3(0, VerticalThrust * VerticalThrustForce * simTimeStep, 0));
- IsHovering = false;
- }
- else if (IsHovering)
- {
- // Hover mode: counteract gravity
- var gravity = Simulation!.PoseGravity;
- var gravityMagnitude = gravity.Length();
- if (gravityMagnitude > 0f)
- {
- // Apply upward force equal to gravity
- var mass = 1f / BodyInertia.InverseMass;
- var counterForce = -Vector3.Normalize(gravity) * gravityMagnitude * mass;
- ApplyLinearImpulse(counterForce * simTimeStep);
- }
- }
- }
- else // Space mode
- {
- if (VerticalThrust != 0f)
- {
- ApplyLinearImpulse(new Vector3(0, VerticalThrust * VerticalThrustForce * simTimeStep, 0));
- }
- }
-
- // Apply drag to both linear and angular velocities
- ApplyDrag(simTimeStep);
-
- LinearVelocity = velocity;
- }
-
- ///
- /// Called after physics simulation tick.
- ///
- public virtual void AfterSimulationUpdate(BepuSimulation sim, float simTimeStep)
- {
- // Update current speed from actual velocity
- _currentSpeed = LinearVelocity.X;
- }
-
- private void ApplyBraking(float deltaTime)
- {
- if (MathF.Abs(CurrentSpeed) < 0.01f)
- {
- CurrentSpeed = 0f;
- return;
- }
-
- var brakeAmount = BrakeDeceleration * deltaTime;
- if (CurrentSpeed > 0f)
- CurrentSpeed = MathF.Max(0f, CurrentSpeed - brakeAmount);
- else
- CurrentSpeed = MathF.Min(0f, CurrentSpeed + brakeAmount);
- }
-
- private void ApplyNaturalDeceleration(float deltaTime)
- {
- // Slower natural deceleration compared to active braking
- var linearDrag = Mode == FlightMode.Atmospheric ? AtmosphericLinearDrag : SpaceLinearDrag;
- var deceleration = CurrentSpeed * linearDrag * deltaTime;
-
- if (MathF.Abs(CurrentSpeed) < 0.01f)
- {
- CurrentSpeed = 0f;
- return;
- }
-
- if (CurrentSpeed > 0f)
- CurrentSpeed = MathF.Max(0f, CurrentSpeed - deceleration);
- else
- CurrentSpeed = MathF.Min(0f, CurrentSpeed + deceleration);
- }
-
- private void ApplyDrag(float deltaTime)
- {
- // Get drag coefficients based on flight mode
- var linearDrag = Mode == FlightMode.Atmospheric ? AtmosphericLinearDrag : SpaceLinearDrag;
- var angularDrag = Mode == FlightMode.Atmospheric ? AtmosphericAngularDrag : SpaceAngularDrag;
-
- // Apply linear drag: F_drag = -coefficient * velocity
- // Using exponential decay: v_new = v_old * (1 - drag * dt)
- // This is more stable than force-based approach
- var linearVelocity = LinearVelocity;
- var dragFactor = 1f - MathUtil.Clamp(linearDrag * deltaTime, 0f, 1f);
-
- // Apply drag to Y (vertical) velocity only, X is controlled separately
- linearVelocity.Y *= dragFactor;
- linearVelocity.Z *= dragFactor; // Apply to Z for consistency
-
- LinearVelocity = linearVelocity;
-
- // Apply angular drag: T_drag = -coefficient * angularVelocity
- var angularVelocity = AngularVelocity;
- var angularDragFactor = 1f - MathUtil.Clamp(angularDrag * deltaTime, 0f, 1f);
- angularVelocity *= angularDragFactor;
-
- AngularVelocity = angularVelocity;
- }
-
- private void UpdateFlightMode()
- {
- if (Simulation == null)
- return;
-
- switch (Mode)
- {
- case FlightMode.Atmospheric:
- Gravity = true;
- // Drag is now applied manually in ApplyDrag() using AtmosphericLinearDrag and AtmosphericAngularDrag
- break;
-
- case FlightMode.Space:
- Gravity = false;
- // Drag is now applied manually in ApplyDrag() using SpaceLinearDrag and SpaceAngularDrag
- IsHovering = false; // No hovering in space
- break;
- }
- }
-
- private void UpdateHoverState()
- {
- if (Mode == FlightMode.Space)
- {
- _isHovering = false; // Cannot hover in space
- }
- }
-}
-
-///
-/// Flight mode affecting physics behavior.
-///
-public enum FlightMode
-{
- ///
- /// Atmospheric flight with gravity and higher drag.
- /// Supports hovering to maintain altitude.
- ///
- Atmospheric,
-
- ///
- /// Space flight with no gravity and minimal drag.
- /// True Newtonian physics.
- ///
- Space
-}
From ea6ffa5594feb22b983884d314c4c17be2faf6b7 Mon Sep 17 00:00:00 2001
From: Vaclav Elias <4528464+VaclavElias@users.noreply.github.com>
Date: Sat, 13 Dec 2025 18:40:12 +0000
Subject: [PATCH 3/3] docs: copilot-instructions.md - Emphasize XML doc review
- Instruct reviewers to always check for missing, incomplete, or incorrect XML documentation on public APIs.
---
.github/copilot-instructions.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index e5b1cfb03e..b2ab6746a6 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -20,5 +20,13 @@ Stride is a game engine project that requires careful code reviews to maintain q
- If you find a bug or performance issue, suggest a concrete fix in the PR.
- For large PRs (20+ C#/*.cs files), do not attempt a full review, only highlight critical or blocking issues.
- Always consider the context and established patterns in the Stride codebase before making suggestions.
+- **Always check for missing, incomplete, or incorrect XML documentation comments** on public types, methods, properties, and fields.
+- **Provide XML comment suggestions as individual, separate items** so they can be reviewed and approved independently.
+- **Do not rewrite existing XML comments unless they contain errors** such as incorrect information, poor grammar, typos, or lack clarity. Preserve well-written documentation.
+- When suggesting XML comments, ensure they are:
+ - Accurate and describe the actual functionality
+ - Consistent with existing documentation style in the codebase
+ - Include ``, ``, ``, `` and `` tags where appropriate
+ - Clear and helpful for API consumers
The goal is to minimize noise and maximize helpful, actionable feedback.