Adrenaline Icon

TrackLang: Language Reference

Complete TrackLang syntax reference. TrackLang is a declarative language for defining motocross tracks with precise geometry, timing zones, and camera positions. This reference covers all keywords, feature types, properties, and positioning syntax.

Basic Syntax

Comments

# This is a comment
# Comments start with # and continue to end of line

Structure

TrackLang files consist of one track declaration containing multiple feature declarations:

track <trackname> {
  # Track properties
  name = "Display Name"
  width = 10
  circuit = true
  
  # Feature declarations
  feature <location> <type> <key> { ... }
  feature <location> <type> <key> { ... }
}

Track Declaration

Every TrackLang file must have exactly one track declaration. Only one track is supported per file.

Syntax

track <trackname> {
  name = <string>      # Display name (optional)
  width = <number>     # Default track width in meters (optional)
  circuit = <boolean>  # true for closed circuits, false for point-to-point (optional)
}

Properties

  • trackname: Identifier used in feature locators (e.g., mx1, track_a)
  • name: Human-readable display name (e.g., "Glen Helen National")
  • width: Default track width in meters, applies to all features unless overridden
  • circuit: true for loop tracks, false for linear tracks

Example

track mx1 {
  name = "Thunder Valley MX"
  width = 12
  circuit = true
}

Feature Declaration

Features are track elements like turns, jumps, slopes, and the finish line. Each feature has a location, type, and properties.

Syntax

feature <trackkey>@<location> <type> <key> {
  name = <string>          # Optional display name
  length = <number>        # Feature length in meters (calculated for turns)
  
  # Feature-specific properties
  entry { ... }            # Entry characteristics
  apex { ... }             # Middle/peak characteristics (or "middle")
  exit { ... }             # Exit characteristics
}

Location Syntax

Features can be positioned absolutely or relative to other features:

  • Absolute: trackname@100 - 100 meters from track start
  • Relative: trackname@featurekey+50 - 50 meters after the end of another feature
feature mx1@0 finish start { }           # At the very start
feature mx1@100 turn first_turn { }      # 100m from start
feature mx1@first_turn+20 jump whoops { }  # 20m after first_turn ends

Location Validation

The system detects overlapping features and warns about conflicts. Features placed at the same location or overlapping in distance will trigger console warnings.

Feature Types

finish

Marks the finish line location. Always has a length of 1 meter.

feature mx1@0 finish start {
  name = "Start/Finish Line"
}

turn | right_turn | left_turn

Defines a turning section. Use turn with direction property, or use right_turn/left_turn directly.

Special properties:

  • direction = right or left (optional if using typed turn)
  • radius = <number> - Turn radius in meters
  • angle = <number> - Turn angle in degrees

Length is automatically calculated: length = radius × 2 × π

feature mx1@100 turn first_turn {
  name = "Turn 1"
  direction = right
  radius = 15
  angle = 90
  
  entry {
    width = 12
    centerHeight = 0
  }
  apex {
    radius = 15      # Centerline radius
    width = 10
  }
  exit {
    angle = 90       # Degrees of rotation
    width = 12
  }
}

# Or use typed turn:
feature mx1@200 right_turn sweeper {
  radius = 20
  angle = 45
}

jump

Defines a jump feature with takeoff, peak, and landing.

Apex special properties for jumps:

  • entryCenterHeight, entryLeftHeight, entryRightHeight - Takeoff heights
  • exitCenterHeight, exitLeftHeight, exitRightHeight - Landing heights
  • length - Distance from takeoff to landing
feature mx1@300 jump triple {
  name = "Triple Jump"
  length = 25
  
  entry {
    length = 5
    centerHeight = 0
  }
  apex {
    length = 15
    entryCenterHeight = 3    # 3m high takeoff
    exitCenterHeight = 0     # Land at ground level
    entryLeftHeight = 3
    entryRightHeight = 3
    exitLeftHeight = 0
    exitRightHeight = 0
  }
  exit {
    length = 5
    centerHeight = 0
  }
}

slope

Defines an uphill or downhill section.

feature mx1@400 slope uphill {
  name = "Uphill Section"
  length = 30
  
  entry {
    centerHeight = 0
    length = 5
  }
  apex {
    centerHeight = 10    # 10m elevation gain
    length = 20
  }
  exit {
    centerHeight = 10
    length = 5
  }
}

Feature Subsections

Most features have three subsections: entry, apex (or middle), and exit. These define how the track transitions into, through, and out of the feature.

Common Properties

All subsections support these properties:

  • length: Length of this subsection in meters
  • width: Track width in meters (inherits from track if not specified)
  • height or centerHeight: Elevation at track center in meters
  • leftHeight: Elevation at left edge in meters
  • rightHeight: Elevation at right edge in meters
  • relativeLocation: Position within the feature (advanced)

Property Inheritance

Properties inherit from previous sections if not specified:

entry {
  centerHeight = 0    # Explicitly set
  width = 12          # Explicitly set
}
apex {
  centerHeight = 5    # Override: different from entry
  # width inherits from entry (12)
}
exit {
  # centerHeight inherits from apex (5)
  # width inherits from apex which inherited from entry (12)
}

Tip: You only need to specify properties that change. Omitted properties inherit from the previous subsection or track defaults.

Complete Example

A simple motocross track with a finish line, turn, jump, and slope:

track mx1 {
  name = "Example MX Track"
  width = 12
  circuit = true
}

# Start/finish line at the very beginning
feature mx1@0 finish start {
  name = "Start/Finish"
}

# First turn at 100 meters
feature mx1@100 right_turn turn1 {
  name = "Turn 1"
  radius = 15
  angle = 90
  
  entry {
    width = 12
    centerHeight = 0
  }
  apex {
    width = 10
  }
  exit {
    width = 12
  }
}

# Jump 20 meters after turn1 ends
feature mx1@turn1+20 jump double {
  name = "Double Jump"
  
  entry {
    length = 5
    centerHeight = 0
  }
  apex {
    length = 10
    entryCenterHeight = 2.5
    exitCenterHeight = 0
  }
  exit {
    length = 5
    centerHeight = 0
  }
}

# Uphill section 30 meters after jump
feature mx1@double+30 slope uphill {
  name = "Uphill Climb"
  
  entry {
    centerHeight = 0
    length = 5
  }
  apex {
    centerHeight = 8
    length = 25
  }
  exit {
    centerHeight = 8
    length = 5
  }
}

# Left turn at top of hill
feature mx1@uphill+10 left_turn turn2 {
  name = "Turn 2"
  radius = 12
  angle = 120
  
  entry {
    centerHeight = 8  # Maintain elevation from slope
  }
  apex {
    centerHeight = 8
  }
  exit {
    centerHeight = 8
  }
}

Best Practices

  • Use descriptive keys: first_turn, whoops_section, not f1, ws
  • Prefer relative positioning: Use @featurekey+distance instead of absolute distances for easier editing
  • Comment your code: Explain complex features or unusual measurements
  • Start with finish: Always declare finish line first at @0
  • Use realistic measurements: Track widths typically 10-15m, jump heights 2-4m, turn radii 10-30m
  • Specify only what changes: Let properties inherit when possible to keep code clean
  • Test frequently: Click "Run" often to catch errors early
  • Validate with ad-hoc races: 3D visualization doesn't guarantee timing accuracy

Common Errors

Circular References

Error: Circular reference: featureA -> featureB -> featureA

Cause: Feature A's location depends on Feature B, but Feature B's location depends on Feature A.

Fix: Use absolute positioning for one of the features.

Overlapping Features

Warning: featureA @ 100 overlaps with featureB @ 95-120

Cause: Two features occupy the same track distance.

Fix: Adjust locations or lengths to avoid overlap. Check if you're using the right reference feature for relative positioning.

Multiple Tracks

Error: Only one track support at a time

Cause: More than one track declaration in the file.

Fix: TrackLang currently supports one track per file. Remove extra track declarations.

Missing Track Declaration

Error: No matching tracks detected with name [trackname]

Cause: No track keyword found, or trackname mismatch.

Fix: Ensure you have track trackname { ... } declaration, and that feature locators match the trackname.

Reserved Keywords

The following keywords are reserved and have special meaning in TrackLang:

Top-Level

  • track
  • feature

Feature Types

  • finish
  • turn
  • right_turn
  • left_turn
  • jump
  • slope

Subsections

  • entry
  • apex
  • middle (alias for apex)
  • exit

Properties

  • name
  • length
  • width
  • height
  • centerHeight
  • leftHeight
  • rightHeight
  • circuit
  • direction
  • radius
  • angle
  • relativeLocation

Jump-Specific

  • entryCenterHeight
  • entryLeftHeight
  • entryRightHeight
  • exitCenterHeight
  • exitLeftHeight
  • exitRightHeight

Values

  • true
  • false
  • right
  • left

Common Questions

Can I define my own feature types?

Not currently. TrackLang supports only the built-in feature types: finish, turn, jump, and slope.

What units are used for measurements?

All measurements are in meters (distances, widths, heights) and degrees (angles).

Can features have the same key?

No. Each feature key must be unique within a track. Duplicate keys will cause unpredictable behavior.

What's the difference between apex and middle?

They're the same—middle is an alias for apex. Use whichever reads better for your feature.

Can I nest features?

No. Features are flat—they cannot contain other features. Use overlapping locations if you need features at the same position (e.g., a jump on a turn).

How do I define cameras or timing zones?

Camera and timing zone support in TrackLang is coming in a future version. Currently, these are configured separately from TrackLang code.

What's the maximum track length?

There's no hard limit, but tracks over 10km may have performance issues in 3D rendering. Typical MX tracks are 1-3km.

Related Topics

Tags
trackdevelopmenttracklangreferencesyntax

Was this information useful?

Help us improve our documentation by rating this article and sharing your feedback.