diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..297f7ce3
--- /dev/null
+++ b/docs/README.md
@@ -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`
+
+
+
+## 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
diff --git a/docs/history.ksy b/docs/history.ksy
new file mode 100644
index 00000000..f60bb2af
--- /dev/null
+++ b/docs/history.ksy
@@ -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 `/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
diff --git a/docs/players.ksy b/docs/players.ksy
new file mode 100644
index 00000000..84136ed2
--- /dev/null
+++ b/docs/players.ksy
@@ -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 `/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.
diff --git a/docs/samples/History.gsi b/docs/samples/History.gsi
new file mode 100755
index 00000000..f253055f
Binary files /dev/null and b/docs/samples/History.gsi differ
diff --git a/docs/samples/Players.gsi b/docs/samples/Players.gsi
new file mode 100755
index 00000000..21c08e1d
Binary files /dev/null and b/docs/samples/Players.gsi differ