Skip to content

A helper script that redirects Steam Proton compatdata from NTFS to a local Linux filesystem using bind mounts, improving compatibility and avoiding corruption.

License

Notifications You must be signed in to change notification settings

Ikkitsuna/steam-ntfs-compat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Steam Proton NTFS Compatibility Helper

License: MIT Bash

Transparently fix Steam Proton compatibility issues on NTFS partitions using bind mounts

Français | English


🎮 The Problem

Running Steam games with Proton on NTFS partitions under Linux causes several issues:

  • Symlinks not supported - Proton requires symlink support for Wine prefix management
  • Case sensitivity - NTFS is case-insensitive while many Linux games expect case-sensitive filesystems
  • Permission issues - NTFS doesn't handle Linux file permissions properly
  • Performance degradation - FUSE-based NTFS drivers (ntfs-3g) can be slower for intensive I/O

This commonly manifests as:

  • Games failing to launch
  • Crashes during gameplay
  • Missing or corrupted save files
  • Poor performance in shader compilation

💡 The Solution

This script creates a transparent bind mount that redirects Steam's Proton compatibility data (compatdata) from your NTFS partition to your Linux native filesystem (ext4/btrfs/etc.), while keeping Steam pointing to the original location.

How It Works

Before:
  Steam → /mnt/GamingDisk/steamapps/compatdata (NTFS - problematic)

After:
  Steam → /mnt/GamingDisk/steamapps/compatdata (bind mount)
          ↓
          ~/.local/share/Steam-Compat/GamingDisk_compatdata (ext4 - works perfectly)

Steam continues to see compatdata on your external disk, but the actual data lives on your Linux filesystem where Proton works flawlessly.

� Technical Details: Why This Works

Why redirect compatdata?

The compatdata folder contains Proton's Wine prefixes. Each game has its own simulated Windows environment. On NTFS, these issues arise:

  • Symbolic links: Proton creates symlinks to manage Windows DLLs. NTFS doesn't support them natively (requires special privileges on Windows).
  • POSIX permissions: Wine configuration scripts require executable permissions (chmod +x). NTFS doesn't preserve them correctly.
  • Case-sensitivity: Some games check for files with specific casing. NTFS treats Config.ini and config.ini as identical.

Why redirect shadercache?

The problem: Modern games compile shaders on-the-fly. Vulkan and DirectX create cache files to speed up subsequent launches.

On NTFS:

  • NTFS transactions via FUSE are slow and can corrupt
  • Temporary files with generated names (e.g., shader_XYZ.tmp) cause name conflicts
  • File locking doesn't work correctly → crashes during compilation

Real example: Ace Combat 7 compiles ~10,000 shaders at startup. On NTFS, it crashes at 30%. On ext4, smooth compilation.

The .lock files problem

Context: Proton/Wine creates .lock files to synchronize access to shared resources (Wine registry, config files).

Why it's critical:

Game starts → Creates compatdata/123456/pfx/system.reg.lock
Game crashes → Process dies BEFORE removing the .lock
Relaunch     → Proton sees .lock → "Resource already in use" → Refuses to start

NTFS makes it worse because file handles don't close cleanly via FUSE. The script automatically cleans these orphaned files before each mount.

Why remove sockets and FIFOs?

UNIX sockets (-type s) and FIFOs (-type p) are special Linux files for inter-process communication.

  • On ext4: They auto-delete when the process dies
  • On NTFS via bind mount: If a crash leaves residues, they can block the next execution
  • Example: A Wine audio server might create /tmp/.wine-1000-audio as a socket. If the game crashes, the socket remains and blocks restart.

Preventive cleanup avoids these edge cases.

Why bind mounts are transparent

mount --bind /home/user/.local/share/Steam-Compat/compatdata /mnt/disk/steamapps/compatdata

This command tells the Linux kernel: "When a process accesses /mnt/disk/steamapps/compatdata, redirect it to the real folder on ext4".

Benefits:

  • ✅ Steam doesn't know files are elsewhere (no config modification needed)
  • ✅ System-level transparency (works with all games)
  • ✅ Native ext4 performance (no FUSE layer)
  • ✅ No impact on other Steam folders (like common/ which contains game binaries)

�📋 Requirements

  • Linux (any distribution)
  • Bash 4.0+
  • Root privileges (sudo)
  • Steam installed
  • An NTFS partition with Steam library

Optional Dependencies

  • gum - Enhanced interactive prompts (recommended)
  • fzf - Alternative interactive selection
  • rsync - Faster data copying with progress (falls back to cp)

Install optional tools on Debian/Ubuntu:

sudo apt install rsync gum fzf

🚀 Installation

Quick Install

# Download the script
curl -O https://raw.githubusercontent.com/Ikkitsuna/steam-ntfs-compat/main/gamingdisk_compat_helper.sh

# Make it executable
chmod +x gamingdisk_compat_helper.sh

# Move to system path (optional)
sudo mv gamingdisk_compat_helper.sh /usr/local/bin/steam-ntfs-compat

Manual Install

  1. Clone this repository:
git clone https://github.com/Ikkitsuna/steam-ntfs-compat.git
cd steam-ntfs-compat
  1. Make the script executable:
chmod +x gamingdisk_compat_helper.sh

📖 Usage

Basic Usage

Mount compatdata to ext4:

sudo ./gamingdisk_compat_helper.sh

Unmount when done:

sudo ./gamingdisk_compat_helper.sh --unmount

Advanced Options

# List all available disks with labels and filesystems (no root needed)
./gamingdisk_compat_helper.sh --list

# Use custom disk label
sudo ./gamingdisk_compat_helper.sh --label MyGameDisk

# Start fresh without copying existing compatdata
sudo ./gamingdisk_compat_helper.sh --no-copy

# Preview what will happen (no root needed)
./gamingdisk_compat_helper.sh --dry-run

# Show help
./gamingdisk_compat_helper.sh --help

Complete Command Reference

Options:
  -l, --label LABEL       Disk label to search for (default: GamingDisk)
  -u, --unmount          Unmount the bind mount
  -d, --dry-run          Show what would be done without executing
      --list             List all available disks with their labels and filesystems
      --no-copy          Skip copying existing compatdata (start fresh)
  -h, --help             Display help message

Examples:
  ./gamingdisk_compat_helper.sh --list              # List available disks (no sudo)
  sudo ./gamingdisk_compat_helper.sh                # Mount using default label
  sudo ./gamingdisk_compat_helper.sh -l MyDisk      # Mount using custom label
  sudo ./gamingdisk_compat_helper.sh --no-copy      # Mount without copying data
  sudo ./gamingdisk_compat_helper.sh --unmount      # Unmount bind mount
  ./gamingdisk_compat_helper.sh --dry-run           # Preview (no sudo)

🔧 Workflow Example

# 1. List available disks to find your disk label
./gamingdisk_compat_helper.sh --list

# 2. Close Steam if running
# (the script will prompt you)

# 3. Run the script
sudo ./gamingdisk_compat_helper.sh

# 4. Launch Steam and play!
steam

# 5. When done gaming, unmount (optional)
sudo ./gamingdisk_compat_helper.sh --unmount

⚙️ Making It Permanent (Systemd)

The bind mount is temporary and disappears on reboot. To make it automatic:

Option 1: Systemd Service

Create /etc/systemd/system/steam-ntfs-compat@.service:

[Unit]
Description=Steam NTFS Compatibility Helper for %i
After=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/steam-ntfs-compat --label %i
ExecStop=/usr/local/bin/steam-ntfs-compat --label %i --unmount

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable --now steam-ntfs-compat@GamingDisk.service

Option 2: Udev Rule (Auto-mount on plug)

Create /etc/udev/rules.d/99-steam-ntfs-compat.rules:

ACTION=="add", ENV{ID_FS_LABEL}=="GamingDisk", RUN+="/usr/local/bin/steam-ntfs-compat --label GamingDisk"

Reload udev rules:

sudo udevadm control --reload-rules

🔍 Troubleshooting

Script says "Cannot find mounted disk"

List all available disks with the --list option:

./gamingdisk_compat_helper.sh --list

Or check manually:

lsblk -o LABEL,MOUNTPOINT

Ensure your disk is mounted and use the correct label:

sudo ./gamingdisk_compat_helper.sh --label YOUR_ACTUAL_LABEL

Games still don't launch

  1. Verify the bind mount is active:
mount | grep compatdata
  1. Check file ownership:
ls -la ~/.local/share/Steam-Compat/
  1. Check logs:
cat ~/.local/share/gamingdisk_compat.log

Permission denied errors

Ensure you're running with sudo:

sudo ./gamingdisk_compat_helper.sh

Steam is running warning

The script requires Steam to be closed to prevent data corruption. Close Steam before running.

📊 Comparison: Before vs After

Aspect NTFS (Before) Bind Mount (After)
Symlinks ❌ Not supported ✅ Full support
Case sensitivity ❌ Case-insensitive ✅ Case-sensitive
Permissions ❌ Limited ✅ Full Linux ACL
Performance ⚠️ FUSE overhead ✅ Native filesystem
Proton compatibility ❌ Frequent issues ✅ Works perfectly
Shaders ❌ Crashes on load ✅ Smooth compilation on ext4
Locks (.lock) ❌ Blocking files ✅ Auto-cleanup on mount

🛡️ Safety Features

  • Steam detection - Automatically detects and offers to close Steam
  • Data preservation - Copies existing compatdata before mounting
  • Dry-run mode - Preview actions without making changes
  • NTFS verification - Warns if target isn't NTFS
  • Logging - Tracks all operations in ~/.local/share/gamingdisk_compat.log

🌍 Multi-Disk Support

You can use different labels for multiple gaming disks:

sudo ./gamingdisk_compat_helper.sh --label GamingDisk1
sudo ./gamingdisk_compat_helper.sh --label GamingDisk2

Each disk gets its own isolated compatdata directory.

❓ FAQ

Q: Will this affect my game files? A: No, only Proton's compatibility data (compatdata) is redirected. Your actual game files remain on NTFS.

Q: What happens if I reboot? A: The bind mount disappears. Re-run the script or set up a systemd service for automatic mounting.

Q: Can I use this with multiple Steam libraries? A: Yes, the script auto-detects steamapps folders and supports multiple libraries on the same disk.

Q: Does this work with Steam Deck? A: Yes, but Steam Deck uses ext4 by default. This is mainly for desktop Linux users with NTFS partitions.

Q: What if I want to remove everything? A: Unmount with --unmount, then optionally delete ~/.local/share/Steam-Compat/.

Q: Is this safe? A: Yes, your original data is preserved. The script copies existing compatdata before creating the bind mount.

Q: How do I find my disk label? A: Use ./gamingdisk_compat_helper.sh --list to see all available disks with their labels and filesystems. No sudo required!

Q: When should I use --no-copy? A: Use --no-copy if you want to start with a fresh Proton prefix, or if your existing compatdata is corrupted. This skips copying the old data and creates an empty compatdata directory. Note: Your games will need to re-download shaders and recreate Wine prefixes.

🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing)
  5. Open a Pull Request

📜 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Steam and Proton developers for making gaming on Linux possible
  • The Linux community for filesystem expertise
  • Everyone who tested and provided feedback

📞 Support


Made with ❤️ for the Linux gaming community

If this helped you, consider giving it a ⭐ on GitHub!

About

A helper script that redirects Steam Proton compatdata from NTFS to a local Linux filesystem using bind mounts, improving compatibility and avoiding corruption.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages