Version 1.0 (Beta) - 7/9/26
This document describes National-style track-side files used by Motocross Madness 1:
.asc - 3ds Max / Charityware grid mesh terrain source
.dat - binary National track-path spline
.scn - scene descriptor, lighting, sky cube, and gate scale
.ter - National MakeTerr terrain compile input
.trn - compiled National terrain
These National formats are different from the Supercross / TrackEdit formats
described in docs/MCM1_TRACK_FILE_FORMATS.md. In particular, National .dat
files are spline paths, while Supercross .dat files are fixed 16 x 16
per-cell navigation fields.
The formats below are intended for programmers implementing readers, writers, validators, or conversion tools.
Other links:
Use these links to jump directly to the file format you need:
| Format | Role | Example file |
|---|---|---|
.asc | Height mesh source | tracks/national_test.asc |
.dat | National track-path spline | tracks/national_test.dat |
.scn | Game scene descriptor and lighting | tracks/national_test.scn |
.ter | MakeTerr terrain compile input | tracks/national_test.ter |
.trn | Compiled National terrain | tracks/national_test.trn |
All binary integer and floating-point fields described here are little-endian.
The .scn and .ter files are INI-like text:
Lines are normally CRLF terminated.
Section names are written as [SectionName].
Key/value lines use Key=Value.
Blank lines and semicolon comments are common and should be ignored by
.scn and .ter readers.
The .asc file is a text mesh export. Height readers normally need only the
vertex lines, while exporters commonly write both vertex and face lists.
The .dat and .trn files are binary.
The National world is a 5 x 5 terrain centered in Direct3D space. The following constants are used by common National tooling:
SIZE = 10S = SIZE / 256WO = 1920WO is the Direct3D world-center offset for National tracks:
xxxxxxxxxxWO = TotalTargetWidth * 1.5WO = 1280 * 1.5WO = 1920Authoring tools often store path points in scene coordinates as x and z.
National .dat and .scn files use MCM / Direct3D coordinates.
Editor path point to .dat Direct3D coordinate:
xMAX_X = editor_x / SMAX_Y = -editor_z / S
D3D_X = MAX_X * 3 + WOD3D_Y = 0D3D_Z = MAX_Y * 3 + WOInverse conversion used by the .dat importer:
xxxxxxxxxxMAX_X = (D3D_X - WO) / 3MAX_Y = (D3D_Z - WO) / 3
editor_x = MAX_X * Seditor_z = -MAX_Y * SFor .scn sun lights, 3ds Max-style sun coordinates can be used as an
intermediate:
xxxxxxxxxxMax X = R * cos(elevation) * cos(azimuth)Max Y = -R * cos(elevation) * sin(azimuth)Max Z = R * sin(elevation)Then it writes the Direct3D light position as:
xxxxxxxxxxSCN Position = MaxX * 3 + WO, MaxZ * 3, MaxY * 3 + WOA reader can use DefaultStartPosition as the source for WO when it is
present, then apply the inverse:
xxxxxxxxxxMax X = (D3D_X - WO) / 3Max Y = (D3D_Z - WO) / 3Max Z = D3D_Y / 3.ASC Format - National Height Mesh SourceFORMAT BANNER:
.ASC3ds Max / Charityware Grid mesh export used as the National terrain height source. Example:
tracks/national_test.asc.
National authoring workflows use .asc files as real-height terrain sources.
A square grid can be imported from an existing .asc, edited, and exported as
an .asc that MakeTerr can consume through a .ter file.
Readers should expect a text mesh with a vertex list. Exporters commonly write both a vertex list and a face list.
xxxxxxxxxx
Named Object: "MyGrid"Tri-mesh, Vertices: <N*N> Faces: <(N-1)*(N-1)*2>Vertex list:Vertex 0: X: -128.000000 Y: -128.000000 Z: <height>Vertex 1: X: -127.000000 Y: -128.000000 Z: <height>...Face list:Face 0: A:<i10> B:<i00> C:<i11> AB:1 BC:0 CA:1Smoothing: 2Face 1: A:<i01> B:<i11> C:<i00> AB:1 BC:0 CA:1Smoothing: 2...The blank first line appears in common generated files.
N is the terrain source resolution. National .trn compilers ultimately use a
257 x 257 center height grid.
ASC readers should accept any square grid with at least 4 vertices:
xxxxxxxxxxvertex_count >= 4N = round(sqrt(vertex_count))require N * N == vertex_countThe writer emits vertices in row-major order:
xxxxxxxxxxfor r in 0..N-1: Y = -128 + r * (256 / (N - 1)) for c in 0..N-1: X = -128 + c * (256 / (N - 1)) Z = terrain heightVertex index:
xxxxxxxxxxvertex_index = r * N + cReaders can identify vertex lines with this pattern:
xxxxxxxxxxVertex <number>: X: <float> Y: <float> Z: <float>Only the numeric X, Y, and Z values are used. The vertex number is not
used to reorder vertices; order in the file is the source of truth.
For a raster-derived heightmap, an exporter can convert authoring units back to ASC / Max units with:
xxxxxxxxxxS = SIZE / 256Z = (baseLum * heightScale + sculptDelta) / SFor an imported .asc, an exporter can preserve imported scale metadata:
xxxxxxxxxxZ = (ascHeights + ascEdge + sculptDelta) / ascScaleSome importers set ascEdge = 0, keeping imported heights exactly apart from
uniform scale into authoring units.
The .asc file lists rows from Y = -128 to Y = 128. Authoring tools may
flip rows north/south into their internal height arrays:
xxxxxxxxxxeditor_index = (N - 1 - r) * N + ceditor_height = asc_Z * scaleOn export, the row order should be flipped back consistently if the internal height array uses the opposite north/south orientation.
When importing, a reader can compute one uniform scale from the X span:
xxxxxxxxxxhoriz = max(1e-6, x_max - x_min)scale = SIZE / horizThat same scale is applied to X/Y/Z semantics by storing:
xxxxxxxxxxeditor_height = asc_Z * scaleImporters may retain X/Y bounds as metadata. Common exporters emit the standard
-128..128 grid.
ASC exporters commonly emit two triangles for each grid cell:
xxxxxxxxxxi00 = r * N + ci01 = r * N + c + 1i10 = (r + 1) * N + ci11 = (r + 1) * N + c + 1
Face A: A=i10 B=i00 C=i11 AB:1 BC:0 CA:1Face B: A=i01 B=i11 C=i00 AB:1 BC:0 CA:1Smoothing: 2Terrain importers may ignore the face list and reconstruct terrain from the ordered vertex grid only.
.ASC Reader BehaviorA typical .asc terrain reader:
extracts all Vertex ... X ... Y ... Z ... lines
requires the vertex count to form a square grid
computes min/max X, Y, and Z
computes a uniform scale from the X extent
flips rows north/south into internal terrain order, if needed
uses the scaled Z values as source-of-truth heights
ignores all face records
.TER Format - National MakeTerr InputFORMAT BANNER:
.TERNational MakeTerr terrain compile input. Example:
tracks/national_test.ter.
The .ter file tells National MakeTerr how to assemble ASC height sources and
TGA texture maps into a compiled .trn.
The National 5 x 5 template writes:
xxxxxxxxxx[ElevationData]GridResolutionInFeet=3.0TerrainType=NATIONALTotalElevationFiles=73TotalTextureMapFiles=2TotalTexturePlacements=1TotalTargetWidth=1280TotalTargetBreadth=1280ElevationFormat=ASCElevationDefault=0ElevationAtEdge=<edge elevation>TextureFormat=8ShareTextures=1ShareGeometries=1UpPropagateTextures=1ElevationPath=.\TextureMapPath=.\GridResolutionInFeet
Often 3.0. Other values are valid. For example, 4.0 makes a 256 x 256
center section cover 1024 ft x 1024 ft instead of 768 ft x 768 ft.
Compiled National .trn files store the corresponding scale as:
xxxxxxxxxxtrn_height_scale = GridResolutionInFeet / 256GridResolutionInFeet = trn_height_scale * 256This value controls horizontal terrain scale. It does not change the vertical
Tga2Asc.exe maxheight value.
TerrainType
Use NATIONAL for National tracks. STUNTQUARRY and BAJA are separate
terrain types and use different world layouts.
TotalElevationFiles
Usually 73 for National 5 x 5 terrain.
TotalTextureMapFiles
Usually 2:
texture.tga for the main center terrain texture
tile.tga for the perimeter / edge tile texture
TotalTexturePlacements
Usually 1 for National 5 x 5 terrain. Only the main 1016 x 1016 texture is
placed explicitly; the perimeter tile is referenced as a texture map file for
MakeTerr's edge handling.
TotalTargetWidth, TotalTargetBreadth
Usually 1280 and 1280. This is the 5 x 5 National target measured in
terrain grid units:
xxxxxxxxxx5 center/perimeter cells * 256 grids = 1280ElevationAtEdge
Elevation value at the terrain edge. Some exporters use the mean elevation around the current terrain edge; others use a manual National edge elevation value.
ElevationPath, TextureMapPath
Often local folder paths:
xxxxxxxxxx.\xxxxxxxxxx[TerrainPalette]TotalFileSets=2NumberOfColors=256FileSet_1=.\tile.tgaFileSet_2=.\texturea.tgaThe embedded template includes historical absolute paths, but buildTerFile
strips those down to local file names:
xxxxxxxxxxFileSet_N=<anything>\<file> -> FileSet_N=.\<file>Some exporters normalize texture names to lowercase texturea.tga,
texture.tga, tilea.tga, and tile.tga.
xxxxxxxxxx[TextureMapFile_1]Name=texture.tgaCoverageInGrids=256PixelsPerGrid=4
[TextureMapFile_2]Name=tile.tgaCoverageInGrids=16PixelsPerGrid=4TextureMapFile_1 is the main exported terrain texture. The export bundle also
includes texturea.tga, the smaller palette source named by [TerrainPalette].
TextureMapFile_2 is the National perimeter tile. The export bundle also
includes tilea.tga, the smaller palette source named by [TerrainPalette].
The National 5 x 5 template contains one texture placement:
xxxxxxxxxx[TexturePlacement_1]MapId=1XIndex=512YIndex=512Transform=NONEThis places the main terrain texture over the center 256 x 256 grid area of the 1280 x 1280 target.
The National template contains 73 elevation sections:
xxxxxxxxxxElevationFile_1..36 outer edge / flat quarry surroundElevationFile_37..40 corner transition piecesElevationFile_41..64 side transition strips with ForceEdgesElevationFile_65..73 3 x 3 center terrain referencesAll elevation sections use INI keys:
xxxxxxxxxx[ElevationFile_N]Width=<grid width>Breadth=<grid breadth>BaseX=<target grid x>BaseY=<target grid y>Name=<asc file>Base=<base elevation>VerticalMultiplier=<scale>ForceEdges=<optional edge flags>The outer surround references stock quarry ASC files that must be available
next to the .ter when using external MakeTerr:
xxxxxxxxxxquarryF.ascquarrySW.ascquarrySE.ascquarryNW.ascquarryNE.ascquarryS.ascquarryN.ascquarryW.ascquarryE.ascMost outer sections are 128 x 128:
xxxxxxxxxxWidth=128Breadth=128Base=<usually 15.0>VerticalMultiplier=1.5Side transition strips include ForceEdges:
xxxxxxxxxxForceEdges=NForceEdges=SForceEdges=EForceEdges=WThe 3 x 3 center terrain sections reference the exported terrain ASC. Template
files often use grid.asc as a placeholder, which should be replaced with:
xxxxxxxxxx<baseName>.ascThe center sections are:
xxxxxxxxxxElevationFile_65..73Each center section is 256 x 256 and uses ForceEdges=NSEW:
xxxxxxxxxx[ElevationFile_69]Width=256Breadth=256BaseX=512BaseY=512Name=<baseName>.ascBase=<asc edge base>VerticalMultiplier=1.0ForceEdges=NSEWElevationFile_69 is the actual center 1 x 1 chunk where the track resides.
Its VerticalMultiplier remains 1.0.
The surrounding eight center references reuse the same ASC with different
VerticalMultiplier values from the template. These provide blended terrain
around the playable center:
xxxxxxxxxx65: BaseX=256 BaseY=256 VerticalMultiplier=-0.39899966: BaseX=512 BaseY=256 VerticalMultiplier=0.45086867: BaseX=768 BaseY=256 VerticalMultiplier=-0.24535768: BaseX=256 BaseY=512 VerticalMultiplier=0.14699269: BaseX=512 BaseY=512 VerticalMultiplier=1.070: BaseX=768 BaseY=512 VerticalMultiplier=0.36800771: BaseX=256 BaseY=768 VerticalMultiplier=-0.31610272: BaseX=512 BaseY=768 VerticalMultiplier=-0.31976773: BaseX=768 BaseY=768 VerticalMultiplier=0.416770An exporter may compute an ASC edge base:
xxxxxxxxxxascEdgeBase = ascMeta.edge / ascMeta.scaleIf no separate edge metadata is available, this is commonly 0.00000.
For National 5 x 5 .ter output, replace the template center base value:
xxxxxxxxxxBase=6.45742... -> Base=<ascEdgeBase>This changes the nine center ASC references while leaving the stock outer quarry/surround base values intact.
Tga2Asc.exe converts a grayscale TGA to ASC heights using a maxheight
argument. From the FireRoad sample:
xxxxxxxxxxASC_Z = gray * maxheight / 255The sample FireRoadNatDispMap257g.tga and .asc were created with:
xxxxxxxxxxmaxheight = 25 ftMakeTerr then compiles ASC heights into TRN raw heights using the center
section Base value:
xxxxxxxxxxraw_height = round(256 * (ASC_Z - Base) + 3840)ASC_Z = Base + ((raw_height - 3840) / 256)The original TGA's darkest usable gray is not stored directly in the .trn.
Many combinations of TGA gray range, Tga2Asc.exe maxheight, and .ter Base
can compile to the same raw TRN heights.
For extraction tools, a practical workflow is to choose an editable darkest
gray target, commonly around 50..58, then solve for a matching Base and
maxheight. Using a target gray of 55 on FireRoad gives:
xxxxxxxxxxBase ~= 5.39Tga2Asc maxheight = 25This is close to FireRoad's known center Base=5.41 and keeps the extracted
TGA out of the too-dark-to-edit range.
.TER Reader Behavior.ter readers should treat the file as MakeTerr source data: parse the
[ElevationData] header, terrain palette, texture map files, texture
placements, and elevation file sections. A .ter alone is not enough to
reconstruct all game-side data; referenced ASC and TGA assets are required.
.SCN FormatFORMAT BANNER:
.SCNNational scene descriptor that tells MCM1 which compiled terrain file to load and configures the lighting, sky cube, and start gate scale. Example:
tracks/national_test.scn.
The .scn file is INI-like text. National scene files normally use a fuller
scene descriptor than the minimal Supercross form.
xxxxxxxxxx; MCM scene file[SceneInfo]SceneName=<track name>LogProgress=FDefaultStartPosition=1920.0,100.0,1920.0DefaultStartDirection=0.0,0.0,1.0
[Environment]TerrainFile=<baseName>.trnCubeFile=<sky cube>ParticleTextureMapName=particles\track02p.tgaStartGateScale=<float>
[Lights]NumberOfLights=2
[Light1]Type=AmbientColorRGB=<r>,<g>,<b>
[Light2]Type=ObjectPointColorRGB=<r>,<g>,<b>Position=<x>,<y>,<z>TargetPosition=0.0,0.0,0.0PlaceLightAtInfinity=TCastsShadows=TEmitsLight=THasLensFlare=F
[Fog]ColorRGB=130,130,190
[Sounds]CrowdPresent=FSceneName
Human-readable track name. Exporters commonly use either the authoring UI track name or the sanitized file base name.
DefaultStartPosition
Direct3D world start position. For National tracks the generated value is:
xxxxxxxxxx1920.0,100.0,1920.0Readers can use the first component as the world-center offset when converting imported light positions back to authoring controls.
DefaultStartDirection
Generated as:
xxxxxxxxxx0.0,0.0,1.0TerrainFile
Compiled terrain file loaded by the game:
xxxxxxxxxx<baseName>.trnCubeFile
Sky / horizon cube. Readers can normalize this value to a known sky-cube list when a case-insensitive match exists. Otherwise, keep the imported string.
ParticleTextureMapName
Generated as:
xxxxxxxxxxparticles\track02p.tgaStartGateScale
Floating-point start gate scale.
Light1
Ambient light. Readers can find the first [LightN] where Type=Ambient and
read ColorRGB.
Light2
Sun / key light. Readers can use the first non-ambient [LightN] with a
Position key, reading Position and ColorRGB.
Fog
Common generated files use this fog color:
xxxxxxxxxx130,130,190Sounds
Common generated files use:
xxxxxxxxxxCrowdPresent=F.SCN Reader BehaviorA typical .scn reader:
parses INI sections and key/value pairs
ignores blank lines and semicolon comments
reads ambient color from Type=Ambient
reads sun color and sun position from the first non-ambient light with
Position
reads DefaultStartPosition to recover the world-center offset
reads StartGateScale
reads CubeFile
.DAT Format - National Track-Path SplineFORMAT BANNER:
.DATBinary National track-path spline. Example:
tracks/national_test.dat.
The National .dat file is a variable-length list of path control points. It is
not the Supercross 16 x 16 navigation field.
xxxxxxxxxx4 + (point_count * 20) bytesReaders should require the file size to match exactly.
xxxxxxxxxxoffset size type field0x0000 4 u32 point_countpoint_count must be at least 2. Readers should reject unreasonable values
such as counts greater than 100000 as a sanity guard.
After the 4-byte header, there are point_count records. Each record is 20
bytes:
xxxxxxxxxxoffset size type field+0 4 f32 D3D_X+4 4 f32 D3D_Y+8 4 f32 D3D_Z+12 4 f32 width+16 4 u32 typeD3D_X, D3D_Y, D3D_Z
Direct3D-space control point position. National path writers commonly emit
D3D_Y = 0.
width
Full track/path width in Direct3D units. If an authoring tool stores each node width as a half-width, export doubles it:
xxxxxxxxxxwidth = editor_half_width * 6 / SA reader can convert the full width back to authoring half-width:
xxxxxxxxxxeditor_half_width = max(0.03, (width / 3) * S * 0.5)type
Common writers emit:
xxxxxxxxxx0 for the first point2 for all later pointsReaders may ignore this field beyond validating the record size.
xxxxxxxxxxwrite_u32_le(point_count)
for i in 0..point_count-1: MAX_X = point[i].x / S MAX_Y = -point[i].z / S width = point[i].half_width
write_f32_le(MAX_X * 3 + WO) write_f32_le(0) write_f32_le(MAX_Y * 3 + WO) write_f32_le(width * 6 / S) write_u32_le(i == 0 ? 0 : 2)xxxxxxxxxxpoint_count = read_u32_le()require point_count >= 2require file_size == 4 + point_count * 20
for i in 0..point_count-1: D3D_X = read_f32_le() D3D_Y = read_f32_le() D3D_Z = read_f32_le() width = read_f32_le() type = read_u32_le()
MAX_X = (D3D_X - WO) / 3 MAX_Y = (D3D_Z - WO) / 3
point.x = MAX_X * S point.z = -MAX_Y * S point.half_width = max(0.03, (width / 3) * S * 0.5)National spline paths are usually treated as closed loops by authoring tools.
.TRN Format - National TerrainFORMAT BANNER:
.TRNCompiled National terrain. Example:
tracks/national_test.trn.
National .trn files contain terrain patches, palette and lookup data, texture
tiles, and a tail / quadtree used for culling and LOD.
xxxxxxxxxxoffset size type field0x0000 4 char[4] "TRN\0"0x0004 4 u32 version = 20x0008 4 u32 texture_format = 1When texture_format == 1, a color-mapper section follows the 12-byte header.
xxxxxxxxxxu32 first_color_indexu32 color_countu32 flag
block paletteblock lut_32768block lut_65536Common National writers emit:
xxxxxxxxxxfirst_color_index = 0color_count = quantized color count, usually 256flag = 1Each color-mapper block uses this framing:
xxxxxxxxxxu32 payload_sizepayload bytesThe payload may be raw or MCM LZW-compressed.
Canonical raw payload sizes:
xxxxxxxxxxpalette = 768 bytes 256 * RGBlut_32768 = 32768 byteslut_65536 = 65536 bytesLZW payloads begin with a 4-byte little-endian subheader equal to the compressed payload length. The bitstream uses these control codes:
xxxxxxxxxxLZW_END = 256LZW_INC = 257LZW_CLR = 258LZW_FIRST = 259LZW_MAX = 0x7FFFThe initial code width is 9 bits. LZW_INC increases the code width.
LZW_CLR clears the dictionary and resets the width to 9 bits. LZW_END
terminates the stream.
After the color mapper, the parser expects a patch-list header:
xxxxxxxxxxu32 unknown_0u32 unknown_1u32 patch_countu32 patch_offsets[patch_count]The parser then walks patch data sequentially. Each patch contains three spans:
xxxxxxxxxxfor patch in 0..patch_count-1: for span in 0..2: u32 stored_size u32 raw_size bytes payload[stored_size or raw_size]Compression is detected per span:
xxxxxxxxxxcompressed = stored_size < raw_sizeIf compressed, the payload is decoded as an MCM LZW stream. If not compressed, the raw payload bytes are used directly.
Known National terrain files use these height-grid constants:
xxxxxxxxxxN = 257MAIN0 = 594SKIRT = 3840The playable center terrain is a 257 x 257 height grid divided into 256 patches:
xxxxxxxxxx16 x 16 patch grid17 x 17 vertices per patchFor the embedded Nation24 scaffold, the center patch indexes are:
xxxxxxxxxxpatch indexes MAIN0..MAIN0+255patch indexes 594..849However, arbitrary compiled National .trn files do not have to use those
fixed patch indexes. Observed examples:
xxxxxxxxxxFireRoad.trn patch_count = 858, center patches 594..849BaatKips_SX2K.trn patch_count = 346, center patches 86..341Readers should locate the center terrain through the tail / quadtree leaf patch
references instead of assuming MAIN0=594.
When fixed MAIN0 indexing is known to apply, patch grid mapping is:
xxxxxxxxxxlocal_patch = patch_index - MAIN0patch_col = local_patch % 16patch_row = floor(local_patch / 16)
grid_x = patch_col * 16grid_y = patch_row * 16Span 2 of each center patch contains the height and normal records used to reconstruct or modify the center terrain.
The tail / quadtree contains leaf records with world-grid coordinates and patch references. For extraction tools:
locate tailStart after the texture section
recursively walk quadtree nodes from the root node at tailStart
follow child-table offsets when present
collect leaves with their ox, oy, and patch index fields
find the 16 x 16 block of leaves covering a 256 x 256 center section
sort the selected leaves by oy, then ox, to rebuild the 16 x 16 patch grid
The quadtree leaf fields needed for center-patch discovery are:
xxxxxxxxxxoffset size type field+28 4 u32 ox, leaf X grid coordinate+32 4 u32 oy, leaf Y grid coordinate+40 4 u32 patch index+56 4 u32 child table offset, or 0 for leafThe selected center block can be offset by one 16-cell patch from the logical center. Observed examples:
xxxxxxxxxxFireRoad.trn center block origin = 496,496BaatKips_SX2K.trn center block origin = 512,512This matters for extraction orientation. A display/export tool may need to apply a cyclic 16-pixel patch-edge wrap derived from the block origin rather than applying the same wrap to every track.
Decoded span 2 for a center patch contains 17 x 17 vertex records. Each record is 16 bytes:
xxxxxxxxxxoffset size type field+0 2 bytes inherited template data+2 2 u16 encoded_height+4 4 f32 normal_x+8 4 f32 normal_y+12 4 f32 normal_zTerrain writers update encoded_height and the three normal fields.
Terrain writers resample source terrain to 257 x 257. One common encoding strategy finds the minimum height and uses the floor of that value as the terrain base:
xxxxxxxxxxbase = floor(min_height)Each height is encoded as:
xxxxxxxxxxencoded_height = round(256 * (Z - base) + SKIRT)encoded_height = clamp(encoded_height, 0, 65535)Writers must keep patch-grid orientation consistent with their source height array. Existing files may require orientation correction when extracting a TGA for image editing.
For tools reading an existing .trn, the raw height values can
be converted back to feet with:
xxxxxxxxxxASC_Z = Base + ((raw_height - 3840) / 256)The .trn does not store the original .ter Base plainly. If the original
.ter is unavailable, extraction tools must choose a reconstruction Base.
One practical approach is to target a darkest editable TGA gray value, such as
55, then solve for a matching Base and suggested Tga2Asc.exe maxheight.
Decoded TRN patch order is not always the same orientation as a TGA shown in a normal image editor. For FireRoad-style extraction, a useful default is:
xxxxxxxxxxdefault orientation = flip verticalThen it applies a quadtree-derived cyclic patch wrap when the selected center
block is offset from 512,512:
xxxxxxxxxxwrap_x = (512 - center_block_x) mod 257wrap_y = (center_block_y - 512) mod 257Observed examples:
xxxxxxxxxxFireRoad center block 496,496 wrap_x=16, wrap_y=241BaatKips center block 512,512 wrap_x=0, wrap_y=0The wrap is an extraction/display correction. It should be derived per track; applying FireRoad's wrap to every National TRN misaligns tracks such as BaatKips.
Normals are computed from the 257 x 257 height grid using neighbor samples:
xxxxxxxxxxdx = (height[x+1, y] - height[x-1, y]) * 0.5dy = (height[x, y+1] - height[x, y-1]) * 0.5
normal = normalize(-dx, 1, -dy)Edges clamp to the nearest valid grid coordinate.
After the patch data, the texture block has this observed National layout:
xxxxxxxxxxu32 K = 16u32 G = 1
u32 perimeter_width = 64u32 perimeter_height = 64u32 inherited_perimeter_fieldu8 perimeter_indices[64 * 64]u8 perimeter_mip[32 * 32]
u32 main_tile_width = 256u32 main_tile_height = 256u32 inherited_main_fieldu8 main_tiles[16][256 * 256]u8 main_mips[16][128 * 128]The parser names the inherited third texture-header fields g3 and k3. Their
values are read from the template and written back unchanged.
For extraction/display, the reconstructed 4 x 4 1024 x 1024 texture needs a vertical flip to match the source texture orientation shown by common image viewers.
A common texture build pipeline is:
quantizes the main terrain RGB image to the requested color count
builds the 768-byte RGB palette
builds both shade lookup tables
resamples the main terrain texture to 1024 x 1024
flips the main texture vertically
palette-maps it to 8-bit indices
splits it into 16 256 x 256 tiles in a 4 x 4 layout
creates one 128 x 128 mip for each main tile
resamples the perimeter texture to 64 x 64
palette-maps the perimeter texture
creates one 32 x 32 perimeter mip
After replacing color-mapper, patch, and texture data, the tail section may move to a new byte offset. Writers must relocate affected tail pointer locations by the same delta.
The tail walk starts at tailStart. Each node is treated as a 15-field
little-endian u32/i32 structure for the fields relevant to patch discovery and
bounds repair:
xxxxxxxxxxfield 2 bA, signed bounds valuefield 3 bB, signed bounds valuefield 4 dmax / LOD error, left unchangedfield 10 patch index for leaves, or 0xfffffffffield 14 child table offset, or 0When field 14 is non-zero, it points to a 256-entry child table of u32
offsets. Non-zero child offsets are recursively walked and relocated.
The embedded Nation24 scaffold includes quadtree / LOD bounds for the original
terrain. If the new terrain is taller or shorter, stale bounds can cull
polygons incorrectly. Writers can repair bounds after recompiling:
decode span 2 of each center patch
read all 289 encoded_height values
compute each center patch's min and max encoded height
for center-patch leaves, write those exact min/max values to fields bA and
bB
for internal nodes, expand stored bounds to include child bounds
leave dmax unchanged
This operation only expands ancestor bounds. It is intended to reduce incorrect culling without changing the template's LOD behavior.
.TRN Reader BehaviorA .trn reader should:
parse the header and optional color-mapper section
locate the patch table and patch spans
detect raw vs compressed spans
decode compressed spans with MCM LZW
locate texture data and preserve inherited texture header fields
locate the tail / quadtree start
walk selected tail offsets for relocation and bounds patching
read the quadtree recursively
discover the 16 x 16 center patch grid from leaf patch references
reconstruct a 257 x 257 displacement map from span 2 height records
infer .ter GridResolutionInFeet from the TRN scale field
suggest Tga2Asc.exe maxheight and .ter Base from raw height range plus an
editable darkest-gray target
reconstruct the 1024 x 1024 texture from 16 palette-indexed tiles
flip the texture vertically for source-image orientation
Fields not used by known readers or writers remain undocumented here.
A complete National track project may contain:
xxxxxxxxxx<baseName>.scn<baseName>.dat<baseName>.trn<baseName>.asc<baseName>.ter<baseName>.tgatexture.tgatexturea.tgatile.tgatilea.tgaREADME.txtThe game-file subset is:
xxxxxxxxxx<baseName>.scn<baseName>.dat<baseName>.trn<baseName>.tgaThe .asc, .ter, texture*.tga, and tile*.tga files are MakeTerr source
assets. The game-file subset is what MCM1 needs at runtime.
National terrain can be built through the National MakeTerr workflow using a
National .ter file and referenced ASC/TGA assets:
xxxxxxxxxxheight source + texture images -> 257 x 257 ASC-style height grid -> 1024 x 1024 indexed texture tiles -> compiled National TRNThe National .trn format is not interchangeable with the Supercross /
TrackEdit .trn format. Supercross uses a different terrain type, different
height encoding, different patch counts, and a different .dat format.
The historical National track workflow used several small tools and 3D Studio Max plug-ins. These tools are useful when rebuilding terrain externally or working with original National authoring assets.
| Tool | Role |
|---|---|
| MakeTerr.exe | Terrain compiler. Consumes .ter plus referenced .asc and .tga assets and produces .trn. This is the same program that ships with MCM 1.0 in the ...\trakedit directory. |
| MakeCub.exe | Creates sky .cub files referenced by .scn CubeFile=. |
| TerGen.exe | Creates skeleton .ter files. |
| Tga2Asc.exe | Creates an .asc height mesh from a .tga image. |
| TrackConvert.exe | Creates National .dat spline path files from .txt files. |
| TrackBastard.dlo | 3D Studio Max plug-in for making spline paths. Place the .dlo in ...\3dsMax2\plugins. |
| msvcrtd.dll | Microsoft runtime DLL required by TrackBastard.dlo. Historically placed in ...\windows\system. |
| Grid.zip | Charityware Grid plug-in for 3D Studio Max, used for grid terrain authoring/export. |