Feature Request: Add a built-in pre-configuration profile for legacy 32-bit strategy games (e.g., Medieval II: Total War massive mods)

Hello Lutris Development Team,

After extensive testing (over 40+ hours) on modern Linux distributions (specifically Zorin OS/Ubuntu layouts) with low-to-mid specs (8GB RAM, AMD/Intel integrated and discrete graphics), we discovered a highly stable configuration formula for legacy 32-bit strategy engines running massive community modifications (such as Divide & Conquer or Tsardoms for Medieval II: Total War).

Currently, these mods are completely unplayable on modern Windows 10/11 due to rigid OS memory management structures and broken DirectX 9 allocations, leading to constant “Out of Memory” runtime errors and graphic crashes. Linux via Lutris handles these games beautifully, but only if very specific, non-standard variables are manually applied.

We kindly request the integration of a toggle or a pre-configured profile inside Lutris tailored for “Legacy 32-bit / Heavy Modded Strategy Games” that automatically applies or suggests the following runtime parameters:

  1. Core Environmental Variables to Automate:
    • WINE_LARGE_ADDRESS_AWARE=1 — Absolutely critical. While the 4GB patch executable bit is modified manually, Wine frequently ignores the memory extension unless this exact flag forces a true 4GB virtual memory address space.
    • PULSE_LATENCY_MSEC=256 — Legacy engines suffer from massive audio buffer overflows on modern Linux audio servers during battles with thousands of units firing projectiles and triggering simultaneous sound effects. Forcing a safe buffer window between 128 and 256 completely stops the hard crashes caused by the audio subsystem. Our tests show that with this variable, whenever the AI triggers sudden heavy voice lines (like general deaths or army status updates), it only results in a minor, harmless audio stutter instead of an instant desktop crash.

• STAGING_SHARED_MEMORY=1 — Crucial for smooth texture and asset streaming between the Wine layer and Linux subsystem, removing micro-stutters during heavy computational frames (like AI “End Turn” processing cycles).
• LC_ALL=C — Prevents localized decimal/string formatting errors within older game engines that cause unintended string read crashes.

  1. Recommended Runner Defaults:
    • DXVK: Enabled (Stable v1.10.3 preferred for DX9 wrappers).
    • VKD3D: Disabled by default for DX9 profiles to save sub-allocator overhead.
    • Esync / Fsync: Disabled or optional. Surprisingly, our practical tests showed that modern synchronization protocols conflict with these specific unoptimized legacy engines, leading to engine lockups. Keeping them OFF yields 100% stability.

Implementing an easy-to-use profile template like this within Lutris would make Linux the ultimate, definitive refuge for retro PC strategy gaming communities who are currently being locked out of their favorite games by Windows updates.

Thank you for your incredible work on Lutris!

:video_game: Universal Stability Blueprint for Heavy Modded 32-bit Engines (Lutris / Linux)

Verified deployment layout for the Medieval II: Total War engine (tested extensively across Tsardoms 3.0, Divide & Conquer, GoT, and DCI: Last Alliance 2.0).

:hammer_and_wrench: 1. Environmental Variables Table (Lutris System Options)

Inject the following keys and values into your Lutris Environment Variables table to stabilize the Wine/DXVK runtime translation layer:

:brain: Core Memory Management & Throughput

  • WINE_LARGE_ADDRESS_AWARE=1 — Absolutely critical. Forces a true 4GB virtual memory address space. This prevents Wine from ignoring manual 4GB executable patches, neutralizing “Out of Memory” crashes during heavy computational cycles.
  • STAGING_SHARED_MEMORY=1 — Crucial for smooth texture and asset streaming between the Wine layer and the Linux subsystem. This completely removes micro-stutters during heavy inter-turn processing phases.
  • LC_ALL=C — Prevents localized decimal/string formatting parsing errors within older game engines that cause unintended crashes when reading configuration files.

:computer: Low-to-Mid Specs & Integrated GPU Safeguards (iGPU - e.g., AMD Ryzen / Intel Iris Xe with 8GB RAM)

If running on shared system RAM architectures, these explicit tokens block the aggressive allocation nature of Vulkan from oversaturating host memory and triggering VK_ERROR_MEMORY_MAP_FAILED allocation errors:

  • Key: DXVK_CONFIG | Value: dxvk.maxChunkSize = 64; dxvk.vramBudget = 2048
    • Why it works: It forces the translation layer to fragment high-fidelity graphical assets into safe 64MB processing blocks and hard-caps the VRAM budget at 2GB, preventing the Linux host from triggering Out-Of-Memory (OOM) routine panics.
  • Key: dxvk.enableGraphicsPipelineLibrary | Value: False
    • Why it works: Mandatory for older integrated chipsets under Linux; leaving this active causes a severe thread deadlock inside the Vulkan driver, trapping the game engine in an infinite loading hourglass freeze on boot.
  • Key: dxvk.gplCache | Value: False
    • Why it works: Completely disables the generation of complex pipeline caches that trigger internal resource leaks and compiler hangs during heavy mid-turn script evaluations on integrated hardware.

:lock: 2. Frame-Pacing & Thread Synchronization (The Esync Breakthrough)

  • Key: DXVK_FRAME_RATE | Value: 60 (or your native monitor refresh rate)
  • Key: d3d9.maxFrameLatency | Value: 1
    • Why it works: Forcing a strict frame latency limit of 1 blocks DXVK from buffering frames ahead. This keeps the GPU perfectly synced with heavy CPU script threads, preventing the notorious post-battle data-dump crash (Runtime Error R6025).
  • The Esync Sync Shift: For advanced, heavy script-driven LUA modification frameworks (like Tsardoms 3.0+), enabling Esync (PROTON_EARLY_SYNC) inside Lutris is mandatory for modern frame fluidity. Esync completely bypasses standard Wine thread synchronization bottlenecks by leveraging native Linux kernel eventfd descriptors, eliminating camera stuttering and stabilizing micro-frames during AI end-turn calculation loops. (Note: For older, basic mods lacking external engine patches, keeping Esync/Fsync OFF may yield better stability.)

:wrench: 3. The Garrison Manager Desync Fix (Siege Battles, Tsardoms 3.0+)

When running Tsardoms 3.0+ on low-to-mid specs or integrated AMD hardware, real-time siege battles that trigger the M2TWEOP Garrison Manager script (spawning/de-spawning defensive troops) can create a rendering deadlock during post-battle transitions, flooding the logs with Garrison for Draw.settlementName loops whenever custom unit types are completely wiped out.

  • The Fix: Applying the Frame-Pacing table above (DXVK_FRAME_RATE=60, d3d9.maxFrameLatency=1) resolves the rendering deadlock by keeping the GPU tightly synced with the Garrison Manager’s script threads, preventing the post-battle log flood and the associated freeze.

:loud_sound: 4. Comprehensive Audio Fail-Safe

  • PULSE_LATENCY_MSEC=256 — Expands the modern Linux audio server buffer window. This entirely eliminates hard desktop crashes when thousands of combat units fire projectiles and trigger parallel voice triggers simultaneously.
  • The ALSA Passthrough Safety Net: If your system layout still experiences dropouts or thread hangs under PulseAudio/PipeWire pipelines, add WINEAUDIODRIVER=alsa to your Lutris environment to establish a direct hardware audio driver bypass.

:gear: 5. Recommended Runner Defaults

  • DXVK: Enabled (Stable v1.10.3 is highly preferred as the definitive wrapper for legacy DX9 titles).
  • VKD3D: Disabled by default for DX9 profile trees to completely eliminate unnecessary sub-allocator memory overhead.
  • Runner Choice: Modern high-throughput runners such as Proton 10-34+ are excellent for heavy graphical throughput. However, script-heavy total overhauls requiring strict legacy stability run best on the Wine-GE 8-26 line (now merged into the GE-Proton naming — look for GE-Proton8-26 if wine-ge-8-26-x86_64 no longer shows as installable).

:open_file_folder: 6. In-Game Engine Configuration Overrides (.cfg adjustments)

Open your mod’s primary engine configuration file (e.g., tsardoms.cfg or TATW.cfg) and append or modify the following distinct blocks:

[sound]
max_channels = 32       ; Caps the simultaneous audio pool to stop server-side mixer overflow crashes
use_3d_sound = 0         ; Strips away obsolete 2006 software 3D positional calculations that overflow buffers
provider = Miles Fast 2D Positional Audio  ; Anchors the engine to its fastest, most compatible legacy decoder block
music_volume = 0.7
sfx_volume = 0.8
voice_volume = 0.9
sound_quality = 1

[game]
auto_management = 0              ; Explicitly instructs the retail framework that the player intends to govern manually
micromanage_all_settlements = 1  ; Overrides profile layers at boot, forcing manual settlement control on Turn 1

[ai]
bypass_ai_automanager = 1        ; Runtime shield blocking background AI from modifying player values during reloads

[video]
windowed = 0     ; Forces exclusive native fullscreen to prevent focus loss on shared memory rigs
borderless = 0   ; Prevents resolution desync loops often triggered on modern Wayland/X11 compositors

[log]
level = * error  ; Restricts log verbosity, cutting file size from 320MB+ down to a clean 3MB

(Note: Limiting the log footprint to errors completely removes heavy camera lag on the strategic map caused by continuous disk I/O log spamming.)

:computer: 7. Command-Line Fixes & Mod-Side Scripting Resolutions

:link: Resolving “Steam Not Found” and Missing Executable Launch Loops

Digital re-releases, GOG binaries, or standalone non-Steam installers often trigger broken launch wrappers under modern Proton layers. First, inject SteamAppId = 21690 and SteamGameId = 21690 into your Lutris Environment table to force Proton to bypass the verification layer.

Next, to satisfy mod launch scripts requiring a specific .exe name without duplicating physical files (which breaks applied 4GB memory patches), open a terminal inside your main game installation root directory and deploy a clean Linux symbolic link:

ln -sf medieval2.exe kingdoms.exe

This maps a 0KB virtual mirror that perfectly satisfies the mod launcher scripts while retaining 100% data integrity.

:bug: Fixing the Fatal Lua Faction-Heir Turn Freeze (luaPluginScript.lua)

When a faction leader dies unexpectedly on the exact turn a new heir is evaluated, the M2TWEOP Lua framework can throw a fatal ‘nil value’ error when executing eventData.faction.leader, permanently freezing the end-turn state. Open luaPluginScript.lua around line 235 and insert a safety barrier check:

if leader ~= nil then

This forces the scripting subsystem to safely bypass the thread execution if the leader object is missing, guaranteeing flawless turn transitions.

:boom: The M2TWEOP Save-Reload Crash (campaign_script.txt)

A minor syntax typo in the AI condition checks for the Hungary/Croatia event monitor (around line 36681) causes the M2TWEOP parser to choke and crash with an “Oh no…” fatal error whenever you attempt to reload a save game directly from inside an active match. The script uses a non-existent token instead of the correct one.

  • The Fix: Replace the broken variant manually with the clean, native commands: and I_FactionIsAIControlled croatia and and I_FactionIsAIControlled hungary. This allows the parser to read the faction states correctly during mid-match reloads.

:brick: Hardcoded Database Structure Gaps (export_descr_buildings.txt)

Logic gaps in unique landmark building trees create extreme I/O log spam and thread stalls when specific factions conquer target provinces.

  • The Issue: A Level 0 base structure blocks a specific culture pool (e.g., suceava_citadel requires not factions { middle_eastern, }), but its subsequent upgrade tier allows everyone (kruje_castle requires factions { all, }).
  • The Fix: Change the Level 0 restriction to requires factions { all, } and handle actual strategic building limitations exclusively through hidden resource flags.
  • Empty Brackets: Search for empty faction constraint parameters (e.g., requires factions { }). Empty hooks trigger endless engine validation loops. Overwrite empty brackets manually to { all, }.

:crown: The Three Golden Rules of Core Gameplay

  1. Enforce Clean Session Loads (VRAM Cache Purge): The heavy, cumulative background scripting generates unavoidable 32-bit memory leaks. NEVER reload a save file or use the “Load Game” feature directly from inside an active 3D match or a running campaign session. You must always Quit to Desktop and launch the game completely fresh to enforce a complete VRAM and script cache flush.
  2. The Geographic Matrix Rebuild: If you experience an improper system shutdown, power loss, or a hard engine lockup, the active campaign map files can get poisoned. Manually delete the map cache file inside your mod directory before launching to force a clean, uncorrupted rebuild:
    • Action: Delete .../mods/[Your-Mod-Folder]/data/world/maps/base/map.rwm.
  3. Strict Log Discipline: Ensure your configuration file’s log level is hard-locked to error blocks only (level = * error). Allowing the retail engine to track routine structural database warnings will result in massive log files that cause severe, artificial stuttering on modern hardware.

:gear: ADDENDUM: Hardware-Specific Optimization for AMD Ryzen iGPUs & Steam Client Bypass

If you are deploying this blueprint on an AMD Ryzen APU with Integrated Radeon Graphics (iGPU) sharing system RAM (e.g., Ryzen 3 4300G / Vega 8 setups) under Wayland environments, two critical anomalies must be resolved: Steam Client Hijacking and Vulkan Memory Map Deadlocks (VK_ERROR_MEMORY_MAP_FAILED).

1. Overcoming the Steam AppID Hijack Loop (The “Trojan Horse” Bypass)

When launching modified engines natively or via custom shortcuts, the Steam client frequently intercepts the execution, forcing a 10–12 second delay before overriding the parameters and executing the retail 32-bit vanilla branch. To completely sever this hardcoded redirection loop:

  1. Navigate to your installation directory: …/SteamLibrary/steamapps/common/Medieval II Total War/
  2. Rename the retail binary medieval2.exe to medieval2_original.exe.
  3. Create a copy of the modern 64-bit engine executable (M2EX.exe) and rename it exactly to medieval2.exe.
  4. Launch your mods cleanly directly from the standard green PLAY button in Steam by passing your parameters cleanly inside Steam’s native LAUNCH OPTIONS: --features.mod=mods/your_exact_mod_folder_name

2. Memory & Frame-Pacing Constraints for Shared RAM (iGPU Vega/Radeon)

Because integrated graphics dynamically allocate memory from the global system pools, unconstrained 64-bit translation can trigger sudden host memory starvation. Implement these precise system caps:

  • Linux Environment Cache Constraint: Open a terminal and bind your global Mesa shader cache to a safe 2GB ceiling to keep host background tasks breathing:

sudo nano /etc/environment# Append this line at the bottom:
MESA_SHADER_CACHE_MAX_SIZE=2G

  • Targeted DXVK VRAM Budgeting (Launch Options): Prefix your Steam LAUNCH OPTIONS syntax to manually fragment processing cycles and strictly enforce a virtual VRAM limit, preventing system-wide rendering deadlocks on shared 16GB system RAM configurations:

DXVK_CONFIG=“dxvk.maxChunkSize=64; dxvk.vramBudget=2048” %command% --features.mod=mods/your_exact_mod_folder_name


:loudspeaker: Feature Request to Lutris Developers: Native Environment Integration for 64-bit Engines

A Call to Action for the Lutris Development Team:
Based on my intensive benchmarking on modern Linux distributions (Zorin OS), Lutris vastly outperforms Steam when it comes to system optimization, custom runners, and micro-stutter reduction. If I were to rate the gaming performance and runtime optimization, Lutris easily scores a 9.5/10 (or a solid 10), while Steam lags behind at a 7/8. The frame pacing and resource allocation controls inside Lutris are vastly superior.
However, we are currently forced into this Steam “Trojan Horse” file-replacement workaround because the steam_api64.dll embedded in the modern M2EX engine aggressively triggers hardcoded Steam client hooks, trapping Lutris in a silent boot loop (Exit Code 13568).
The Request:
We kindly ask the Lutris developers to investigate a native bypass or a pre-configuration layout within the UMU/Wine runner subsystem. If Lutris can find a way to gracefully intercept or satisfy these modern 64-bit Steam API calls without crashing the prefix container, users will finally be able to ditch Steam entirely and run these massive total conversions natively inside Lutris—where the performance actually belongs.
Adding a native “64-bit Legacy Strategy Bypass” profile or toggle would permanently solve retro-compatibility for thousands of players on Linux!

Update — Tested with Third Age: Total War 6.1 (M2TWEOP)

Following up with validated data from a recent major mod release.

Third Age: Total War 6.1 dropped earlier this year with significantly heavier campaign systems: a persistent Knowledge/Research mechanic, a White Council diplomatic layer with script triggers, and a reworked Spying system with more active map entities. In practice, this means more CPU load per campaign turn and larger battle scripts than previous versions (TA 3.2, DAC, etc.).

Performance validation on the proposed profile:

  • Menu: 1000+ FPS

  • Campaign map: 120+ FPS

  • Battle (x6 speed, large unit counts): 120+ FPS stable

This was achieved with:

  • Runner: GE-Proton11-3

  • Esync: OFF / Fsync: ON

  • Core affinity: taskset -c 0-7 (isolated from background processes)

  • DXVK: default async (legacy D3D9 path)

The key point: TA6.1 is a harder stress test than the base game or older mods. If the profile handles this, it handles the rest of the M2TW ecosystem.

Refined request:

Instead of a broad „fix everything" ticket, would the Lutris team consider either:

  1. A community installer template for M2TW + major mods (TA, DAC, Stainless Steel) that auto-detects kingdoms.exe vs medieval2.exe, sets the correct Proton runner, disables Esync, enables Fsync, and applies taskset affinity?

  2. Or a reusable „32-bit Legacy Strategy" template profile that pre-configures: 32-bit Wine prefix, legacy DXVK, WINE_CPU_TOPOLOGY, and core affinity — applicable to M2TW, Rome TW, and similar era games.

Currently, every user rediscovers the same four variables through trial-and-error (correct Proton version, Esync/Fsync inversion, core affinity, DXVK legacy settings). A pre-built template would cut onboarding from ~2 hours of debugging to a 5-minute dropdown selection.

Attaching two FPS screenshots from TA6.1 battles and campaign map for reference.

Addendum v2.1 — GPU-Agnostic & Flatpak Survival Guide

(Extends the “Universal Stability Blueprint” for all platforms and all game versions)


:fire: TL;DR — “I have 3 minutes, what do I copy?”

Table

You have… Runner Esync Fsync D3D Extras DXVK VRAM Cap Quick note
Tsardoms / Fall of Constantinople (M2TWEOP) GE-Proton8-26 ON OFF OFF YES Esync mandatory for M2TWEOP hooks
DaC / DCI:LA (no M2TWEOP, heavy) GE-Proton8-26 OFF env ON NO Fsync via WINEFSYNC=1, D3D Extras fixes artifacts
Third Age 3.2 / GoT / TATW 6.2 (light) GE-Proton10-34+ OFF env ON NO Native Fsync, DXVK_ASYNC=1 accepted
NVIDIA proprietary any ON OFF ON optional __GL_THREADED_OPTIMIZATIONS=0 is CRITICAL
Intel iGPU / Arc any OFF env ON YES Shared VRAM = DXVK cap mandatory
AMD RADV any see above see above see above see above Baseline of the original guide

Golden Rule (all mods, all GPUs):

  1. WINE_LARGE_ADDRESS_AWARE=1

  2. LC_ALL=C

  3. SteamAppId=21690 + SteamGameId=21690 (even for retail/GOG versions — see Section 6)

  4. Quit to Desktop — never reload a save from the in-game menu.


:brain: Section 1 — WHY Esync vs Fsync? When to choose which?

I’ve seen confusion in the thread: “Why does Tsardoms want Esync ON, DaC wants Fsync, and TATW doesn’t care?” The answer isn’t arbitrary — it depends on three factors: M2TWEOP, Proton/GE version, and GPU vendor.

1.1 What do they actually do?

  • Esync (Eventfd Sync): Wine/Proton emulates Windows synchronization objects using Linux eventfd. Available on any kernel. Higher overhead with hundreds of threads, but maximum compatibility with external DLL hooks.

  • Fsync (Futex Waitv): Uses futex_waitv (kernel 5.16+). Much lower overhead, smoother frames, but stricter with user-space hooks.

1.2 Decision matrix

Table

Factor Esync ON Fsync (env)
Mod uses M2TWEOP (Tsardoms, FoC) :white_check_mark: MANDATORY :x: Risk of deadlock on M2TWEOP DLL injection with GE-Proton8-26
Mod without M2TWEOP (DaC, DCI, TATW) :warning: Works, but stutters :white_check_mark: RECOMMENDED — smoother frames
NVIDIA proprietary old (<driver 535) :white_check_mark: Safer :x: Kernel may lack futex_waitv support
Kernel < 5.16 :white_check_mark: Only option :x: Incompatible
AMD RADV / Intel works :white_check_mark: Optimal

1.3 Why Fsync via WINEFSYNC=1 and NOT the UI toggle?

The Lutris UI toggle only works if the runner was compiled with the Fsync patch and exposes it correctly via registry. GE-Proton8-26 and 10-34 have inconsistent behavior with the UI toggle — sometimes it ignores it, sometimes it conflicts with Esync. The WINEFSYNC=1 environment variable forces the Fsync path regardless of UI, and PROTON_NO_ESYNC=1 disables the other. This is the empirically tested “bulletproof” method.

How to apply in Lutris:

  • Esync ON: UI toggle “Enable Esync” = ON. Do NOT add WINEFSYNC.

  • Fsync ON: UI toggle “Enable Esync” = OFF, UI toggle “Enable Fsync” = OFF. Add env var: WINEFSYNC=1.

  • NEVER both simultaneously.


:video_game: Section 2 — GPU Vendor-Specific Cheatsheet

The original guide was validated on AMD RADV (ACO). Here are the adaptations for NVIDIA and Intel.

2.1 NVIDIA (Proprietary / Closed-Source Driver)

NVIDIA has the best Vulkan driver for modern games, but for 32-bit legacy it has pitfalls:

Mandatory environment variables for NVIDIA:

plain

__GL_THREADED_OPTIMIZATIONS=0     # CRITICAL: For 32-bit executables,
                                  # threaded opts cause race conditions
                                  # and crash at loading screen.
__GL_SHADER_DISK_CACHE=1          # Persistent shader cache
__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1  # Don't wipe cache on exit
__GL_SYNC_TO_VBLANK=0             # Force Vsync OFF at driver level

DXVK note on NVIDIA: The NVIDIA driver manages VRAM aggressively. If you have 8GB VRAM or less, keep DXVK_CONFIG with dxvk.vramBudget (see Heavy profiles). If you have 12GB+, you can remove the cap.

Fsync on NVIDIA: Fsync requires support in the NVIDIA kernel module. It was added in drivers 535.x+. If your driver is older, Fsync will not work at all — the game will launch, but synchronization will fall back to the classic (slow) path. Stick to Esync.

Useful one-time nvidia-settings:

bash

nvidia-settings -a '[gpu:0]/GPUPowerMizerMode=1'  # Permanent Performance Mode

2.2 Intel (iGPU Iris Xe / Arc A-series / UHD)

Intel uses the ANV driver (open-source). DXVK performance on Intel iGPU is surprisingly good for M2TW, but requires attention to shared memory.

Environment variables for Intel:

plain

ANV_QUEUE_THREAD=1                # Dedicated thread for queue submission
MESA_SHADER_CACHE_MAX_SIZE=1GB    # Generous cache for shader compilation
INTEL_DEBUG=noccs                 # Disable color compression,
                                  # prevents corruption on certain SKUs

Shared VRAM = mandatory DXVK_CONFIG: On Intel iGPU, “VRAM” is system RAM. Without dxvk.vramBudget, DXVK can request more than Linux can allocate, triggering OOM. Always keep dxvk.vramBudget=2048 and dxvk.maxChunkSize=64 on Intel iGPU.

Fsync on Intel: Works natively, no restrictions. You can use Fsync on all non-M2TWEOP mods.

2.3 AMD RADV (The guide’s baseline)

The original profiles remain valid. One addition:

plain

RADV_DEBUG=nocompute    # Only for Fall of Constantinople 2.0
                        # (compute shaders crash on AMD iGPU)
RADV_PERFTEST=aco       # Fast shader compiler (default on newer kernels,
                        # but explicit = safe)

:package: Section 3 — Using Lutris from Flatpak? Survival Guide

Many install Lutris from Flathub (flatpak install flathub org.lutris.Lutris). It works, but the sandbox blocks some commands from the guide.

3.1 What does NOT work in Flatpak (and the fix)

Table

Command / Setting Why it fails Fix
sudo sysctl vm.swappiness=10 Flatpak has no kernel access Run in a separate terminal on the host before gaming
gsettings set org.gnome.mutter check-alive-timeout 0 gsettings inside sandbox only modifies the sandbox Run on host: gsettings set org.gnome.mutter check-alive-timeout 0
flatpak run --command=gsettings org.lutris.Lutris ... Does not affect host GNOME Don’t use — it’s useless
Access to /mnt/Jocuri_SSD Flatpak only sees ~/ and ~/.var/ by default Add explicit permission (see below)
cpupower frequency-set Lacks CAP_SYS_ADMIN capability Run on host with sudo
zRAM (zram-config) System service — works regardless Install on host, not in Flatpak

3.2 How to grant Flatpak permissions for your game drive

If your games are on /mnt/Jocuri_SSD (or any external path):

bash

flatpak override --user --filesystem=/mnt/Jocuri_SSD org.lutris.Lutris

If you use Flatseal (GUI for Flatpak permissions):

  1. Open Flatseal → select Lutris

  2. Under “Filesystem” → add /mnt/Jocuri_SSD or ~/Games (as applicable)

  3. Enable “Device=all” (for direct GPU access)

3.3 Recommended workflow for Flatpak

Step 1 — Terminal on host (before session):

bash

# Mutter fix (one-time, persists permanently)
gsettings set org.gnome.mutter check-alive-timeout 0

# Temporary RAM optimizations
sudo sysctl vm.swappiness=10
sudo sysctl vm.vfs_cache_pressure=50

# Governor performance (optional)
sudo cpupower frequency-set -g performance

Step 2 — Open Lutris (Flatpak) and launch the game.

Step 3 — Terminal on host (after session):

bash

sudo sysctl vm.swappiness=60
sudo sysctl vm.vfs_cache_pressure=100
sudo cpupower frequency-set -g ondemand

Alternative: Save a pre-game.sh and post-game.sh script on your desktop and run them manually. Flatpak cannot automate this from inside.

3.4 Wineprefix in Flatpak

Flatpak Lutris creates prefixes in ~/.var/app/org.lutris.Lutris/data/lutris/runners/wine/. This path works correctly — no changes needed. Just make sure the actual game files (.exe, mod folders) are on a path with Flatpak permission.


:cd: Section 4 — Game Version: Retail, GOG, Steam, or Standalone?

The guide uses SteamAppId=21690 and WINEDLLOVERRIDES=steam_api=n,b. This works for all versions, not just Steam.

4.1 Why?

  • SteamAppId=21690 tricks the Proton layer into thinking “I already know what game this is” — avoiding launcher checks that crash non-Steam versions.

  • WINEDLLOVERRIDES=steam_api=n,b (no-op + builtin) forces Wine to ignore the Steam API DLL. If your game doesn’t have steam_api.dll (e.g., GOG, retail CD), Wine “simulates” it without errors. If it has a fake one, it prevents the crash.

4.2 Table per source

Table

Game source SteamAppId WINEDLLOVERRIDES Additional note
Original Steam 21690 steam_api=n,b Works out-of-the-box
GOG release 21690 steam_api=n,b GOG has no Steam API, override is harmless
Retail CD/DVD 21690 steam_api=n,b Make sure you have official patch 1.5
Standalone / Digital re-release 21690 steam_api=n,b Symlink kingdoms.exe needed if mod looks for medieval2.exe

It doesn’t matter where you got the game — the variables stay identical. Do not change SteamAppId and do not remove WINEDLLOVERRIDES.


:hammer_and_wrench: Section 5 — “One-Shot” Setup Script (Bash)

For those who want to automate without copying 15 variables manually into the GUI:

bash

#!/bin/bash
# m2tw_flatpak_bootstrap.sh
# Run on HOST (not inside Flatpak) before the session

echo "=== M2TW Linux Bootstrap ==="

# 1. Mutter fix (permanent)
echo "[1/5] Disabling 'not responding' popup..."
gsettings set org.gnome.mutter check-alive-timeout 0

# 2. Temporary sysctl
echo "[2/5] Optimizing kernel RAM/cache..."
sudo sysctl vm.swappiness=10
sudo sysctl vm.vfs_cache_pressure=50

# 3. Governor (optional)
echo "[3/5] CPU Performance mode..."
sudo cpupower frequency-set -g performance 2>/dev/null || echo "  (cpupower unavailable, skip)"

# 4. Check Flatpak permissions
echo "[4/5] Checking Flatpak permissions..."
if flatpak info org.lutris.Lutris &>/dev/null; then
    echo "  Lutris Flatpak detected. Make sure you ran:"
    echo "  flatpak override --user --filesystem=/mnt/Jocuri_SSD org.lutris.Lutris"
fi

# 5. Symlink kingdoms.exe (if medieval2.exe exists)
M2TW_PATH="/mnt/Jocuri_SSD/jocuri instalate/Medieval II - Total War"
if [ -f "$M2TW_PATH/medieval2.exe" ] && [ ! -L "$M2TW_PATH/kingdoms.exe" ]; then
    echo "[5/5] Creating symlink kingdoms.exe..."
    ln -sf "$M2TW_PATH/medieval2.exe" "$M2TW_PATH/kingdoms.exe"
else
    echo "[5/5] Symlink kingdoms.exe exists or path invalid — skip."
fi

echo ""
echo "✅ System ready. Now open Lutris and launch the game."
echo "⚠️  AFTER you finish, run: ./m2tw_cleanup.sh"

Cleanup script (after session):

bash

#!/bin/bash
# m2tw_cleanup.sh
echo "Restoring system parameters..."
sudo sysctl vm.swappiness=60
sudo sysctl vm.vfs_cache_pressure=100
sudo cpupower frequency-set -g ondemand 2>/dev/null || true
echo "✅ Done."

:bar_chart: Section 6 — Quick Diagnostic: “How do I read my own crash?”

Not all crashes are “Out of Memory”. Here’s how to identify the cause before posting.

6.1 Where the logs are

  • Wine/Proton: ~/.local/share/lutris/runners/wine/[prefix]/drive_c/users/[user]/Temp/

  • Mod-specific: .../mods/[Mod]/logs/ (e.g., tsardoms.log.txt)

  • DXVK: ~/.local/share/lutris/runners/wine/[prefix]/drive_c/users/[user]/Local Settings/Application Data/

6.2 Key messages and what they mean

Table

Message in log / terminal Meaning Fix
VK_ERROR_MEMORY_MAP_FAILED Insufficient or fragmented VRAM/RAM Add dxvk.maxChunkSize=64;dxvk.vramBudget=2048
R6025 - pure virtual function call Thread desync (GPU ahead of CPU) d3d9.maxFrameLatency=1 + DXVK_FRAME_RATE=60
Out of Memory (without VK error) LAA missing or 4GB patch ignored WINE_LARGE_ADDRESS_AWARE=1
Garrison for Draw.settlementName loop Garrison Manager deadlock post-battle Strict frame-pacing (see Tsardoms profile)
steam_api.dll not found / crash at startup Proton checking for Steam SteamAppId=21690 + WINEDLLOVERRIDES=steam_api=n,b
Oh no... (M2TWEOP) Lua/script parser error Fix campaign_script.txt (see post #12)
Crash on “Apply Changes” video Native fullscreen on Wine windowed=1 + borderless_window=1 in CFG

6.3 MangoHud for live diagnostic

Add to env vars:

plain

MANGOHUD=1
MANGOHUD_CONFIG=ram,vram,frametime,graphs,cpu_stats,gpu_stats

Displays in real-time: RAM, VRAM, frametime. If VRAM hits the limit before the crash, you know for sure it’s memory.


:arrows_counterclockwise: Section 7 — OpenGL Fallback (Plan B)

If DXVK crashes inexplicably (especially on old Intel or problematic NVIDIA drivers), Medieval II has a native OpenGL renderer accessible via WineD3D.

How to switch to OpenGL (WineD3D):

  1. In Lutris → Runner Options → Disable DXVK (uncheck)

  2. Add env var: WINEDLLOVERRIDES="d3d9=w"

  • w = WineD3D (OpenGL implementation of DirectX 9)
  1. Expect lower FPS (20-30% below DXVK), but maximum stability.

When to use:

  • Crash on every loading screen on Intel HD 5500/620

  • Purple/green visual artifacts on NVIDIA with beta drivers

  • “Black screen” after intro on certain configurations


:white_check_mark: Final Checklist before first launch

Copy this to a text file and check off:

  • [ ] Game is on an ext4 partition (not NTFS)

  • [ ] Each mod has its own Wine prefix

  • [ ] ln -sf medieval2.exe kingdoms.exe exists in the game folder

  • [ ] medieval2.preference.cfg is read-only (chmod 444)

  • [ ] log level = * error in CFG (not trace)

  • [ ] windowed = 1, borderless_window = 1, vsync = 0 in CFG

  • [ ] Correct environment variables for your mod (see TL;DR table)

  • [ ] If using Flatpak: --filesystem permission is active

  • [ ] If using NVIDIA: __GL_THREADED_OPTIMIZATIONS=0 is set

  • [ ] If using Intel iGPU: dxvk.vramBudget=2048 is present

  • [ ] Quit to Desktop after every session — never “Load Game” from menu


This addendum completes the “Universal Stability Blueprint” (post #12) and the community v2.0 guide. Tested on AMD RADV, NVIDIA 535+, and Intel Iris Xe. For questions, mention your GPU and Lutris version (native/Flatpak).

:robot: Can’t get it to work? Let an AI adapt this for your exact system

If the settings above don’t work for your specific setup, you can copy-paste this entire guide into any AI assistant (ChatGPT, Claude, Gemini, etc.) and ask:

“I have [your GPU], [your RAM], [your distro], Lutris [native/Flatpak], and I’m trying to run [mod name]. Adapt the environment variables and runner settings from this guide for my exact system.”

What to mention for best results:

  • GPU vendor and model (e.g., NVIDIA GTX 1060 6GB, Intel Iris Xe, AMD RX 6600)

  • RAM amount

  • Linux distro and version (e.g., Ubuntu 24.04, Fedora 40, Arch)

  • Lutris install method (native package vs Flatpak)

  • Which mod you’re running (Tsardoms, DaC, Third Age, etc.)

  • Exact error message or behavior (crash at launch, black screen, freeze at loading, etc.)

The guide above contains enough technical depth for any capable LLM to cross-reference your hardware against the vendor-specific sections and output a tailored configuration.