SaveEditor
Back to Blog
Tutorial9 min readMarch 15, 2026

Understanding Binary Save Files

If you've ever opened a save file and seen a wall of garbled characters, you were looking at binary data. This guide breaks down what binary files are, how to read them, and how to make sense of the hex view in SaveEditor — no prior experience needed.

Binary Data vs. Text Data

Every file on your computer is a sequence of bytes — numbers from 0 to 255. The difference between "binary" and "text" is simply how those bytes are meant to be interpreted.

Text files

Each byte represents a character using an encoding like UTF-8 or ASCII. The number 72 = "H", 101 = "e", 108 = "l". You can open these in Notepad and they look normal. JSON, XML, and INI save files (Stardew Valley, Hollow Knight, Undertale) are text.

Binary files

Bytes represent raw numbers, not characters. A group of 4 bytes might be a 32-bit integer for your health, or a floating-point number for your x-coordinate. Opening these in Notepad shows gibberish because the bytes aren't meant to be characters. Elden Ring (.sl2), Skyrim (.ess), and Dark Souls (.sl2) use binary formats.

Hexadecimal: The Language of Bytes

Hex (base-16) is a compact way to write byte values. Instead of writing decimal 0–255, hex uses 00–FF. Each hex digit represents 4 bits, and two hex digits represent one full byte (8 bits).

DecimalHexBinaryAs ASCII
00000000000NUL
100A00001010Line Feed
654101000001A
1006401100100d
255FF11111111(none)

Why hex instead of decimal? Because hex aligns perfectly with byte boundaries. One byte is always exactly two hex characters, making it easy to see where one value ends and the next begins.

Common Data Types in Save Files

Games store different kinds of values using different amounts of bytes. Here are the types you'll encounter most often:

int8 / uint81 byte

Range: -128 to 127 (signed) or 0 to 255 (unsigned)

Boolean flags, small counters, inventory slot indices.

int16 / uint162 bytes

Range: -32,768 to 32,767 or 0 to 65,535

Item IDs, moderate counters, short distances.

int32 / uint324 bytes

Range: Up to ~2.1 billion (signed) or ~4.3 billion (unsigned)

Gold/currency, experience points, time played in seconds, most integer stats.

int64 / uint648 bytes

Range: Up to ~9.2 × 10¹⁸

Steam IDs, Unix timestamps in milliseconds, very large counters.

float32 (IEEE 754)4 bytes

Range: ~±3.4 × 10³⁸ with ~7 decimal digits precision

Player coordinates (x, y, z), camera angles, physics values, percentages.

StringsVariable

Range: N/A

Character names, quest IDs. Usually stored as a length prefix (1–4 bytes) followed by the characters, or as null-terminated (bytes until 0x00).

Endianness: Byte Order Matters

When a number takes more than one byte, the bytes can be stored in two orders. Getting this wrong is one of the most common reasons an edited value doesn't work.

Little-Endian (LE)

The least significant byte comes first. This is the standard on x86/x64 processors — meaning virtually all PC games use little-endian.

The number 1,000 (0x000003E8) stored as a 32-bit int:

E8 03 00 00

Big-Endian (BE)

The most significant byte comes first. Used by some console games (GameCube, Wii, PS3), network protocols, and Java-based formats.

The same number 1,000 (0x000003E8):

00 00 03 E8

Quick rule:If you're editing a PC game save, assume little-endian unless you know otherwise. SaveEditor's Data Inspector lets you toggle between LE and BE so you can quickly check which interpretation gives a sensible value.

How to Read a Hex Dump

A hex dump displays file contents in three columns: the offset (address), the hex bytes, and the ASCII representation. Here's an example of what you might see in SaveEditor's hex view:

Offset    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   ASCII
────────  ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ──   ────────────────
00000000  42 4E 44 34 00 00 00 00 E8 03 00 00 01 00 00 00   BND4........
00000010  48 65 72 6F 00 00 00 00 64 00 00 00 C8 AF 44 42   Hero....d...ȯDB
00000020  00 00 80 3F 05 00 00 00 53 77 6F 72 64 00 00 00   ...?....Sword...
Offset

The leftmost column shows the byte position in the file. Offset 0x00000010 means 16 bytes from the start. Use offsets to navigate to specific values when you know where they're stored.

Hex bytes

The middle section shows 16 bytes per row, each displayed as a two-character hex value. This is where you read and edit raw data.

ASCII

The right column shows the same bytes interpreted as text characters. Non-printable bytes appear as dots. This helps you spot readable strings (like "BND4", "Hero", "Sword") which serve as landmarks when navigating.

SaveEditor's Hex View & Data Inspector

When you open a binary file in SaveEditor, the hex view displays the raw bytes alongside an interactive Data Inspector panel. The Data Inspector reads the bytes at your cursor position and shows the value interpreted as every common data type simultaneously:

int8-24
uint8232
int16 LE1000
uint16 LE1000
int32 LE1000
float32 LE1.401e-42
UTF-8è

In this example, the cursor is at the byte E8. The int16 and int32 interpretations (reading E8 03 as little-endian) both show 1000 — which could be the player's gold. The float32 interpretation gives a tiny number (1.401×10⁻⁴²), which makes no sense as a gameplay value, so you can rule that out. This process of elimination is how you identify what type of data you're looking at.

Common Patterns to Look For

Magic bytes (file signatures)

Most binary formats start with a unique sequence of bytes that identifies the file type. Elden Ring's .sl2 starts with "BND4" (42 4E 44 34). Dark Souls uses the same signature. Skyrim .ess files start with "TESV_SAVEGAME". If you see these at offset 0, you know you have the right file.

Null terminators (0x00)

Strings in binary files often end with a zero byte (0x00), called a null terminator. When you see readable ASCII text followed by 00, that's the end of the string. Some formats pad strings to a fixed length by filling remaining bytes with 0x00.

Repeated structures (arrays)

Inventory systems, skill trees, and quest logs often store data as arrays of fixed-size records. If you see the same pattern of bytes repeating at regular intervals (say every 16 or 32 bytes), you've likely found an array. Count the repetitions to figure out the record size.

Length-prefixed data

Instead of null-terminated strings, some formats write the string length first (as a uint16 or uint32), then the string characters. If you see 05 00 00 00 followed by 5 readable characters, that's a length-prefixed string.

Section headers and offsets

Complex save files are divided into sections. A header near the top of the file lists the offset (position) and size of each section. If you see a table of large numbers early in the file, those are probably section offsets — follow them to jump to specific data blocks.

Example: Walking Through a Simple Save Structure

Let's imagine a tiny save file for a hypothetical game. The format stores a header, a player name, and some stats:

Offset    Hex                                                 ASCII
────────  ──────────────────────────────────────────────────  ────────────────
00000000  53 41 56 45 01 00 04 00 48 65 72 6F E8 03 00 00   SAVE....Hero....
00000010  64 00 05 00 00 00 C8 42 00 00 48 43              d.....ÈB..HC

Offset 0x00–0x03: Magic bytes

53 41 56 45= "SAVE" in ASCII. This identifies the file format.

Offset 0x04: Version byte

01 = format version 1. The game checks this to ensure compatibility.

Offset 0x05: Padding

00 = unused byte for alignment.

Offset 0x06–0x07: Name length (uint16 LE)

04 00 = 4 in little-endian. The player name is 4 characters long.

Offset 0x08–0x0B: Player name

48 65 72 6F= "Hero". Exactly 4 bytes, matching the length prefix.

Offset 0x0C–0x0F: Gold (int32 LE)

E8 03 00 00= 1,000 gold. To change this to 5,000, you'd write 88 13 00 00 (0x1388 in LE).

Offset 0x10: Level (uint8)

64 = 100 in decimal. The player is level 100.

Offset 0x11: Current quest (uint8)

05 = quest ID 5.

Offset 0x12–0x15: X position (float32 LE)

00 00 C8 42 = 100.0 as a floating-point number. (In IEEE 754: sign=0, exponent=133, mantissa=1.5625 × 2⁶ = 100.)

Offset 0x16–0x19: Y position (float32 LE)

00 00 48 43 = 200.0. The player is at coordinates (100.0, 200.0).

In SaveEditor, you wouldn't need to do this math yourself. Click any byte in the hex view, and the Data Inspector instantly shows the value at that offset in every common format — int8, int16, int32, float32, and string — so you can immediately see which interpretation makes sense.

Next Steps

Now that you understand the fundamentals, here's how to put them into practice:

  • 1Open a save file you're familiar with in SaveEditor's hex view.
  • 2Look for magic bytes at offset 0x00 to confirm the format.
  • 3Find your character name in the ASCII column — it's a great landmark.
  • 4Check the Data Inspector at different offsets near your name. Stats like HP, gold, and level are usually nearby.
  • 5Make a small change (like adding 1 to a value), save, and load the game to see the effect.
  • 6Always keep a backup, and read our guide on safe editing practices before making bigger changes.

Try the Hex View Yourself

Drop any binary file into SaveEditor to explore it with the hex view and Data Inspector — no installation required.

Open SaveEditor