LEX (File Format)

From Custom Mario Kart
(Redirected from LEX)
Jump to navigation Jump to search

LEX (short for LE-CODE Extension) is a file format defined by Wiimm. A LEX file is usually stored as part of a track SZS under the name course.lex. It is similar to the KMP's course.kmp file, but it provides additional settings and modifications not covered by the KMP. The purpose is to override global game functions with individual functions for each track.

LEX files are designed to be open for future extension by third persons. Each new section identifier (a 4 byte ASCII magic) should be requested to Wiimm. He will guarantee unique identifiers.

Currently, only LE-CODE and »Countdown Mode Beta8 Mod« (only section CTDN) support LEX files. Other code executors simply ignore a LEX file, so there is no need to release 2 versions of a track with and without the LEX file.

Design Notes

There were some prerequisites before the definition of the file format:

  • The format should be open for future extensions.
  • Extensions are managed by sections. Each section is identified by an unique ID (magic).
  • ID (magic) should be 4 ASCII characters to make viewing by a hex-dumper easier.
  • Old implementations must work, event if new unknown subtypes were added. Therefore, the code needs an easy skip mechanism.
  • Tools to edit LEX files must be able to handle unknown subtypes as well (not deleting them when saving).
  • The order must be stable to support sections, that depend on other prior defined sections.
  • Fast and easy scanning support.
  • The data of a section should be easy to use for the game extender like LE-CODE.

File Format

Each file starts with a LEX header, followed by a sequence of LEX sections. The chain of sections is closed by a special termination section.

All values are stored in network byte order (big endian). Each section is aligned to 4 bytes.

File header of LEX files
Offset Type Description
0x00 char[4] File magic, always »LE-X«
0x04 uint16 The major version number. Usually 1. It is incremented, if the data structure changes in an incompatible way. This is not expected.
0x06 uint16 The minor version number. It starts with 0 and is incremented, if this header is expanded in a compatible way.
0x08 uint32 Total size of file. Use it for sanity checks.
0x0c uint32 Offset of first section of the chain relative to the beginning of this structure. Usually the value is 0x10, but this may change in future versions.
0x10 End of file header
  • The version number is printed as %u.%u. At the moment it is 1.0.
  • Don't expect the first section of the chain at offset 0x10. Use Offset of first section instead.

The list of sections is managed as chain. The header of each section contains a magic to identify it, and the size of the embedded data:

Section header of LEX files
Offset Type Description
0x00 uint32 A magic to identify the section (type of section). An alternative datatype is char[4].
0x04 uint32 Size of the section data. It is an offset to the next section relative to the data member too. The size is always a multiple of 4.
0x08 u8[SIZE] Binary data of the section.
0x08+SIZE The next section
  • Duplicates of the same section are forbidden.
  • The chain of sections is well ordered. Tools should usually not change this order, except they know exactly what they do.
  • The offset of the next section is: current_offset + 8 + section_size
  • Magic and size of the final section (terminator) are 0.

Example Implementation

For example code in C, see »LEX (File Format)/C example«.


Each section has its own identity (magic). This magic is an integer of 4 bytes. It can be interpreted as 4 characters. So it created by printable ASCII characters. At the moment, the identities are manged by Wiimm to guarantee unique values.

List of defined sections
Identity / Magic Date of
Date of
last update
ASCII uint32
0 2019-02-28 Terminator of chain.
---- 0x2d2d2d2d 2019-02-28 Invalidated section. Ignore it.
FEAT 0x46454154 2022-08-06 2023-06-02 Declare the special features of a track file.
SET1 0x53455431 2020-02-02 2023-06-01 Define various settings.
CANN 0x43414e4e 2019-02-28 Cannon settings.
CTDN 0x4354444e 2023-10-12 Settings for game mode countdown.
HIPT 0x48495054 2020-02-04 Define rules based on lap index and check points to hide the position tracker.
RITP 0x52495450 2023-06-09 Shuffle next-links of KMP:ITPH to allow a random selection of equivalent routes.
TEST 0x54455354 2020-01-10 2020-02-01 Define test settings.
DEV1 0x44455631 2023-07-12 Define various developer settings. Only for LE-CODE developers.

FEAT : Declares the special features

This section declares the special features of a track file. It is available as of v2.28a.beta2 of Wiimms SZS Tools.

The FEAT has been requested by MrBean35000vr, as a first step to allow CTGP Revolution to support some LE-CODE features. The ghost database is problematic here if a property affects the game. Let's take scaled Goombas as an example. In the original game, they are always respawned at a scale factor of 1. LE-CODE restores Goombas with their defined scale. So the impact on the game changed.

Therefore, there is the following implementation for ghost races:

  • If this feature is not declared, then the ghost racing feature remains disabled.
  • If this feature is declared and implemented, then it will be activated. Due to the LEX section, the track has its own SHA1 and its own entry in the ghost database.
  • If at least one feature is declared that is relevant to time trials but not yet implemented, ghost data will be rejected.

This means, right now CTGP will refuse to let you play Time Trials on any track that contains such a FEAT section. In the future, all tracks containing specific LE-CODE features will be updated to include such a section that defines which exact LE-CODE features the track requires. In a future update CTGP will add support for these LE-CODE extensions, and will start allowing you to play time trials only on these tracks where it supports all the used LE-CODE features.

Command and Option support:

  • Command wszst FEATURES prints the feature list to standard output.
  • Command wlect CREATE FEAT creates a LEX template with section FEAT.
  • Patching option --lex-features adds or updates LEX section FEAT if any relevant feature is set.
  • Patching option --lex-rm-features removes LEX section FEAT.

??? technical info

SET1 : Define various settings

Section SET1 defines various settings to modify the behavior of the track.

Data of section »SET1« (ID 0x53455431)
Offset Type Name Description
0x00 float[3] ITEM-POS-FACTOR Define 3 stretch factors (one for each axis) to increase the range for items at the expense of accuracy and therefore to fix the Item Position Bug. The background is, that the online protocol only supports positions for items in the range of ±131071. The default value is v(1,1,1) (no stretch).
0x0c byte START-ITEM Wiimmfi and tool mkw-ana support an automatic ban systems, that detect items before race start. Unfortunately, there are some tracks where players get an item through an item box before race start. And it is precisely these tracks that must be marked with value 1 as an exception to avoid banning.
0x0d byte padding
0x0e short APPLY-ONLINE-SEC If playing online, the racing time is limited. The original MKW uses 5:00 and LE-CODE 5:40 by default. A racing track can apply another online time limit if the value is >0. LPAR settings MIN-ONLINE-SEC and MAX-ONLINE-SEC limit the actually used value.
0x10 End of section

CANN : Cannon properties

This section allows you to change the properties of cannons and even define more than 3 types of cannons. The use of more than 3 types makes a track incompatible for distributions without LE-CODE. So it is not recommended.

Data of section »CANN« (ID 0x43414e4e)
Offset Type Description
0x00 uint32 N = Number of defined cannon types
0x04 float[4] 4 settings for cannon type #0
0x14 float[4] 4 settings for cannon type #1
0x24+ ...
4+N*16 End of section

See »Cannon Characteristics« for details about the properties. See »LE-CODE: Track FAQ« too.

CTDN : Settings for game mode countdown

as of Wiimms SZS Tools v2.39a

Section CTDN defines various settings for game mode countdown. It was a request by user Kazuki.

Data of section »CTDN« (ID 0x4354444e)
Offset Type Name Description
0x00 u16[6] TIME-LIMIT-* Define 6 values for engine based time limits in seconds: battle, 50cc, 100cc, 150cc, 200cc, >200cc. The battle value is not needed here, but was defined in order to have identical vectors for the engine classes in LE-CODE and LEX. Additionally, with 6 values no padding is needed. The default value for all engine classes is 150 seconds.
0x0c End of section

HIPT : Hide position tracker

Hide the position tracker based on online mode, the current lap index and the current checkpoint of the player. Sound on position change is disabled if tracker is hidden.

This section is row based. Each row is a rule of 5 bytes. The total number of rows is determined by dividing the section data size by 5 and rounding down. If a player enters a new check point, the first matching rule is used. Therefore the current mode (offline or online), the current lap index and the index of the current CKPT is compared with the row elements COND, LAP, FROM and TO (see table below). Lap is 0 until crossing the lap counter the first time. This includes the start position.

Place the most specific rules above and more general rules below on the list because of the first-hit search. If no rule matches, the position tracker is shown (like rule 3 99 0 255 1).

Row members of section »HIPT« (ID 0x48495054)
Offset Type Name Description
0x00 uint8 COND This base condition is either 1 for offline only, 2 for online only, or 3 for both cases. Parameter @OFFLINE-ONLINE of section TEST can be used to force a condition for testing (e.g. set @OFFLINE-ONLINE=2 to test the online mode while playing offline).
0x01 int8 LAP This member is compared with the current lap index. Negative values refer to the absolute number of laps: −1 is always the last lap and −2 is the penultimate lap. This means that the setting remains valid if the number of laps (STGI) is changed. The special value 99 means match all laps.
0x02 uint8 FROM FROM and TO build an inclusive range to compare the current check point. Use 0 255 for all check points.
0x03 uint8 TO
0x04 uint8 SHOW This member is either 0 to hide or 1 to show the position tracker. Other values are reserved.
0x05 End of row
  • Track »Test: Hide Pos Tracker« demonstrates the possibilities of HIPT.
  • »Electric Shredder« uses the single rule 2 99 0 255 0 to hide the position tracker during the whole race if playing online.
  • »The Rabbit Hole« uses the single rule 3 0 0 255 0 to hide the position tracker in the start phase before reaching the start line the first time.
  • »N64 Yoshi Valley (zilly)« uses the single rule 3 99 11 52 0 to hide the position tracker in the maze portion (check points 11 to 52).

RITP : Random Item Points

Normally only the first next-link of KMP:ITPH is used for Bullet Bill and Red Shells (except when the shell has already targeted a player). In the case of equivalent routes, however, it would be desirable for one of the possible routes to always be selected at random. It is important to ensure that everyone uses the same route when racing online.

And exactly this can be defined with this section. Therfore you define a list with rules. Each rule defines the index of the ITPH element, the number of next-links affected, and the type of modification. LE-CODE is very robust here and only accepts valid rules on existing elements.

The general rule syntax: INDEX NN MODE [PARAM]

Rule Members
Name Description
INDEX Index of KMP:ITPH entry (0..255).
NN Number of next-links to shuffle (2..6).
MODE How to shuffle (see next table).
PARAM Optional parameter for some modes (see next table).
Rule Modes
Name Description
RITP$OFF Ignore this rule, but store it including PARAM. This mode can be used to temporary deactivate a rule.
RITP$START Select first next-link by random at race start. The selected next-link must be defined (not -1 == not 0xff), otherwise ignore the rule. PARAM is ignored.
? More modes are planned.

ITPH element #10 (zero based index) has defined 3 equivalent routes and 2 additional routes by its next-links. At race start one of the first 3 links should be selected by random as standard route. The rule for this case is:


This rule is ignored by LE-CODE, if the addressed ITPH element does not exists or if the by random selected next-link is not defined.

TEST : Define test settings

Section TEST defines values to test scenarios build by Extended presence flags. The idea is to force different modes so that a single player can test all possible scenarios offline. This test section should only be used during track testing, a finished released custom track should not contain a TEST section in its LEX file. Option --lt-clear of Wiimms SZS Tools remove the test section on creating or patching a track file.

Data of section »TEST« (ID 0x54455354)
Offset Type Name Description
0x00 uint8 OFFLINE-ONLINE If 1: Force offline mode. If 2: Force online mode. Otherwise enable automatic detection.
0x01 uint8 N-OFFLINE If >0: Force number of players at Wii. It is robust, so values >4 are accepted, but rounded down to 4 (offline) or 2 (online).
0x02 uint8 N-ONLINE If >0: Force number of total players for online modes. It is robust, so values >99 are rounded down to 99. Can be combined with FORCE-ONLINE.
0x03 int8 COND-BIT If between 0 and 15: If testing the settings (1-8) of a DEFINITION_OBJECT for CONDITIONS, ignore the calculation of a bit number by previous data members and use this bit number.
0x04 uint8 GAME-MODE Force a game mode: 0=AUTO (default), 1=STANDARD (ignore extension), 2=BALLOON, 3=COIN, 4=VERSUS, 5=ITEMRAIN.
0x05 uint8 RANDOM If between 1 and 8: Force a random scenario.
0x06 uint8 ENGINE Force an engine mode: 0=AUTO (default), 1=Battle, 2=50cc, 3=100cc, 4=150cc, 5=200cc, 6=150cc+mirror, 7=200cc+mirror.
0x07 uint8 padding
0x08 End of section

DEV1 : Define various developer settings

This section is only intended for LE-CODE developers to support development. Sometimes you want to test new code with just one or a few tracks. These then use settings from DEV1 for activation.

A description of the parameters makes no sense, as they only have a temporary effect and are used again and again for new purposes.

Wiimms SZS Tools

As of v2.01a, Wiimms SZS Tools will support LEX files. The implementation is similar to KMP:

  • Command wlect create …[1] creates various file templates, including LEX files.
  • Command wlect cat …[2] will print the content of a LEX file to stdout.
  • Command wlect decode …[3] will decode a binary LEX file into a text form, that can be modified by tools and editors.
  • Command wlect encode …[4] will create a text file into a binary LEX file. There a 2 pass compiler is used.
  • Command wszst lex …[5] will search file course.lex and will print the content of it to stdout.
  • Encoding and decoding is integrated in tool wszst for automated decoding and encoding (like KMP before).
  • Commands filetype and fileattrib of all tools detect LEX files (binary and text).

Example commands

Command wlect create … will create an LEX text file as template. Without keyword, you get a list of possible keywords.

wlect create lex > course.lex.txt
wlect create set1 > course.lex.txt

Use command wlect encode … to create a binary LEX file after your edits. The output is stored as course.lex and can be copied to the track's SZS. Option --overwrite (short: -o) allows the tool to overwrite an already existing file. Use this command after every change of of the text file.

wlect encode -o course.lex.txt

Use command wlect cat … to view the content of a binary LEX file as text in a console window. It is also possible to redirect the output to a file:

wlect cat course.lex
wlect cat course.lex > proof.txt