Add initial Kaitai formats to document LEGO Island file formats (#1712)

* Add initial Kaitai formats

* Update README with installation and command examples

Added installation instructions for Kaitai Struct Visualizer and updated ksdump command examples.

* Update README.md

* Update link to Kaitai Struct documentation

* Update installation link for Kaitai Struct Visualizer
This commit is contained in:
Christian Semmler 2026-01-10 13:52:53 -07:00 committed by GitHub
parent 4bcc2b964b
commit f52b275130
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 228 additions and 0 deletions

55
docs/README.md Normal file
View File

@ -0,0 +1,55 @@
# LEGO Island File Format Documentation
This folder contains documentation for LEGO Island's custom binary file formats using [Kaitai Struct](https://kaitai.io/), a declarative language for describing binary data structures.
## What is Kaitai Struct?
Kaitai Struct allows you to define binary formats in a YAML-based `.ksy` file, which can then be:
- Compiled into parser libraries for [many programming languages](https://kaitai.io/#quick-start) (C++, Python, JavaScript, etc.)
- Visualized interactively using the [Kaitai Struct Visualizer](https://github.com/kaitai-io/kaitai_struct_visualizer)
- Dumped to human-readable formats using `ksdump`
<img width="1877" height="706" alt="image" src="https://github.com/user-attachments/assets/0d124219-1208-48ce-83bb-f433d9bb84b1" />
## Documented Formats
| File | Extension | Description |
|------|-----------|-------------|
| [`players.ksy`](/docs/players.ksy) | `.gsi` | Player profile save data (usernames) |
| [`history.ksy`](/docs/history.ksy) | `.gsi` | Score history and high scores |
## Using the Tools
### Installation
See the [Kaitai Struct Visualizer installation instructions](https://github.com/kaitai-io/kaitai_struct_visualizer?tab=readme-ov-file#downloading-and-installing) for setup details.
### Kaitai Struct Visualizer (ksv)
The [Kaitai Struct Visualizer](https://github.com/kaitai-io/kaitai_struct_visualizer) (`ksv`) provides an interactive terminal UI for exploring binary files.
```bash
# View a Players.gsi file
ksv samples/Players.gsi players.ksy
# View a History.gsi file
ksv samples/History.gsi history.ksy
```
### Kaitai Struct Dump (ksdump)
`ksdump` outputs the parsed structure as JSON or YAML for scripting and inspection.
```bash
# Dump Players.gsi to JSON
ksdump --format json samples/Players.gsi players.ksy
# Dump History.gsi to YAML
ksdump --format yaml samples/History.gsi history.ksy
```
## Sample Files
The [`samples/`](/docs/samples/) directory contains example save files for testing:
- `Players.gsi` - Sample player profile data
- `History.gsi` - Sample score history data

125
docs/history.ksy Normal file
View File

@ -0,0 +1,125 @@
meta:
id: history
title: Score History Save File
application: LEGO Island
file-extension: gsi
license: CC0-1.0
endian: le
doc: |
Score history save data for LEGO Island (1997). Stores up to 20 player
score entries, tracking high scores across all missions and characters.
The file is located at `<save_path>/History.gsi` where save_path is
typically the game's installation directory.
seq:
- id: next_player_id
type: s2
doc: |
The next player ID to be assigned when a new player profile is created.
Increments each time a new player is added, ensuring unique IDs.
- id: count
type: s2
doc: Number of score entries in the history (0-20 max).
- id: entries
type: score_entry
repeat: expr
repeat-expr: count
doc: Array of score history entries, sorted by total score descending.
types:
score_entry:
doc: |
A single score history entry containing a player's high scores across
all minigames and characters. Total serialized size is 45 bytes
(2 for index + 43 for score_item data).
seq:
- id: index
type: s2
doc: Array index of this entry (0 to count-1). Stored redundantly in file.
- id: total_score
type: s2
doc: Sum of all individual high scores across all missions and actors.
- id: scores
type: mission_scores
doc: High scores organized by mission type, each containing scores per actor.
- id: name
type: username
doc: The player's username associated with these scores.
- id: player_id
type: s2
doc: Unique player identifier matching the player's profile.
mission_scores:
doc: |
High scores for all 5 missions. Each mission contains scores for all
5 playable actors.
seq:
- id: car_race
type: actor_scores
doc: Car Race mission high scores.
- id: jetski_race
type: actor_scores
doc: Jetski Race mission high scores.
- id: pizza_delivery
type: actor_scores
doc: Pizza Delivery mission high scores.
- id: tow_track
type: actor_scores
doc: Tow Track mission high scores.
- id: ambulance
type: actor_scores
doc: Ambulance mission high scores.
actor_scores:
doc: |
High scores for a single mission across all 5 playable actors.
seq:
- id: pepper
type: u1
enum: score_color
doc: High score for Pepper.
- id: mama
type: u1
enum: score_color
doc: High score for Mama.
- id: papa
type: u1
enum: score_color
doc: High score for Papa.
- id: nick
type: u1
enum: score_color
doc: High score for Nick.
- id: laura
type: u1
enum: score_color
doc: High score for Laura.
username:
doc: |
A player username consisting of up to 7 letters. Each letter is stored
as a signed 16-bit index. The struct is always 14 bytes (0x0e).
seq:
- id: letters
type: s2
repeat: expr
repeat-expr: 7
doc: |
Letter indices for the username characters:
- 0-25: Standard alphabet (0=A, 1=B, ..., 25=Z)
- 29: International ä, å, or ñ (language-dependent)
- 30: International ö or æ (language-dependent)
- 31: International ß or ø (language-dependent)
- 32: International ü
- -1 (0xFFFF): Empty/unused position
Unused positions are filled with -1. A name shorter than 7
characters will have trailing -1 values.
enums:
score_color:
0: grey
1: yellow
2: blue
3: red

48
docs/players.ksy Normal file
View File

@ -0,0 +1,48 @@
meta:
id: players
title: Players Save File
application: LEGO Island
file-extension: gsi
license: CC0-1.0
endian: le
doc: |
Player profile save data for LEGO Island (1997). Stores up to 9 player
profiles, each identified by a 7-character username. Usernames are stored
as letter indices rather than ASCII characters.
The file is located at `<save_path>/Players.gsi` where save_path is
typically the game's installation directory.
seq:
- id: count
type: s2
doc: |
Number of saved player profiles. The game supports a maximum of 9
players; when a 10th player is added, the oldest profile is deleted.
- id: entries
type: username
repeat: expr
repeat-expr: count
doc: Array of player username entries, ordered by most recently played.
types:
username:
doc: |
A player username consisting of up to 7 letters. Each letter is stored
as a signed 16-bit index. The struct is always 14 bytes (0x0e).
seq:
- id: letters
type: s2
repeat: expr
repeat-expr: 7
doc: |
Letter indices for the username characters:
- 0-25: Standard alphabet (0=A, 1=B, ..., 25=Z)
- 29: International ä, å, or ñ (language-dependent)
- 30: International ö or æ (language-dependent)
- 31: International ß or ø (language-dependent)
- 32: International ü
- -1 (0xFFFF): Empty/unused position
Unused positions are filled with -1. A name shorter than 7
characters will have trailing -1 values.

BIN
docs/samples/History.gsi Executable file

Binary file not shown.

BIN
docs/samples/Players.gsi Executable file

Binary file not shown.