What happens when you spill off the track into the lush green grass
This article details the extra calculations that the driving model performs when any part of the car is driving on grass. It is designed to be read alongside the core driving model calculations.
Note that the game knows if the car is on grass by checking the colour of two specific screen pixel bytes, one just to the left of the dashboard, and the other just to the right. If one of these pixel bytes is fully green, then we know that side of the car is on grass. The screen memory addresses for these two bytes are defined by the leftSurface and rightSurface configuration variables.
See code: ApplyGrassOrTrack
This is an explanation of calculation 5 in the driving model. It might help to see calculation 5 in context.
First, we check whether we have just hit the track verge, and if so, we set some variables so the car jumps and spins, as follows:
- If all the following are true:
- There is grass under at least one side of the car
- bumpyGrassHeight = 0
- heightAboveTrack = 0
- Bit 7 of playerDrift is set
- We have at least one wheel off the track
- We haven't already hit the grass, as the grass height is zero
- We aren't already jumping, as we are on the ground
- We are moving sideways pretty fast
yGravityDelta = playerSpeedHi / 2 yJumpHeight = playerSpeedHi / 4 heightAboveTrack = heightAboveTrack + 1 spinYawAngleHi = spinYawAngleHi >> 1 with bit 7 setWe also make the crash/contact sound to indicate that we have hit the verge.
Second, if any part of the car is on the grass, then we set the height of the grass in bumpyGrassHeight to a random figure in the range 1 to 7 (with a higher number more likely at higher speeds). We do this on each iteration of the main driving loop, so while we are driving on grass, our height bumps up and down, with higher bumps the faster we are going. Specifically, we do this:
- If there is grass under at least one side of the car, then:
bumpyGrassHeight = random number in the range 1 to 7 that is higher with higher speedsotherwise:
bumpyGrassHeight = 0
These variables are used in the jumps and drops calculation in the last step of the driving model.
Calculation 6: Calculate wing and brake downward forces
See code: ApplyGrassOrTrack
This is an explanation of calculation 6 in the driving model. It might help to see calculation 6 in context.
If we are driving on grass on both sides of the car, then instead of the normal calculation, we set:
wingForce = wingForceGrass + brakeForce
where wingForceGrass is defined as 25 for the front wing and 26 for the rear wing. This cancels out the downward force that we normally get from the wings, and reduces the base downward force from wingForceTrack (53) to wingForceGrass (25 or 26). The result is a serious loss of grip.
See code: ApplyWingBalance
This is an explanation of calculation 17 in the driving model. It might help to see calculation 17 in context.
If bumpyGrassHeight > 0, then we are already driving across grass, so we change the calculation so the acceleration reduces by twice the amount, as follows:
xPlayerAccel = xPlayerAccel - 2 * playerSpeedHi * xPrevVelocityHi
zPlayerAccel = zPlayerAccel - 2 * playerSpeedHi * (wingBalance * playerSpeedHi + 2048) * abs(zVelocity)
The effect is that driving on grass doubles the drag on the car, which leads to a noticeable loss of acceleration.