diff --git a/Game/scripts/ship.gd b/Game/scripts/ship.gd index e1310025..788faeee 100644 --- a/Game/scripts/ship.gd +++ b/Game/scripts/ship.gd @@ -18,6 +18,7 @@ extends RigidBody3D @export var max_angular_speed = 3.0 # Maximum rotation speed @export var drag_coefficient = 0.98 # Linear drag (air resistance) @export var angular_drag = 0.95 # Rotational drag +@export var idle_angular_drag = 0.9 # Rotational drag when no rotation input is held @export_group("Surface Pull") @export var wall_pull_strength = 6.0 # Wall grav-plating strength (m/s^2-equivalent) @@ -279,12 +280,22 @@ func apply_rotation_forces(state: PhysicsDirectBodyState3D, rotation_input: Vect state.apply_torque(torque) +# Scales a per-tick decay multiplier `k` (defined at a 60 Hz reference rate) +# by the actual elapsed tick time `step`, so `v *= _tick_scaled(k, step)` +# decays at the same rate per second regardless of physics_ticks_per_second. +func _tick_scaled(k: float, step: float) -> float: + return pow(k, step * 60.0) + + func apply_drag_and_limits(state: PhysicsDirectBodyState3D, rotation_input: Vector3): # Linear drag (air resistance) # Physics: F_drag = -½ * ρ * v² * C_d * A (drag force equation) # Simplified: v_new = v_old * drag_coefficient (exponential decay) - # This simulates air resistance reducing velocity over time - state.linear_velocity *= drag_coefficient + # This simulates air resistance reducing velocity over time. + # _tick_scaled makes the decay rate invariant to the physics tick rate — + # drag_coefficient/angular_drag/idle_angular_drag are all defined as the + # per-tick multiplier at a 60 Hz reference rate. + state.linear_velocity *= _tick_scaled(drag_coefficient, state.step) # Angular drag (rotational resistance) # Physics: Similar to linear drag but for rotational motion @@ -292,10 +303,10 @@ func apply_drag_and_limits(state: PhysicsDirectBodyState3D, rotation_input: Vect # Simplified: ω_new = ω_old * angular_drag (exponential decay) if rotation_input.length() < 0.01: # More drag when not actively rotating to stop quicker - state.angular_velocity *= 0.9 + state.angular_velocity *= _tick_scaled(idle_angular_drag, state.step) else: # Normal drag when actively rotating - state.angular_velocity *= angular_drag + state.angular_velocity *= _tick_scaled(angular_drag, state.step) # Limit maximum speeds # Physics: Terminal velocity concept - maximum achievable speed