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:
truefor loop tracks,falsefor 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 endsLocation 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 = rightorleft(optional if using typed turn)radius = <number>- Turn radius in metersangle = <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 heightsexitCenterHeight,exitLeftHeight,exitRightHeight- Landing heightslength- 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, notf1,ws - Prefer relative positioning: Use
@featurekey+distanceinstead 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
trackfeature
Feature Types
finishturnright_turnleft_turnjumpslope
Subsections
entryapexmiddle(alias for apex)exit
Properties
namelengthwidthheightcenterHeightleftHeightrightHeightcircuitdirectionradiusanglerelativeLocation
Jump-Specific
entryCenterHeightentryLeftHeightentryRightHeightexitCenterHeightexitLeftHeightexitRightHeight
Values
truefalserightleft
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
- TrackLang: Getting Started - Introduction and workflows
- Setting Up Cameras - Camera configuration for AI Vision
- Running Ad-Hoc Races - Testing tracks before live events
Was this information useful?
Help us improve our documentation by rating this article and sharing your feedback.