@@ -57,7 +57,11 @@ const TAU = Math.PI * 2;
5757
5858const ACCEL = 560 ;
5959const FRICTION = 2.8 ;
60+ // Rolling resistance while coasting is much lower, so the rover glides and
61+ // rolls downhill into dips instead of stopping dead on an incline.
62+ const ROLL_FRICTION = 0.8 ;
6063const AIR_FRICTION = 1.1 ;
64+ const FLAT_GRADE = 0.06 ;
6165const MAX_V = 220 ;
6266// Lunar gravity: floaty ascents and descents, with slow bouncy landings.
6367const FLY_GRAVITY = 60 ;
@@ -189,10 +193,26 @@ export function stepRover(
189193 state . vx += ACCEL * dt ;
190194 state . facing = 1 ;
191195 }
192- const friction = state . onGround && ! input . thrust ? FRICTION : AIR_FRICTION ;
196+
197+ // Gravity pulls the rover along the grade it stands on, so it rolls
198+ // downhill and comes to rest at the bottom of dips, not mid-slope.
199+ const grade = state . onGround ? terrain . slopeAt ( state . x ) : 0 ;
200+ if ( state . onGround ) {
201+ state . vx += ( grade / Math . hypot ( 1 , grade ) ) * FALL_GRAVITY * dt ;
202+ }
203+
204+ const driving = input . left || input . right ;
205+ const friction =
206+ state . onGround && ! input . thrust
207+ ? driving
208+ ? FRICTION
209+ : ROLL_FRICTION
210+ : AIR_FRICTION ;
193211 state . vx *= Math . exp ( - friction * dt ) ;
194212 state . vx = Math . max ( - MAX_V , Math . min ( MAX_V , state . vx ) ) ;
195- if ( Math . abs ( state . vx ) < 0.5 && ! input . left && ! input . right ) state . vx = 0 ;
213+ if ( Math . abs ( state . vx ) < 0.5 && ! driving && Math . abs ( grade ) < FLAT_GRADE ) {
214+ state . vx = 0 ;
215+ }
196216
197217 state . x = ( ( state . x + state . vx * dt ) % terrain . width + terrain . width ) %
198218 terrain . width ;
0 commit comments