- Rust 66.6%
- Fluent 27%
- Shell 4.3%
- Python 0.7%
- NSIS 0.6%
- Other 0.8%
|
All checks were successful
CI / Windows, MSYS2 sysroot (push) Successful in 17s
CI / Windows, command line (clippy with tests) (push) Successful in 48s
CI / Windows, installer (tests under Wine) (push) Successful in 1m39s
CI / Windows, command line (tests under Wine) (push) Successful in 1m58s
CI / Bundle programs, command line and helper (push) Successful in 1m56s
CI / Arch package (push) Successful in 3m36s
CI / Bundle programs, desktop app (push) Successful in 2m31s
CI / Format, lint and test (push) Successful in 6m31s
CI / Windows, GTK with AccessKit (push) Successful in 8s
CI / Windows, desktop app (clippy, script tests) (push) Successful in 1m9s
CI / Bundle for any distribution (push) Successful in 23s
CI / Windows, installer and portable zip (push) Successful in 6m35s
CI / Windows, desktop app (tests under Wine) (push) Successful in 1m30s
CI / Release (push) Has been skipped
|
||
|---|---|---|
| .forgejo/workflows | ||
| assets | ||
| crates/ogc-db-proto | ||
| data | ||
| docs | ||
| packaging | ||
| scripts | ||
| src | ||
| tests | ||
| tools | ||
| .gitignore | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
| rustfmt.toml | ||
Get disk space back from your Steam library, without changing a single game.
Transparent btrfs zstd compression for Linux and WOF compression for Windows, with a desktop app, a CLI and a
background timer.
OpenGameCompressor does for Linux what CompactGUI does for Windows, and runs on Windows too. It compresses installed games in place with the filesystem's own transparent compression: btrfs with zstd on Linux, NTFS with Windows' own WOF compression on Windows. Games keep running as before: the system decompresses data as it is read, fast enough that loading times barely change. Steam still sees the same files, and updates simply work.
Contents
- Quick start in 2 minutes
- Why a separate tool?
- Features
- Screenshots
- Requirements
- Installation
- Usage
- Windows
- Moving a drive to btrfs
- Safety
- FAQ
- Development
- Documentation
- Code signing policy
- License
Quick start in 2 minutes
On Windows? See Windows. On Linux:
1. Is your game drive btrfs? In a terminal (on a Steam Deck: Desktop Mode, Konsole):
findmnt -no FSTYPE -T ~/.local/share/Steam # or the folder of another Steam library
btrfs means you are ready; Fedora and Bazzite use it by default. ext4 or ntfs means the drive has to
be moved to btrfs first. On a Steam Deck the internal storage is ext4 and stays so,
as it holds your home folder: microSD cards and external drives can be moved to btrfs, and games kept there compressed.
2. Install it. Nothing below needs root, and nothing outside your home folder changes.
| System | How |
|---|---|
| Steam Deck / SteamOS, Bazzite, Fedora (Atomic or not), other distributions | Download the bundle of a release, opengamecompressor-<version>-x86_64.tar.gz (or build it: scripts/build-bundle.sh), then:tar -xf opengamecompressor-*-x86_64.tar.gzopengamecompressor-*-x86_64/install.sh --user |
| Arch, CachyOS, Manjaro, EndeavourOS | The package, as below; or the bundle |
The bundle puts ogc, the desktop app and its menu entry into ~/.local. The app uses the system's GTK 4 and
libadwaita; where they are missing or too old (SteamOS does not promise them), install.sh says so and installs the
command line only, which does the same: ~/.local/bin/ogc compress --all, then
~/.local/bin/ogc timer enable.
3. Compress. Open OpenGameCompressor from the application menu, go to Game library, press COMPRESS ALL, then switch on Recompress after game updates in Settings. Games stay playable all along; a game you start pauses the job.
Only moving a drive to btrfs needs more: a small helper that runs as administrator, installed once for the whole
system. The app tells you when it is missing and shows the command; for the bundle it is
sudo ~/.local/share/opengamecompressor/system/install-helper.sh (on a Steam Deck, set a password with passwd
first). See The migration helper.
Why a separate tool?
btrfs can compress everything with the compress=zstd mount option. Steam game installs don't get compressed that
way, though. Steam preallocates every file with fallocate before downloading, and btrfs does not compress
preallocated space. So even on a drive mounted with compression, the games end up uncompressed.
OpenGameCompressor rewrites installed games through the btrfs defragment ioctl with zstd enabled. That needs no root, no FUSE layer and no changes to the games. It also remembers what it has done: after Steam updates a game, the game is compressed again automatically.
Features
| 🎮 Steam integration | Finds every library and game (libraryfolders.vdf, app manifests) and leaves out games that are downloading, updating or verifying. |
| 📊 Estimate first | analyze samples the files and predicts the savings per game before anything is written. |
| ⚡ Fast, parallel rewriting | Files are processed in parallel. Already packed data (videos, archives) is detected by sampling and skipped instead of being rewritten for nothing. |
| 🔗 Identical files stored once | ogc dedupe, or Share identical files now in the app's settings, lets identical files of games and Proton prefixes, such as the same runtime in many games, share their data on the disk. The kernel compares them byte by byte first. |
| 🍷 Proton prefixes | The Windows environments Proton keeps for each game lie outside the game folders. A switch in the app's settings, or --prefixes, compresses them too. |
| 🔁 Stays compressed | Auto-recompress, an hourly systemd user timer (on Windows a task of the Task Scheduler), recompresses games after Steam updates them. It runs on AC power only and stops when you unplug. On Linux it waits while a game runs and reads at idle CPU and I/O priority; the kernel compresses the data at normal priority. On Windows a game that starts ends the run, and the next hourly run picks up where it left off. The library shows which games were updated since, and recompresses them in one go. |
| ⏸️ Pauses for your games | When a Steam game, or any game running with Proton, starts, compression and the app's background analysis wait until it has exited, so the game does not stutter. |
| 🚫 Games left alone | Exclude a game, and nothing compresses it: not the command line, not auto-recompress, not the app. |
| ↩️ Undo | Decompress a game that misbehaves; it is left alone from then on. Needs Linux 6.17; works on every Windows. |
| 🖥️ Desktop app | GTK4/libadwaita app with a dashboard, per-game savings, a library view and settings, in a dark and a light theme. |
| 💽 Drive migration | A wizard moves a game drive from ext4, NTFS and other filesystems to btrfs, either by converting in place or by formatting and downloading the games again. You always pick the drive yourself. |
| 🧩 Beyond Steam | Games of Heroic (Epic, GOG, Amazon, ZOOM), Lutris and Faugus are found too, with their Wine prefixes; on Windows those of the Epic Games Launcher, GOG, Heroic, Ubisoft Connect and the EA app. Add folder… in the app adds any other folder, such as a Bottles game or an emulator's games, as a game of its own; --dir compresses one once. |
| 🪟 Windows too | The same app and commands on Windows 10 and 11, with Windows' own compression (WOF, as CompactGUI uses it), exact savings, a per-user install without administrator rights or a portable zip. See Windows. |
| 🌍 13 languages | English, Deutsch, Français, Español, Português, Italiano, Polski, Русский, Українська, Türkçe, 中文, 日本語, 한국어 |
Screenshots
| Game library | Moving a drive to btrfs | Light theme |
|---|---|---|
![]() |
![]() |
![]() |
The games and drives in these pictures are made up; scripts/screenshots.sh takes them again.
Requirements
For Windows, see Windows. On Linux:
- Linux with the games on a btrfs filesystem. For other filesystems, see Moving a drive to btrfs.
- Kernel 6.15 or newer to choose the zstd level per run. Older kernels work too, but use btrfs's default level.
btrfs-progs,util-linux, ande2fsprogs(only needed for migrations)polkit, for the administrator prompt during a migration- For the desktop app: GTK ≥ 4.14, libadwaita ≥ 1.6 and Pango ≥ 1.56
- For the release bundle: x86-64 and glibc ≥ 2.28 (every SteamOS 3 and Fedora 40 or newer have it); its desktop
app needs glibc ≥ 2.35, which every system with the GTK above has.
BUNDLE_INFOin the bundle names both. A bundle you build yourself withscripts/build-bundle.shneeds the glibc of your system or newer
Installation
For Windows, see Installing on Windows.
Release bundle (any distribution, also SteamOS, Bazzite and Fedora Atomic)
tar -xf opengamecompressor-<version>-x86_64.tar.gz
opengamecompressor-<version>-x86_64/install.sh --user # --no-gui: the command line only
install.sh runs as your own user and installs into ~/.local (another folder with --prefix):
| What | Where |
|---|---|
ogc, ogc-gui |
~/.local/bin |
| Menu entry (starts the app by its full path), icon | ~/.local/share/applications, ~/.local/share/icons |
| Completions for bash, zsh and fish; man pages | ~/.local/share/{bash-completion,zsh,fish}, ~/.local/share/man/man1 |
Fonts, the installer of the migration helper, uninstall.sh |
~/.local/share/opengamecompressor |
It checks first that the programs run on this system, and installs only the command line when the desktop app
cannot start for want of GTK 4, libadwaita or Pango. Installing a newer bundle replaces the older one; a background
timer that ran another ogc is pointed at the installed one, with its options. zsh finds the completion once
~/.local/share/zsh/site-functions is in its $fpath; ogc is found by name once ~/.local/bin is in PATH.
To remove it: ~/.local/share/opengamecompressor/uninstall.sh.
Why a tarball and not an AppImage or a Flatpak: see Packaging in the architecture notes.
The migration helper
Compression, the timer and the history run as your user. Only moving a drive to btrfs changes the system: a small
helper, ogc-migrate-helper, runs as root through polkit's pkexec, which asks for the administrator password each
time. It is installed separately, once, and the app looks for it only in /usr/lib/opengamecompressor and
/usr/local/lib/opengamecompressor. The Arch package installs it; for the bundle:
sudo ~/.local/share/opengamecompressor/system/install-helper.sh # --uninstall removes it again
- Where
/usrcan be written to (most distributions), it installs the helper into/usr/local/lib/opengamecompressorand its polkit policy into/usr/share/polkit-1/actions, naming that path. - Where
/usris read-only (SteamOS, Bazzite, Fedora Atomic), it installs both as a systemd system extension,/var/lib/extensions/opengamecompressor-helper.raw, which systemd lays over/usrat every boot; it switches onsystemd-sysext.servicefor that. polkit reads the new policy only when it starts, so restart the computer after every install or update: until then pkexec asks with its generic prompt, and the helper refuses to run. If a system update ever drops the extension, the app says so and shows the command again. A tool that makes/usrwritable for a while, such as SteamOS'ssteamos-readonly disable, may needsudo systemd-sysext unmergefirst (andsudo systemd-sysext mergeafterwards).
What installing it means for security:
- It adds root code to the system, reachable by any program that runs as you, but only behind the administrator password: each of its polkit actions asks for it every time and never remembers it. The prompt names the drive and its mount point, and the helper checks every argument against the drive before it acts (details).
- The installed helper and its policy belong to root, so no program running as you can change them; the app never takes a helper from a folder you can write to. The system extension is a read-only image.
install-helper.shruns withsudofrom your home folder, like any script you run that way: whatever can change files in your home can change it first. Check the bundle you downloaded against its.sha256, and install the helper right after unpacking it if in doubt.- The extension applies to every version of the system (
ID=_any), so it survives updates without being rebuilt; the helper then needs only a compatible glibc.install-helper.shrefuses a helper that does not run.
Arch Linux, CachyOS, Manjaro, EndeavourOS
Each release has the package attached
(sudo pacman -U opengamecompressor-<version>-1-x86_64.pkg.tar.zst). Or build and install it from the source tree:
git clone https://forgejo.skyfar.de/LevelXStudios/OpenGameCompressor.git
cd OpenGameCompressor
scripts/build-arch-package.sh
sudo pacman -U target/arch/opengamecompressor-*.pkg.tar.zst
This installs ogc, ogc-gui, a desktop entry, the migration helper and its polkit policy, and for ogc the
completions for bash, zsh and fish and the man pages (man ogc, man ogc-compress, …).
From source
cargo build --release # ogc, ogc-gui, ogc-migrate-helper
cargo build --release --no-default-features # CLI only, no GTK needed
scripts/build-bundle.sh # the release bundle, in target/bundle/
The binaries end up in target/release/. The bundle's install.sh and system/install-helper.sh install them as
described above. A package installs the helper as /usr/lib/opengamecompressor/ogc-migrate-helper plus the
policy in /usr/share/polkit-1/actions/, as package() in packaging/arch/PKGBUILD
does.
ogc prints its shell completions and writes its man pages itself:
ogc completions bash > ~/.local/share/bash-completion/completions/ogc
ogc completions zsh > ~/.local/share/zsh/site-functions/_ogc # a directory in your $fpath
ogc completions fish > ~/.config/fish/completions/ogc.fish
ogc manpages ~/.local/share/man/man1 # ogc.1 and one page per subcommand
Usage
Desktop app
Start OpenGameCompressor from the application menu, or run ogc-gui. The pages are in the sidebar, which
folds away behind a button in a narrow window (a Steam Deck's half screen next to Steam); Ctrl+1 to Ctrl+5 switch
pages, Ctrl+F searches the library (or just type a game's name on its page; Escape clears the search), F5 reads the
libraries again, and Ctrl+? lists all shortcuts. In a question, Alt and the underlined letter pick an answer. The
menu at the end of the header bar opens the shortcuts, the help by topic (sections of this README), Report a
problem…, which copies the debugging information and opens a new issue to paste it into, and About, whose
troubleshooting section has the same information.
- The dashboard shows how much compression has saved out of what it could save, with a button that compresses
the games COMPRESS ALL would take, also while they are still being estimated ("≈ 73 GiB so far"), and how far
a job is while it runs (or, where your games are on ext4 or NTFS, what moving that drive to btrfs would bring and a
button that opens the migration wizard with it chosen), the games on btrfs with the most to gain (a click shows one
in the library; a game that gains that much only at a higher level than it was compressed at says so, and a click
opens the settings, which recompress it), the last action of the app, auto-recompress or the command line, your drives with their free
space, and a switch that keeps games compressed after updates. After the first job that compressed a game it
offers once to turn that on. The status under each page's name says what runs (a job, a migration,
auto-recompress) or how auto-recompress stands ("On: auto-recompress · next check at 9:00 PM", the state first,
in the language's own way of telling the time), and a click on it
opens the page that explains it. Space already gained is "saved", an estimate "can save" or "could save", and
what a decompression took "more used", without signs, in the app, in
ogcand in the notifications. - The library lets you estimate and compress individual games. Each game's button says what it needs:
COMPRESS, RECOMPRESS once Steam has updated it, or none but a check mark and "31 GiB saved" once it is
done. The savings column ("can save ≈ 46 GiB"; on a narrow window the end of the game's line) tells an estimate
being made ("Estimating…") from a game too small to gain ("— already small").
COMPRESS ALL names its work ("Compress 9 games · ≈ 99 GiB"), takes the games shown, in their order, that gain
from it, and asks first, saying what it can save on how many drives and about how long it takes. SHOW: UPDATED
lists the games Steam has updated since they were compressed; COMPRESS ALL then recompresses just those.
Compressing a game while a job runs queues it after the job ("Queued · 2 games ahead"). A game's card shows the
job's progress, the time left and what it has saved so far; while a game runs, the job pauses until it exits,
and says so. When a job for several games ends, a card above the list sums it up ("9 of 10 games compressed ·
98.4 GiB saved · 12 min"), with a line for each problem in plain words, RETRY FAILED and SHOW IN
LIBRARY; a single game ends in a short message. A game that failed or was skipped carries a chip that opens
the whole reason, its folder and what to do (for files that belong to another user, the command that takes them
over). Games on a drive that is not btrfs show NEEDS BTRFS (unless excluded), and one banner per drive offers
MOVE THIS DRIVE TO BTRFS, which opens the migration with that drive chosen, if it can be chosen. The ⋯ menu of a game (also a right click or a
long press on it) opens its folder or its page in Steam, analyses it again, compresses it at another level,
shows the history, excludes it from compression (with UNDO, and naming the games in the same folder), or
includes it again, and decompresses it (on a kernel older than 6.17 it says so). Each card shows the game's cover
as Steam, Heroic, Lutris or Faugus keep it on your disk (nothing is downloaded; else its initials), its launcher,
PROTON ✓ where its Proton prefix is compressed too, and its filesystem only where that is not btrfs. The line
above the games and the totals below them count what the search and the filters show ("1 of 15 games"), with
Reset filters. With the keyboard, the arrow keys go from game to game, Tab goes through the buttons of the
game you are on and then past the list, Enter does what its button does, and the Menu key or Shift+F10 opens its
⋯ menu. A screen reader reads each game as one line, and hears when a job starts, at each quarter of it, when
each game is done, errors at once, and how many games a search shows; the window's title shows how far a job
is. The folder button in the header
bar adds any folder as a game (a Bottles or itch.io game, an emulator's games): it gets a card with a FOLDER
badge and is analysed, compressed, excluded and decompressed like a game, and auto-recompress compresses it when
it compresses new games. A folder that holds the home folder, a drive, Downloads or a Steam library, a system
folder, one inside a game's folder or prefix, and one that holds a game, is refused with the reason. Where the window is narrow,
DRIVE, SHOW and SORT fold into one FILTER button. A banner above the games says when some could not be
listed (naming the one problem, such as an own folder whose drive is not connected), and DETAILS tells why. While a job runs, COMPRESS ALL turns into CANCEL, which stops the
whole job and the games queued after it. Closing the window then lets the job continue in the background:
the window goes, a notification shows how far the job is, with SHOW and CANCEL, and the app ends once the
job is done, leaving a notification of what it did that opens the history; you can also cancel the job and close,
or keep the window. Meanwhile the computer does not go to
sleep. While auto-recompress or
ogc compressis compressing, the game's card and the header bar show it ("In the background: compressing Deep Orbit · 43%"), and a job you start waits for it ("Waiting for the background run (Deep Orbit · 43%)"); STOP THE BACKGROUND RUN on the card of the game it compresses stops it after the files in progress. Sharing identical files shows in the header bar too, and closing the window waits for it as for a job. - The history lists what auto-recompress, the app and the command line compressed, decompressed, shared and skipped, by day ("Today", "Yesterday", "September 28") with what each day saved, under what this month saved. A game and its Proton prefix share one line. Chips show only what auto-recompress or the app did, or the problems. A line says how it ended ("Iron Meridian: compression not finished") and, in short, why ("drive full"), and unfolds to the whole reason (a file it could not read, a full drive, snapshots of a new game), the level and the files, with SHOW IN LIBRARY and, where it did not go through, COMPRESS AGAIN. While auto-recompress has problems you have not seen there, HISTORY in the sidebar says how many; a game it skips every day for the same reason counts once.
- Settings hold the compression level (Fast, Balanced, Stronger, Maximum, or any level from 1 to 15; the
estimates follow it, as the games are analysed again in the background), whether
Proton prefixes are compressed (by the app along with their games, and by auto-recompress every prefix that is new
or has changed) and whether auto-recompress stores identical files once; Share identical files now, which
first says how much identical data it found and what it leaves out (games that run, drives with snapshots), then
shares it on your answer, also without auto-recompress, pauses while a game runs and can be cancelled; Own
folders, the folders added as games, each with REMOVE (which changes no file, and can be undone), and
Add folder…; Auto-recompress, the background timer, with whether
it also compresses new games and notifies you of what it did; the excluded games, also those no longer installed,
each with ALLOW; and the theme and the language (which
ogcand the notifications of auto-recompress use too, unlessLANGUAGE,LC_ALLorLC_MESSAGESasks for another), with RESTART NOW to use a new one. They also say when auto-recompress last checked and what that did ("2 games, 5.3 GiB saved", or why it looked at nothing: "Skipped: another compression was running"), with CHECK NOW, and when it is on but does not work (stopped, its program gone, or its last run failed), with REPAIR where that mends it; so do the header bar, in amber, and the dashboard. After you raise the level, they count the games compressed at a lower one and offer RECOMPRESS AT LEVEL 6, with what it saves and about how long it takes. When a long compression or decompression job finishes while the app is in the background, it notifies you too, with what failed and what was skipped; so does a migration when it needs your administrator password, stops, has all its downloads back, or is finished. A click on a notification, also on one from auto-recompress, opens the app on the history (or on the migration).
Command line
ogc list # libraries and games, and whether they are compressed
ogc analyze --all # how much would I save? (read-only)
ogc compress "Cyberpunk" # compress one game (name or app id; gog:Hades picks GOG's Hades)
ogc compress --all # compress everything
ogc compress --dir ~/Games/Bottles/SomeGame # a folder no launcher lists, once
ogc compress folder:SomeGame # a folder added in the app (also by name, or with --all)
ogc compress --all --prefixes # … and the Proton prefixes of the games
ogc dedupe --all --prefixes # store identical files once (after compressing)
ogc timer enable # keep games compressed after updates
ogc timer enable --include-new # … and compress newly installed games too
ogc timer enable --include-prefixes --dedupe # … also prefixes, and store identical files once
ogc timer enable --notify # … and show a desktop notification when it compressed games
ogc exclude add "Elden Ring" # never compress this game (also: remove, list)
ogc decompress "Elden Ring" # undo it, and leave the game alone from then on (Linux 6.17+)
ogc history # what the timer, the app and the command line did
ogc db show "Cyberpunk" # what others' results expect it to save (community data; also steam:1091500)
ogc db status # which community data is in use, and how old it is
ogc db update # download the current community data now (whole file, only when asked)
ogc db outbox --show # with sharing on: exactly what is queued to be shared (--clear deletes it)
ogc db send # send what is due now, one game at a time, at least two hours apart
ogc db measure "Portal" --by tester-1 # a curated measurement for ogc-db (see Community data)
Every command explains its options with --help, e.g. ogc compress --help, in the app's language, and ogc --help ends with the commands to start with. The package installs a man page for each (man ogc-compress, in
English). Tab completes commands and options in bash, zsh and fish.
Progress and quiet runs: on a terminal, long runs redraw one progress line. --progress=lines prints a line
every tenth of the work (or every 30 seconds) instead, which a screen reader reads without a flood of numbers;
--progress=none prints none, and -q also leaves out the notes about waiting. auto, the default (or the
environment variable OGC_PROGRESS), picks lines on a dumb terminal (TERM=dumb), while a screen reader runs, and
when the output goes into a file or a pipe. ogc writes no colours; with NO_COLOR, the help has none either.
Listing for screen readers and scripts: ogc list --format=plain prints each game as lines of a label and its
value ("Name: Portal", "Size: 4.7 GiB", …); ogc list --format=json prints the same for scripts, with names and values
that are the same in every language. Each entry of libraries lists its games:
| Field | Meaning |
|---|---|
format |
1; raised only when a field changes its meaning or goes away |
libraries[].path, .launcher |
the library folder (for the own folders, the list of them); steam, heroic, lutris, faugus, folder, or on Windows epic (the folder of its manifests), gog (its registry key), ubisoft and ea (the launcher's folder, else its registry key) and xbox (a folder of the Xbox app, whose games are listed as warnings only) |
libraries[].available |
false for a Steam library whose drive is not there |
libraries[].filesystem, .compresses, .free_bytes |
a Steam library's filesystem, whether it compresses, its free space; null for other launchers |
libraries[].warnings[] |
what was left out or could not be read: code (unreadable: a record; missing, too-broad, holds-games: a game whose folder is missing, holds more than the game or holds other games; overlaps: an own folder inside or around another game; xbox: a game of the Xbox app, which cannot be compressed; the dual-boot hints windows-compressed: games on NTFS that Windows compressed, which Linux may not start or which Steam's updates decompress, and on Windows used-by-linux: a Steam library Linux uses too, whose games the background runs leave alone), name (the game, or null), path, and message, the sentence ogc list prints, in the user's language |
libraries[].ntfs_driver |
on Linux, for a Steam library on NTFS: ntfs3, ntfs or ntfs-3g; left out elsewhere |
games[].appid, .name, .source |
the app id (made up for other launchers' games, and selecting them all the same), the name, and heroic/gog, lutris, epic, gog, ubisoft, ea, folder and the like (null for Steam) |
games[].install_dir, .size_bytes |
the folder, and the size the launcher records, or else what its files take (null where they cannot be read) |
games[].state |
installed, updating, validating, files-missing, update-paused, update-pending or not-ready |
games[].compression, .level |
compressed, updated (compressed, then updated by Steam), uncompressed or excluded; the zstd level of the first two |
games[].algorithm |
on Windows only, for a game compressed with WOF: xpress4k, xpress8k, xpress16k or lzx (level is null then); left out elsewhere |
games[].windows_compressed |
on Linux, true for a game on NTFS that Windows compressed (its compression says what OpenGameCompressor did: uncompressed); left out elsewhere |
games[].predicted_savings_bytes, .prediction_confidence, .prediction_source, .prediction_method |
what the community data expects compressing the game to save, in bytes; high, medium or low; curated, crowd, calibrated, compactgui or derived; and the method it is for (btrfs-zstd:3, wof:lzx: the one the game is compressed with, else the system's default). All null for a game the data does not know or that has no store id. A hint only: the game's own analysis replaces it |
Community data: OpenGameCompressor ships with a snapshot of the community database
(db.opengamecompressor.de): how much games saved for others, from curated
measurements and, later, results shared anonymously. ogc db show GAME tells what it expects for a game (for an
installed one, worked out for its size, the platform of its files and its build), ogc analyze adds a line
"Community data for …: ≈ 27% saved (reliable)" beside its own result, and ogc list --format=json carries it in the
fields above. Only games of Steam, Epic, GOG and Amazon have a store id it knows; others are never looked up. The
values are hints: they never decide what is compressed or skipped. ogc db update downloads the current data
once (see Privacy for what that reveals). Automatic downloads, at most once a day, belong to
the app's setting Download current community data (community-download=true in gui.conf), which is off until
you turn it on; the command line never downloads unasked. ogc db status tells which data is in use (shipped or
downloaded), its date, whether it is outdated, and whether downloads and sharing are on. Builds without the
database's public key cannot download or share at all and say so.
Curated measurements are named measurements for the database's maintainers, submitted to
ogc-db by pull request: ogc db measure GAME --by HANDLE writes
BUILD-SET.json in ogc-db's format (-o names another file) and the details beside it as BUILD-SET.detail.json,
which stays out of ogc-db's curated/ folder. HANDLE is a role or handle such as maintainer or tester-1, never a
real name. Every method is estimated from every chunk of every file (--methods all: every zstd level, not only 1, 3,
6, 9 and 15); on Linux the game's files are only read. On Windows each WOF algorithm is also compressed for real and
measured, which rewrites the game four times and needs room for it uncompressed; --restore stores every file as it
was at the end. Neither file holds a path, a user or a computer name. Nothing is sent.
Sharing results is a second setting in the app, Share results anonymously, off until you turn it on and
confirm what it sends. Then every analysis estimates all the methods a contribution carries (this costs extra CPU
time, at low priority), and each game's result is queued: one small record per game with its store id, build, a size
class, the expected savings per method and the share of data that does not compress, never a name, path or
identifier. View queue in the settings and ogc db outbox --show show exactly what would be sent, and either
deletes it. The app sends while it is open, one game at a time, at a random time 1 to 24 hours after it was queued
and at least two hours after the one before; ogc db send sends what is due on request. The command line and the
background task only queue. See Privacy.
Choosing a level: level 3, the default, is the sweet spot. Higher levels take far longer to compress, save only
a few percent more, and make no noticeable difference to loading times. Levels range from 1 to 15. Without
--level, a Steam game keeps the level it was compressed with (an app installed later into its folder, as an
episode of Half-Life 2, takes the folder's), and a folder given with --dir gets level 3;
a level other than before rewrites the files at that level.
No_COW folders: btrfs never compresses files marked No_COW: those in a folder some guides tell you to
chattr +C against fragmentation, and every file written to a drive mounted with nodatacow. Nor does it compress
files written to a drive mounted with nodatasum, which keeps no checksums for them; on such a drive every file not
compressed yet is left alone, as the two cannot be told apart. These files are left as they are and counted apart in
the summary, the analysis promises no savings for them, and ogc dedupe lets their identical copies share their data.
Identical files: ogc dedupe finds files of the same size and content in the selected games and prefixes and lets
btrfs keep their data once. Only files the compressor has finished with take part (compressed, found incompressible,
or No_COW): compressing a shared file later would give it its own copy again. For the same reason, a compression at another level leaves files whose compressed data is
shared as they are; --unshare rewrites them anyway. It needs Linux 5.10 or newer; before Linux 5.18, files only
share data with files on the same mount, so a library in a subvolume mounted elsewhere is deduplicated on its own.
How much it saves depends on the library: copies of the same runtimes and engine files are common, while the DLLs
Proton places in its prefixes are usually shared with the Proton installation already.
Leaving games alone: an excluded game, and its Proton prefix, is skipped by ogc compress (also when named),
ogc dedupe, the timer, the app and the compression pass of a drive migration. The list lives in
~/.config/opengamecompressor/excluded.tsv, one game per line starting with its app id; comments (#) you add
there are kept. Folders given with --dir are taken as given.
Own folders: the folders added in the app are listed in ~/.config/opengamecompressor/folders.tsv, one absolute
path per line (~/ works too; comments are kept). Every command sees them as games of the launcher Folder:
ogc list, --all, ogc exclude, ogc dedupe and the timer, which compresses one once it is new (with
--include-new). A folder records no version, so the timer does not notice files added to it later; compressing it
again from its ⋯ menu, or with ogc compress, compresses them. A folder that is missing (a drive not connected) is left out with a warning.
On Windows the commands work alike, with Windows' algorithms in place of the zstd level: see Windows.
Windows
OpenGameCompressor runs on Windows too, with the same app and the same ogc commands. There it compresses with
Windows' own transparent compression, the Windows Overlay Filter (WOF), which compact /exe and CompactGUI use as
well: Windows decompresses a game's files as they are read, for every program, Steam sees the same files, and no
marker or other file is added to the games. Nothing needs administrator rights, but compressing a game whose files
your user may not open (below). How it works in detail:
Architecture.
Windows requirements
- Windows 10 22H2 or Windows 11, 64-bit (x64). It has been tested on Windows 11 so far; there is no ARM64 build yet.
- Games on a local NTFS drive. FAT, exFAT, ReFS and network drives have no WOF and are refused with the reason, as are Windows' own folders, the Xbox app's games and OneDrive folders.
Installing on Windows
Each release after v0.1.0-alpha.1, which came
before the Windows port, carries two Windows downloads, each with its .sha256:
| Download | What it does |
|---|---|
OpenGameCompressor-<version>-x64-setup.exe |
Installs for your user alone into %LOCALAPPDATA%\Programs\OpenGameCompressor, without administrator rights and without a UAC prompt. It adds a Start-menu entry and an entry in Windows' installed apps, and, if you tick the optional component Background task (off by default), the background task. A newer version installs over the older one in the same folder and leaves the task as it is; close the app first. |
OpenGameCompressor-<version>-x64-portable.zip |
The same files, without an install. Unpack it anywhere; it holds the folder OpenGameCompressor-<version>-x64, whose bin\ogc-gui.exe starts the app. |
"Windows protected your PC": the Windows downloads are not signed yet (see Code signing
policy), so SmartScreen may stop the installer and name an unknown publisher. Check the
download against its .sha256 first, in PowerShell Get-FileHash .\OpenGameCompressor-<version>-x64-setup.exe, which
prints the SHA-256 to compare; then choose More info and Run anyway.
First steps on Windows
Start OpenGameCompressor from the Start menu, go to Game library and press COMPRESS ALL; the app works as on Linux, without the pages and settings that are btrfs' (moving a drive, Proton prefixes, sharing identical files). It finds the games of Steam, the Epic Games Launcher, GOG (Galaxy or GOG's own installers), Heroic, Ubisoft Connect and the EA app; the folder button in the header bar adds any other folder. The Xbox app's games are shown but cannot be compressed, and Battle.net's are not looked for yet.
Settings → Compression method picks the algorithm: Fast (XPRESS4K), Balanced (XPRESS8K), the default and recommended, Strong (XPRESS16K) or Maximum (LZX), which frees the most space but compresses slowest and needs more processor time while loading; it suits games that are rarely updated. A game's ⋯ menu compresses it with another method, or decompresses it. The savings after compressing are exact, as NTFS reports them, without "≈". A game's card also says when it is already compressed by another tool, stored with the old LZNT1 compression, loads with DirectStorage, has known problems once compressed, needs administrator rights, or lies in a library Linux uses too; the FAQ says what each means.
The app, ogc and the background task keep their settings, the excluded games and the own folders in
%APPDATA%\OpenGameCompressor, and their records, the history and the analyses in %LOCALAPPDATA%\OpenGameCompressor.
The command line on Windows
ogc list, analyze, compress, decompress, exclude, history and timer work on Windows; dedupe and
migrate are btrfs' and Linux' alone, and the help there does not list them. The installer does not add ogc to
PATH; in PowerShell:
cd "$env:LOCALAPPDATA\Programs\OpenGameCompressor\bin" # or the bin folder of the portable zip
.\ogc list # launchers, games, and what they are compressed with
.\ogc analyze --all # what xpress4k, xpress8k (the default, *), xpress16k and lzx would save
.\ogc compress "Portal" # xpress8k, or the algorithm the game was compressed with before
.\ogc compress "Portal" --algorithm lzx # another algorithm (the same as --level wof:lzx)
.\ogc compress "Portal" --remove-lznt1 # remove Explorer's old NTFS compression (LZNT1) first, then compress
.\ogc decompress "Portal" # undo it, and leave the game alone from then on
.\ogc timer enable --include-new # the background task, also for newly installed games
epic:NAME, gog:NAME, heroic:NAME, ubisoft:NAME or ea:NAME picks a game of one launcher, --dir a folder
once, as on Linux. A game the launcher is installing or updating is left alone, as Steam's are; as Ubisoft Connect and
the EA app record no download in progress, --include-new takes up a game of theirs only once it has a version. A
game another store installed and Ubisoft Connect or the EA app records too is listed once, as that store's.
Files stored with another algorithm already (CompactGUI's LZX, say) get the algorithm you name with --algorithm or
--level where they then take no more space, and all of them with --force. Without one they are switched only
where that saves at least 3 %. ogc compress says how many it left so and with which algorithm, and ogc analyze
names the games stored with another algorithm below its table. A game whose data is mostly stored with another
algorithm is recorded with that one, so that ogc list and its updates go by what its files have. Files another
program writes to while they are compressed, and files too large for the room left on the drive, are left for a
later run: the game is not recorded as fully compressed until then, and the run ends with an error. A later
ogc compress takes these files up, and so does ogc auto, with --include-new for a game that was not recorded as
compressed before. On a hard disk one file is compressed, or decompressed, at a time.
The background task on Windows
Recompress after game updates under Background task (Task Scheduler) in the settings, the installer's
component Background task, or ogc timer enable (with --include-new for newly installed games too, and
--algorithm for theirs; ogc timer status, ogc timer disable) set up a task of your own in Windows' Task
Scheduler, OpenGameCompressor Auto-<your account's SID>. It runs every hour and 15 minutes after you sign in, only
while you are signed in, never with administrator rights and at below-normal priority, and recompresses the games
their launcher has updated since, with the algorithm each was compressed with.
It does not start on battery, while a game runs, while a program runs in exclusive full screen or a presentation, or
while another compression runs; a run in progress ends after the files in progress when you unplug, when a game
starts or a program goes to full screen, and after 5 hours 45 minutes. It leaves alone the excluded games, games
their launcher is installing or updating, and, each noted once a day in the history: games whose files need
administrator rights,
games that load with DirectStorage, games with known problems once compressed, and games in a Steam library Linux
uses too (see the FAQ). What its last run printed is in
%LOCALAPPDATA%\OpenGameCompressor\state\background.log. Details:
Architecture.
Compressing as administrator
A game whose files your user may not open "needs administrator rights": ogc and the app say so and ask for nothing by
themselves. Compress as administrator on its card, or ogc compress --elevated GAME, compresses that one game
with them: Windows asks first, every time, and only that game's folder, as its launcher records it, is compressed.
The background task never asks and leaves such games alone. Compressing needs no write permission otherwise, and
Steam's default library in Program Files (x86) needs no administrator rights either. How the program with
administrator rights keeps to the one folder:
Architecture.
Compressing as administrator has not been tried on a real PC yet.
Uninstalling on Windows
Compressed games stay compressed and keep working without OpenGameCompressor, as Windows reads WOF itself. To have
them take their old space again, decompress them first: Decompress in a game's ⋯ menu, or
ogc decompress GAME. ogc decompress --all decompresses every game it lists, also those another tool such as
CompactGUI compressed, and excludes each one it decompressed.
- Installed: close the app, then uninstall OpenGameCompressor in Windows' settings, under Apps, or run
uninstall.exein its folder. It turns off and removes the background task, and removes the programs, the Start-menu entry and its registry entries. Then it asks whether your settings and records go too,%LOCALAPPDATA%\OpenGameCompressorand%APPDATA%\OpenGameCompressor; by default they stay.uninstall.exe /Suninstalls without a question and keeps them,/REMOVEDATAremoves them. - Portable: if you turned the background task on, run
bin\ogc.exe timer disable(or switch it off in the app) first, then delete the folder, and the two data folders above if you want. The app also registers itself for its notifications at every start, inHKEY_CURRENT_USER\Software\Classes\AppUserModelId\LevelXStudios.OpenGameCompressorandHKEY_CURRENT_USER\Software\Classes\opengamecompressor; these two keys can be deleted with the Registry Editor.
Moving a drive to btrfs
Is your game drive still ext4 or NTFS? The migration wizard (in the app, or ogc migrate) takes care of it. The
tool never selects a drive on its own: it lists all non-btrfs drives, explains why some of them can't be selected
(system drive, swap, encrypted container, …), and you choose.
Dual boot: a Steam library on NTFS that Windows compressed (with compact, CompactGUI or OpenGameCompressor on
Windows) is told in ogc list and above the drive's games in the app, with what the NTFS driver in use does with such
files, tried on one of them. In short (from the drivers' documented behaviour; not yet tried on real drives): ntfs-3g
reads them only with the plugin ntfs-3g-system-compression, the newer ntfs driver reads such files as zeros before its
WOF support (Linux 7.3, where the kernel enables it), and ntfs3 does not map them as Proton loads programs, so the games
do not start; a game compressed with Explorer's "compress contents" (LZNT1) is told where the driver fails with it
alike. On Windows, a Steam library that Linux uses too (it holds Proton's steamapps\compatdata) gets the matching hint
in ogc list and on its games' cards in the app, and the background runs leave its games alone.
| Method | Works for | What happens |
|---|---|---|
| Convert in place | ext2/3/4 | btrfs-convert turns the filesystem into btrfs and keeps all data. A rollback image stays until you have checked that your games still start; until then the drive can go back to its old filesystem. |
| Format and download again | any filesystem | The drive is formatted as btrfs. Data you select is backed up to another drive and copied back afterwards, then Steam downloads the games again, and each game is compressed as soon as it has arrived. Of the folders of Steam games, only what is not as Steam installed it is backed up and put back once Steam has delivered the game: saves, mods and settings, found with Steam's own list of the game's files, or by their times and names where Steam keeps none. Logs and caches are not. |
In the app, the wizard recommends the method that fits the drive and says why, and compares both for your drive:
how long until you can play again (the download for a 100 Mbit/s and a 1 Gbit/s line, and the backup at the same
cautious pace the confirm step uses for when the password is asked), whether it needs the internet, whether it can be
undone (a converted drive can go back to its old filesystem until you remove the rollback image; going back loses
what was written to it meanwhile), and what it risks. It checks whether btrfs-convert can convert the drive as soon as you have chosen it.
A drive that is only not mounted yet is listed with a MOUNT button, which mounts it the way the file manager does.
Along the way the tool:
- Scans the drive and preselects everything that can't be downloaded again: other launchers, non-Steam folders,
Proton prefixes with save games and, for a re-download, the saves, mods and settings in each Steam game's folder,
game by game (very large ones, which a game's own updater may have written but may as well be mods, are listed but not
preselected). A game's saves and mods go back once Steam has delivered the game, never over a file the game or you
wrote after that: such files are kept, and named with their copy in the backup. Data that is not backed up is said in red above the list and on its own row,
and before the start it has to be accepted as lost separately, with what it holds (such as
roms · saves · bios). - Creates the backup on a different drive and checks that there is enough free space: the backup itself and 2 GiB
that stay free as a safety buffer, both shown. The backup folder must be
on a Linux filesystem: FAT and exFAT cannot store the links in Proton prefixes. A folder held in memory (tmpfs,
such as
/tmpon many systems) is refused, because a restart would erase the backup. So is a pool that combines folders of several drives (mergerfs, unionfs, overlay): it might put the backup on the drive being formatted. The wizard lists your home folder and the other mounted drives with their free space, says which of them can hold the backup and why not, and picks the one that fits best; any other folder can be chosen as well. - Converts or formats the drive through a small privileged helper. The helper re-checks the drive's UUID and
filesystem and makes sure no process is using it.
/etc/fstabis updated to btrfs withcompress=zstd, and the old file is kept as a backup. - Restores your data, gets Steam to download the games one at a time, and compresses them. While it waits, the app lists every game with where it stands (compressed, being compressed, how much Steam has downloaded, paused by Steam with a button to Steam's downloads), what is left to download and when it checks again, and what to look at when Steam does not download.
After a conversion the app lists your games with PLAY, which starts one through Steam, and a check for each that
runs as before, plus one for the other files on the drive. REMOVE ROLLBACK waits for a check (or for "Skip the
test"); the screen says how much space removing the image frees at least, and the games are compressed after it. BACK TO EXT4… turns the drive back
into exactly what it was before the conversion. It asks first and lists, game by game, what was written to the drive
since, which is lost; files deleted since come back. The drive is unmounted for about a minute, and a rollback that is
cut short, by a power loss say, is finished by running it again; until then the drive is not mounted at boot, and the
start of the computer does not wait for it. One cut short before it changed anything can also be given up with
KEEP BTRFS. If the old filesystem was mounted and written to while going back was unfinished, the app writes
nothing over it and says so. A drive converted by an older version of the app,
whose helper kept no record of it, is not turned back by the app: it shows the steps to do it by hand, naming the drive as it is connected now. A balance of the
drive (btrfs balance, also a scheduled one) moves the data of the old filesystem and makes the way back impossible.
At the end the app says what the migration brought (the drive's space before and after, the games compressed) and
what needs you: a drive that no line of /etc/fstab mounts at every start (with the line to add), a top folder that
now belongs to you, games Steam did not deliver (with a button that installs them in Steam), games not compressed.
It offers to compress the other launchers' games on the drive in the game library, which asks first.
Before anything starts, the app's data and confirm steps show a checklist that checks again by itself every few
seconds: the helper and pkexec, a window that can ask for the password, the tools the helper needs (mkfs.btrfs;
btrfs-convert and e2fsck for a conversion), whether the drive can be converted, the backup folder and its space,
Steam (with a button that asks it to close), other programs that use the drive, and the power supply. Each problem
comes with what to do about it, and the start stays off while one is left. The confirm step also says when the
administrator password will be asked: right at the start, or after the backup, in about how many minutes.
Every phase is saved, so an interrupted migration picks up where it stopped. The app shows each phase with how far
it got (amount, speed and time left), says in large when the administrator password is asked for and whether
anything on the drive has been changed yet, and warns when Steam is started during the backup. CANCEL asks
first and pauses; the drive stays as the step left it, which the app says. When a run stops, a card tells why and
how to go on: RETRY with the one thing to fix first (close Steam, which a button does, plug in the power, mount
the drive, connect the backup drive, check a drive that failed to read or write), or NEW PLAN where retrying
could not work, as when something on the drive changed after the backup. Coming back
to a waiting migration shows what it is, how far it got, what became of the drive and the last error, and the
button names the next step. What every run said is kept in migration.log beside the saved plan.
Outside the wizard, the app's header bar says how far a migration is ("Migrating sda1 · backup 30%", "Waiting for
Steam (3 left)", "Migration paused", "Migration needs you"; in short on a narrow window), MIGRATE in the sidebar
carries a badge, and the dashboard shows a card with SHOW THE MIGRATION while a migration is paused, waits or needs
you. Closing the window during a step that must not be interrupted keeps it open and says why; the backup and the
copy back can be stopped from there. Steam's downloads can take hours: when you close the
window while the migration waits for them, the app offers to keep compressing in the background (ogc migrate continue, which never runs a step that needs the administrator password) and notifies you when all downloads have
arrived and when the migration is finished. The app takes over again when you open it.
On the command line:
ogc migrate drives
ogc migrate plan --device /dev/nvme0n1p1 --method redownload --backup-dir /mnt/backup
ogc migrate run --confirm nvme0n1p1 # add --accept-data-loss if you left data out
ogc migrate continue # wait for Steam's downloads and compress them as they arrive
ogc migrate status
ogc migrate remove-rollback --confirm nvme0n1p1 # a conversion, once the games run: frees the old filesystem's space
ogc migrate rollback --confirm nvme0n1p1 # a conversion instead: back to the old filesystem, losing what was written since
ogc migrate keep-btrfs --confirm nvme0n1p1 # a rollback cut short before it changed the drive: stay on btrfs
ogc migrate delete-backup # once the migration has finished
The backup gets a folder of its own, opengamecompressor-backup/<drive id>, inside the folder you name.
delete-backup removes only that; anything else in your folder stays. run and continue exit with 0 once the
migration has finished, 3 while games are still downloading or could not be compressed (run it again later), and 4
when a conversion waits for remove-rollback (or rollback). rollback exits with 0 once the drive is its old
filesystem again, keep-btrfs with 4, as the conversion then waits for remove-rollback again.
⚠️ Formatting erases the drive. Read the plan, and keep your own backup of anything important.
Safety
- Copy-on-write: btrfs writes compressed data to new blocks before it releases the old ones. An interrupted run
never leaves a broken file. Ctrl-C, closing the terminal, and a logout or shutdown, also during a timer run, stop
ogcand the app once the files in progress are done, so the finished files keep their markers and their modes; a second Ctrl-C stops them at once. - Hands off busy games: games that are running, downloading, updating or being verified are skipped, and so are
folders with open files. A folder several apps share (Half-Life 2 and its episodes) is left alone while Steam
downloads, updates or verifies any of them, by the app,
ogc compress,ogc decompressand the timer alike. A Steam or Proton game started during a run pauses it until the game has exited. - Snapshot aware: snapshots (snapper, Timeshift, btrbk, ...) and other copies still reference the old uncompressed data, so compressing would increase disk usage until they are gone. OpenGameCompressor detects snapper's snapshots and data that is mostly shared, and asks first.
- Stops on a full drive: if the drive fills up during a run (for example because snapshots keep more of the old data than the check saw) or turns read-only, the run stops there, leaves the remaining files as they are, says why once, and leaves the other games on that drive alone. A btrfs subvolume that reaches its quota limit is treated the same way, but only the games in that subvolume are left alone. A game in a read-only subvolume or snapshot is refused before the run, with that reason.
- Sharing is verified:
ogc dedupechanges no file. The kernel compares two files byte by byte, with both locked, before one uses the other's data; a file that changed in between is left alone. - No pointless rewrites: an extended attribute (
user.opengamecompressor) marks finished files. Unchanged files aren't touched again unless the level changes, and SSDs aren't worn out needlessly. A marked file whose data something else decompressed (asbtrfs filesystem defragmentwithout-c) is noticed and compressed again. - Migrations are guarded: the drive name has to be typed in, a box naming what is not backed up has to be ticked, the helper only runs through polkit, whose password prompt names the device and mount point it is about to change, and nothing is formatted while data you did not accept losing is still unprotected. The app asks before it deletes the backup, naming what only the backup still holds, and before it discards a plan. It keeps the computer from sleeping or logging out while a migration runs or waits for Steam, and does not convert or format a drive while the computer runs on battery.
FAQ
These answers are for Linux; those for Windows follow them.
Will my games load slower? Hardly. The kernel decompresses the data as it is read, and zstd is fast enough that loading times barely change; the level makes no noticeable difference to them either. On a slow drive (a hard disk, a microSD card) less data has to be read, which can make up for it. Try one game first if in doubt; it can be undone.
Does it break anti-cheat, DRM or mods? No. The compression happens below the files: every program, the game and its anti-cheat included, reads exactly the same bytes as before. File names, sizes and contents stay the same.
What about Steam's "Verify integrity of game files"? Verifying reads the files and finds them unchanged, so nothing is downloaded again. What Steam writes during an update lands uncompressed (see Why a separate tool?); auto-recompress, or SHOW: UPDATED and COMPRESS ALL in the library, compresses those files again.
What if I play while it compresses? A Steam game, or any game running with Proton, pauses the job until you quit it. Games that are downloading, updating or running are left out.
How do I undo it? Decompress a game from its ⋯ menu in the library, or with
ogc decompress "<game>"; it is left alone from then on. This needs Linux 6.17; on older kernels, reinstalling the
game brings it back uncompressed. To stop compressing a game without undoing it, exclude it (⋯ menu, or
ogc exclude add).
How do I uninstall it? Compressed games keep working without OpenGameCompressor, so decompress first only if you want the space used as before.
- Bundle:
~/.local/share/opengamecompressor/uninstall.sh. It turns off the timer and removes the programs; your settings and history stay in~/.config/opengamecompressorand~/.local/state/opengamecompressor. Remove the migration helper first, if you installed it:sudo ~/.local/share/opengamecompressor/system/install-helper.sh --uninstall. - Arch package:
ogc timer disable, thensudo pacman -R opengamecompressor.
A migration says the helper is missing. See The migration helper. The app checks for it before you choose a drive, and shows the command that installs it.
On Windows
Will my games load slower? Mostly not: Windows decompresses the files as they are read. Fast, Balanced and Strong (the XPRESS algorithms) cost little; Maximum (LZX) needs more processor time while loading. Try one game first if in doubt; Decompress in its ⋯ menu undoes it. A game you start while a job runs pauses the job until it has exited.
Does it break anti-cheat, DRM or mods? It is unlikely to. WOF works below the files: every program, the game and its anti-cheat included, reads exactly the same bytes as before, and file names, contents and modification times stay the same. The games tried on a real PC so far started and ran as before. A file written later, by an update or a mod, is stored uncompressed again until the next compression. Should a game misbehave all the same, decompress it; it is left alone from then on.
What about Steam's "Verify integrity of game files"? Tried on a real PC with four games, compressed with XPRESS8K and with LZX: Steam found nothing to repair, downloaded nothing and the games started; where it was checked, the files stayed compressed. What Steam writes during an update is stored uncompressed: the card then says "Updated by Steam since compressed with …", and the background task, or compressing the game again, compresses those files again.
The drive's free space grew by less than the app says it saved. The app counts what the game's files take less, exactly as NTFS reports it, not the change of the drive's free space, which other programs change too. Restore points can also hold on to the space: on a drive that System Restore (Volume Shadow Copy) protects, by default only the system drive, Windows keeps the data the files had when a restore point was made, so the free space can grow by less than the saving, or shrink again later, until those restore points are deleted or replaced by newer ones. Their space is limited to what System Protection allows for the drive; its settings show that and can delete restore points.
Some games are left alone: DirectStorage and known problems. A game that loads its data with DirectStorage (it
brings dstorage.dll or dstoragecore.dll) may load more slowly once its files are compressed. Its card and
ogc analyze and ogc compress say so, the background task leaves it alone, and you can still compress it when you
ask for it. Games with a known problem once compressed are treated alike, from a small built-in list of the reports in
CompactGUI's issue #101: Guild Wars 2 and Secret World Legends (they decompress themselves at start and hang
meanwhile), Ghost Recon Wildlands (stops at its main menu) and The Lord of the Rings Online (hangs while patching).
I dual boot with Linux and share a Steam library on NTFS. Linux reads Windows' compression badly or not at all (from
the drivers' documented behaviour; not yet tried on real drives): ntfs-3g reads it only with the plugin
ntfs-3g-system-compression, the newer ntfs driver reads such files as zeros before its WOF support (Linux 7.3, where
the kernel enables it), and ntfs3 reads them but cannot map them as Proton loads programs, so the games do not start
under Linux, and it decompresses every file written to, for good. On Windows, a Steam library that Linux uses too (it
holds Proton's steamapps\compatdata) gets a hint in ogc list and on its games' cards, and the background task leaves
its games alone; compressing one when you ask for it still works, with a warning. On Linux, ogc list and the app tell
which games on NTFS Windows compressed, and what the driver in use does with them, tried on one of their files
(more). Keep games you play under Linux uncompressed on Windows, or decompress them there.
What about games CompactGUI or compact /exe compressed? They use the same WOF compression. Their card says
"Already compressed by Windows (LZX)", and ogc analyze names them below its table, so that little to save is
explained. Their files stay as they are unless the algorithm you chose stores them in no more space (from the
command line without --algorithm, only where it saves at least 3 %); --force switches them all. The savings the app shows count only the
games OpenGameCompressor compressed. Decompressing such a game removes CompactGUI's compression too.
What about Explorer's "Compress contents" (LZNT1)? Files stored with NTFS' older LZNT1 compression are left as they
are, and the card says "Old NTFS compression (LZNT1)". Remove old NTFS compression first in its ⋯ menu, or
ogc compress GAME --remove-lznt1, returns them to plain storage and then compresses them with WOF, where WOF stores
them in no more space (all of them with --force). That needs write permission to the files, and it never happens in
the background.
How do I uninstall it? See Uninstalling on Windows. Compressed games keep working without OpenGameCompressor.
Windows says "Windows protected your PC" or names an unknown publisher. The Windows downloads are not signed yet; see Installing on Windows and the Code signing policy.
Development
cargo fmt --check
cargo clippy --all-targets --locked -- -D warnings
cargo test --locked
- Conversion tests run against image files and skip themselves when the tools are missing.
- btrfs tests work in
target/tmp, or in the folderOGC_TEST_BTRFS_DIRnames, and skip themselves when it is not on btrfs (OGC_TEST_REQUIRE_BTRFS=1makes them fail instead). CI runs them in the VM test. Those of the timer also skip while a game runs or the computer runs on battery. - GUI tests need a display. A headless one works well:
gtk4-broadwayd :7 & GDK_BACKEND=broadway BROADWAY_DISPLAY=:7 cargo test - End-to-end migration test boots a disposable VM (qemu inside a container, KVM if available). It migrates a
fake game drive with both methods, including a simulated Steam client:
scripts/vm-e2e.sh # or: scripts/vm-e2e.sh convert - Release bundle:
scripts/build-bundle.shbuilds it, andscripts/check-bundle.shchecks the glibc versions in itsBUNDLE_INFO, installs it into a made-up home folder and root (with a stand-in forsystemctl), validates the menu entry and uninstalls it again. The CI builds the programs for an old glibc first and passes them in withscripts/build-bundle.sh --programs DIR. - Windows port: the library and
ogc, with their tests, must pass clippy for Windows (x86_64-pc-windows-gnullvm, built with llvm-mingw), and their portable tests must pass under Wine. Both run in a container, so the host needs neither the target nor llvm-mingw nor Wine:
Wine runs with a prefix of its own inscripts/windows/in-container.sh scripts/windows/check.sh # clippy, as the CI job windows-check scripts/windows/in-container.sh scripts/windows/wine-test.sh # tests under Wine, as windows-wine-testtarget/windows/, never~/.wine, and without a display or crash dialog. What exists on Linux only says so there; see Platforms. - CI (Forgejo Actions) checks formatting, lints, runs the tests, checks the Windows build, and builds the Arch
package and the release bundle. It also builds and tests the Windows installer and portable zip, and attaches them
to releases. The VM test runs every night and for pull requests that change the code it runs:
ogc, the helper and the btrfs tests as Linux builds them, without the desktop app, Windows' own modules and the unit tests. - Windows measurement probe (
tools/ogc-probe/, a crate of its own outside the Linux build):ogc-probe.exemeasures WOF compression, Steam libraries and access rights on a Windows PC, where it answered the Windows port's first questions. It is cross-built in a container and tested natively, under Wine and with PowerShell 7 (see Architecture):tools/ogc-probe/build/dist.sh # exe, German guide, scripts/windows/measure-wof.ps1, SHA256SUMS.txt tools/ogc-probe/build/wine-test.sh # its unit tests as a Windows program
Translations live in src/i18n/<language>/*.ftl (Project Fluent). The
tests make sure every language has the same keys and every message formats. German uses the impersonal form
throughout ("Laufwerk auswählen", never "du" or "Sie", nor "ich"), which a test checks. To add a language, copy en/ and
register it in src/i18n/mod.rs; then add its texts from system.ftl to the desktop entry and the polkit policy in
data/, as the test that compares them prints.
Project layout
src/
├── main.rs, commands/ CLI (ogc)
├── gui/ desktop app (ogc-gui), incl. the migration wizard
├── helper/ privileged migration helper (ogc-migrate-helper)
├── btrfs.rs, compress.rs defragment/FIEMAP ioctls and the compression engine
├── estimate.rs, analyze.rs
├── steam/ library and manifest parsing
├── platform/, paths.rs what differs between Linux and Windows (Linux's processes, power and
│ notifications in platform/linux/), and where files are kept
├── codec.rs zstd levels and WOF algorithms, named once
├── migrate/ drives, plan, backup, fstab, runner
├── systemd.rs, auto.rs background timer
└── i18n/ translations
tests/ integration tests, tests/vm/ for the VM test
packaging/arch/ PKGBUILD
packaging/bundle/ install.sh, uninstall.sh and system/ of the release bundle
tools/ogc-probe/ Windows measurement probe (own crate, not part of the Linux build)
scripts/windows/ measure-wof.ps1, the probe's compact.exe-based fallback
Documentation
- Architecture: how compression, the Steam integration, the migration and the helper work
- Roadmap: open tasks, known limitations and ideas
Code signing policy
Free code signing provided by SignPath.io, certificate by SignPath Foundation.
Not yet in use: the Windows builds are to be signed through the SignPath Foundation's free code signing for open source projects once it accepts the project; until then they are unsigned, and Windows may warn of an unknown publisher (see Installing on Windows).
- What will be signed: the Windows programs this repository builds,
ogc.exe,ogc-gui.exe,ogc-background.exeandogc-elevated.exe, and the installerOpenGameCompressor-<version>-x64-setup.exe, as they come in the installer and in the portable zip. The libraries of other projects that the app ships beside them (GTK, libadwaita and their dependencies) and the Linux downloads are not signed with this certificate. - Where releases come from: every release is built by CI (Forgejo Actions,
.forgejo/workflows/ci.yml) from a tagged commit of this repository, after its tests pass, and attached to the release with a.sha256for each file. The third-party libraries come from packages pinned by version and SHA-256 (packaging/windows/msys2.lock); GTK is built from its pinned source. - Team roles:
- Privacy: This program will not transfer any information to other networked systems unless specifically
requested by the user or the person installing or operating it. OpenGameCompressor makes no network connections
unless asked to: it reads the launchers' records and the games' files on your computer, and game covers only as the
launchers keep them on your disk. Only what you click opens a web page or another program: the help and Report a
problem… open this project's pages in your browser, a game's Steam page opens Steam, and a migration on Linux that
formats a drive has Steam download its games again; what those do is their own business.
Community data: the program ships with a snapshot of the community database and uses it without any network
access. Newer data is downloaded only when you run
ogc db update, or at most once a day after you turn on Download current community data (off until then). A download fetches whole files fromhttps://db.opengamecompressor.de/v1/(latest.json, its signature and the snapshot it names), never anything about one game, so it reveals nothing about which games you have. Where that server fails, the same files come from the mirror in the database's repository onforgejo.skyfar.de, which may log requests like any Forgejo: at once forogc db update, and for the automatic download only a day later, when the server failed again. The server sees your IP address and the time, as for any download, and aUser-Agent: OpenGameCompressorwithout a version; nothing else is sent, no cookies, no identifiers.HTTPS_PROXY,ALL_PROXYandNO_PROXYare honoured; where the first of those set holds a proxy the program does not understand, nothing is downloaded rather than connecting directly. A SOCKS proxy (such as Tor'ssocks5://127.0.0.1:9050) resolves the host names itself, so no DNS query goes past it. The data is checked against the database's public key before it is used. Sharing results: off until you turn on Share results anonymously in the app and confirm it. Then, per game, one record of 1024 bytes goes tohttps://submit.opengamecompressor.de/v1/contribute: the store and game id, the game's build, whether its files are Windows' or Linux', a size class (steps of about 19 %), the expected or measured savings per method in ‰, the shares of data left alone in steps of 5 %, the estimator's generation, the week's salt and a proof of work. Never names, paths, launchers, accounts, hardware, the program's version, times or other games. Each game goes on its own connection (a new TLS session, no cookies, the sameUser-Agentas above, proxies honoured), at a random time 1 to 24 hours after it was queued, at least two hours apart and at most eight a day, so that records cannot be linked; the server sees your IP address for the request and does not store it. Shared results cannot be traced back and therefore not deleted afterwards; until they are sent, the queue (<state>/communitydb/outbox/) can be looked at and emptied, and turning the setting off deletes it. The program also fetches the database's signedlatest.jsonwhen the one it has is too old to give the week's salt. Only the app while it is open, andogc db sendwhen you run it, send;ogc analyze,ogc compressand the background task only queue. Games you leave alone (ogc exclude) are not shared. Estimating every method a record carries takes about ten times as long as an analysis (a small game up to 40 times, which is at most half a minute of CPU time): the app does it at low priority when it has nothing else to do, andogc analyzeafter its table; both only on AC power (ogc analyze --on-batterydoes it on battery too).sent.tsv, the record of what was sent, stays on your computer.
License
OpenGameCompressor is licensed under the GNU General Public License v3.0 or later.
The bundled Chakra Petch and IBM Plex fonts are under the SIL Open Font License 1.1 (data/fonts).
Inspired by CompactGUI and by this XDA Developers article about compressing a Steam library instead of buying another SSD.



