LEX (File Format)
- LE-CODE & LEX
- LE-CODE: General description
- LE-CODE: History
- LE-CODE: FAQ for track creators
- LE-CODE: Distribution Tutorial
- LE-CODE: FAQ for distribution creators
- LE-CODE: Item Cheat
- LE-CODE: Slot usage
- LPAR: File format for parameters
- LEX: File format and definitions
- Controllers & Buttons
- Wiimm's Test Tracks
- Extended presence flags
- Related Categories
LEX (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's like KMP's course.kmp, but it provides additional settings and modifications outside of a KMP. The main idea is, that global game settings can be overridden by track dependent settings in cases, where it is not possible otherwise.
LEX is designed to be open for future extension by third persons. Anyway, each new section identifier (a 4 byte ASCII magic) should be requested to Wiimm. He will guarantee unique identifiers.
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.
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.
|0x00||char||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:
|0x00||uint32||A magic to identify the section (type of section). An alternative datatype is char.|
|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.
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.
|Identity / Magic|| Date of
| Date of
|0||2019-02-28||—||Terminator of chain.|
|----||0x2d2d2d2d||2019-02-28||—||Invalidated section. Ignore it.|
|SET1||0x53455431||2020-02-02||—||Define various settings.|
|HIPT||0x48495054||2020-02-04||—||Define rules based on lap index and check points to hide the position tracker.|
|TEST||0x54455354||2020-01-10||2020-02-01||Define test settings.|
SET1 : Define various settings
Section SET1 defines various settings to modify the behavior of the track. At the moment 1 vector is defined only, other settings may follow:
|0x00||float||ITEM-POS-FACTOR||Define 3 stretch factors (one for each axis) to increase the range for items at the expense of accuracy and therefor 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 »1.0 1.0 1.0« (no stretch).|
|0x0c||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.
|0x00||uint32||N = Number of defined cannon types|
|0x04||float||4 settings for cannon type #0|
|0x14||float||4 settings for cannon type #1|
|4+N*16||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. Therefor 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«).
|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.|
|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).
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.
|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.|
|0x08||End of section|
Wiimms SZS Tools
- Command wlect cat will print the content of a LEX file to stdout.
- Command wlect decode will decode a binary LEX file into a text form, that can be modified by tools and editors.
- Command wlect encode will create a text file into a binary LEX file. There a 2 pass compiler is used.
- Command wszst lex 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).
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
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