Documentation

v2.5.3

Terrain Difficulty Model

RaceCraft uses a sophisticated terrain difficulty system that models how different trail surfaces and technical features affect running pace. Unlike simple time penalties, terrain difficulty is implemented as a local, immediate efficiency penalty that affects segment speed without altering fatigue accumulation.

Overview

The terrain model recognises that technical terrain slows runners down independently of fitness or fatigue. A fresh runner on rocky terrain will be slower than on smooth trail, and a fatigued runner on rocky terrain will experience the same terrain-induced slowdown plus their fatigue penalty.

Key Principles

  1. Terrain affects speed, not fatigue: Terrain difficulty multiplies segment time but does NOT affect when fatigue kicks in or how fast it accumulates
  2. Separate from gradient: Terrain and elevation changes are independent factors - steep smooth trail is different from flat technical trail
  3. Skill-dependent: Technical skill reduces terrain penalties, representing experienced trail runners' ability to navigate obstacles efficiently
  4. Gradient-scaled: Terrain effects amplify on steeper grades (both up and down)
  5. Descent-weighted: Terrain impacts descents more than climbs (braking and foot placement are more critical downhill)

Terrain Efficiency Factor (TEF)

The core of the model is the Terrain Efficiency Factor (TEF), a multiplier applied to segment time:

segment_time = base_time × terrain_factor × fatigue_multiplier

Where: - base_time: Time to cover segment based on Z2 pace and elevation adjustments - terrain_factor: TEF from terrain model (≥ 1.0) - fatigue_multiplier: Separate fatigue penalty based on cumulative effort

Terrain Types and Baseline Factors

RaceCraft includes 7 terrain types with scientifically-derived baseline multipliers:

Terrain Type Factor Description Example
Road/Track 0.95× Paved or groomed surfaces Roads, athletics tracks
Smooth Trail 1.00× Ideal baseline trail Well-maintained singletrack, fire roads
Dirt Road 1.05× Unpaved roads, double track Jeep trails, dirt roads
Rocky Runnable 1.15× Rocky but continuously runnable Alpine trails with rock gardens
Technical Trail 1.33× Roots, rocks requiring care Typical technical singletrack
Very Technical 1.65× Hands-on-knees terrain Steep rock sections, major obstacles
Scrambling 2.00× Unstable footing, route-finding Talus fields, boulder scrambles

Factor Interpretation

A terrain factor of 1.33× means the terrain makes you 33% slower compared to smooth trail at the same gradient and effort level. For example: - Smooth trail at 6:00/km → Technical trail at 7:58/km - This is before gradient effects or skill adjustments

Gradient Scaling

Terrain effects become more pronounced on steeper terrain. The model applies gradient scaling:

effective_terrain_factor = terrain_factor × (1 + γ × |gradient|)

Where: - γ (gamma): Gradient scaling coefficient = 1.25 - gradient: Net grade as decimal (e.g., 0.10 = 10% grade)

Example

Technical trail (base factor 1.33×) on 10% grade:

effective_factor = 1.33 × (1 + 1.25 × 0.10)
                = 1.33 × 1.125
                = 1.496×

The terrain penalty increases from 33% to 49.6% due to the steep grade.

Rationale

Steeper terrain amplifies technical difficulty because: - Uphill: Harder to maintain line, more precise foot placement needed - Downhill: Greater braking forces, more consequence for missteps - Both: Reduced margin for error increases time cost of obstacles

Climb vs Descent Differential

Terrain affects descents more severely than climbs:

  • Descents: 100% terrain effect
  • Climbs: 70% terrain effect

This reflects the reality that: - Descending technical terrain requires constant braking and precise foot placement - Ascending technical terrain allows more careful, deliberate movement - Downhill speed amplifies consequences of mistakes

Example

Very technical terrain (1.65× base factor): - On descent: Full 1.65× penalty applied - On climb: Only 1.455× penalty (70% effect)

The formula:

if is_descent:
    direction_adjusted = 1 + (scaled_factor - 1) × 1.0
else:  # climb
    direction_adjusted = 1 + (scaled_factor - 1) × 0.7

Technical Skill Adjustment

Athletes with better technical skills navigate difficult terrain faster. The skill parameter ranges from 0 (novice) to 1 (expert):

skill_adjusted_factor = 1 + (direction_adjusted_factor - 1) × (1 - skill)

Skill Levels

Skill Level Value Terrain Penalty Description
Novice 0.0 100% New to trail running
Beginner 0.25 75% Some trail experience
Intermediate 0.5 50% Regular trail runner
Advanced 0.75 25% Experienced technical runner
Expert 1.0 0% Elite mountain/trail runner

Example

Technical trail (1.33× base) with intermediate skill (0.5):

adjusted_factor = 1 + (1.33 - 1) × (1 - 0.5)
                = 1 + 0.33 × 0.5
                = 1.165×

The runner experiences only 16.5% slowdown instead of 33% due to their technical proficiency.

Interpretation

An expert trail runner (skill = 1.0) on technical terrain runs at the same pace as if it were smooth trail - they've mastered the technique so well that terrain no longer slows them down. Meanwhile, a novice (skill = 0.0) experiences the full terrain penalty.

Complete Calculation Flow

The full terrain efficiency factor calculation combines all components:

Step 1: Base Terrain Factor

Select terrain type → get base factor (e.g., Technical Trail = 1.33×)

Step 2: Gradient Scaling

scaled_factor = base_factor × (1 + γ × |gradient|)

Step 3: Descent/Climb Adjustment

if elevation_loss > elevation_gain:
    direction_factor = 1 + (scaled_factor - 1) × 1.0  # descent
else:
    direction_factor = 1 + (scaled_factor - 1) × 0.7  # climb

Step 4: Skill Adjustment

final_factor = 1 + (direction_factor - 1) × (1 - skill_level)

Step 5: Apply to Segment Time

adjusted_time = base_segment_time × final_factor × fatigue_multiplier

Worked Example

Scenario: Technical trail segment - Distance: 5 km - Net elevation: -200m (descent) - Average gradient: -4% - Base pace: 6:00/km (no elevation) - After elevation adjustment: 5:30/km (downhill benefit) - Skill level: Intermediate (0.5) - No fatigue yet (multiplier = 1.0)

Calculation:

  1. Base terrain factor: Technical Trail = 1.33×

  2. Gradient scaling:

    scaled = 1.33 × (1 + 1.25 × 0.04)
           = 1.33 × 1.05
           = 1.397×
    
  3. Descent adjustment (100% effect):

    direction = 1 + (1.397 - 1) × 1.0
              = 1.397×
    
  4. Skill adjustment (intermediate):

    final = 1 + (1.397 - 1) × (1 - 0.5)
          = 1 + 0.397 × 0.5
          = 1.198×
    
  5. Apply to segment:

    base_time = 5 km × 5:30/km = 27:30
    terrain_adjusted = 27:30 × 1.198 = 32:57
    final_pace = 32:57 / 5 km = 6:35/km
    

Result: Despite the downhill advantage (5:30/km elevation-adjusted pace), the technical terrain slows the runner to 6:35/km - slower than their flat pace. A novice runner would be at 7:28/km on the same segment.

Integration with Fatigue Model

The terrain system operates independently of the fatigue model:

Fatigue Calculations (Unchanged)

effort_km = distance + ascent/100 + descent/200
cumulative_effort += segment_effort
if cumulative_effort > FOP:
    fatigue_multiplier = 1 + α × ((E - FOP) / FOP)^β

Combined Effect

final_pace = base_pace × terrain_factor × fatigue_multiplier

Key Point: Terrain difficulty does NOT: - Change when fatigue starts (FOP remains the same) - Affect how fast fatigue accumulates (effort calculation unchanged) - Compound with fatigue exponentially (multipliers are independent)

A runner with 30% terrain penalty and 20% fatigue penalty experiences:

1.30 × 1.20 = 1.56× total slowdown (56% slower than base)

NOT: 50% slower (30% + 20%)

Usage Guidelines

Choosing Terrain Type

Consider the predominant surface and technical demands of each segment:

  • Road/Track: Almost entirely paved, no obstacles
  • Smooth Trail: Well-maintained, minimal obstacles, good footing
  • Dirt Road: Unpaved but wide, minimal technical features
  • Rocky Runnable: Rocks/roots present but continuous running possible
  • Technical Trail: Frequent obstacles requiring focus and adjustment
  • Very Technical: Regular need to use hands, careful foot placement
  • Scrambling: Route-finding, boulder hopping, significant exposure

Setting Skill Level

Be honest about technical ability:

  • Novice: First trail race, limited technical experience
  • Beginner: 1-2 years trail running, comfortable on moderate terrain
  • Intermediate: Regular trail racer, confident on most technical terrain
  • Advanced: Experienced mountain runner, rarely slowed by terrain
  • Expert: Elite level, technical sections are not a limiting factor

Tips for Accuracy

  1. Be conservative early in plan development: Overestimate terrain difficulty for unfamiliar courses
  2. Adjust after reconnaissance: Update terrain types after course preview
  3. Consider conditions: Wet/muddy conditions may warrant upgrading terrain type
  4. Segment appropriately: Break course into segments with similar terrain characteristics
  5. Don't overthink it: Small errors in terrain type have minimal impact on overall plan

Model Validation and Tuning

The terrain factors are derived from: - Field data from trail running studies - Analysis of professional endurance athlete splits - Comparison of road vs trail pace ratios - Trail running community feedback

Adjusting Parameters (Advanced)

If you need to tune the model for your specific conditions, the key parameters in app.py are:

TERRAIN_FACTORS = {
    'road': 0.95,
    'smooth_trail': 1.0,
    'dirt_road': 1.05,
    'rocky_runnable': 1.15,
    'technical': 1.325,
    'very_technical': 1.65,
    'scrambling': 2.0
}

TERRAIN_GRADIENT_GAMMA = 1.25    # How much gradient amplifies terrain
TERRAIN_CLIMB_FACTOR = 0.7       # Terrain effect on climbs (0.0-1.0)
TERRAIN_DESCENT_FACTOR = 1.0     # Terrain effect on descents (0.0-1.0)

Comparison to Old System

The previous system used simple time additions: - Easy (road): -10 seconds/km - Normal: 0 seconds/km - Difficult: +10s/km uphill, +20s/km downhill

Limitations of old system: - Fixed penalties regardless of gradient - No skill adjustment - Only 3 categories - Inconsistent with fatigue model

New system advantages: - Multiplicative (scales with pace and fatigue) - Gradient-aware - Skill-adjustable - 7 detailed terrain types - Mathematically consistent with other penalties - Better represents real-world running biomechanics

See Also

References

The terrain model is based on research and practical experience in: - Mountain and trail running physiology - Trail running pace analysis - Biomechanical studies of running on varied surfaces - Elite athlete training and racing data

For questions or suggestions about the terrain model, please open an issue on the project repository.