Overview
I recently purchased the remaining DLCs for Age of Empires II: Definitive Edition (steam) and I wanted to make sure that my ability to play this game survives Steam, my relationship with them, and even the world wide web.
After a lot of research and the benefit of many Free Software tools, I can play multiplayer AoE2DE with my mods without Steam, on Linux! Here is my method for assembling a package for distributing to my systems without Internet. I have tested only for a few minutes between two machines in the same room. I don't know how this would scale to a vpn or wireless clients.
This does not use system Wine, which crashes immediately with some opengl32 problem.
Building the package
This first asset is the proper Steam directory with all my DLCs installed.
tar -zcf aoe2de-alldlcs-raw.2026-06-28.tgz "${HOME}/.steam/steam/steamapps/common/AoE2DE"
-
Explode my asset aoe2de-alldlcs-raw.2026-06-28.tgz to ~/aoe2de.
tar -zx -C ~ -f aoe2de-alldlcs-raw.2026-06-28.tgz
-
Download dependency files to ~/aoe2de/prepare, which is a temporary spot.
wget https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton11-1/GE-Proton11-1.tar.gz https://github.com/Open-Wine-Components/umu-launcher/releases/download/1.4.0/python3-umu-launcher_1.4.0-1_amd64_debian-13.deb https://github.com/Open-Wine-Components/umu-launcher/releases/download/1.4.0/umu-launcher_1.4.0-1_all_debian-13.deb https://github.com/luskaner/ageLANServerLauncherCompanion/releases/download/v1.3.0.0/ageLANServerLauncherCompanion_Age2FakeOnline_1.0.0.0.zip https://github.com/Detanup01/gbe_fork/releases/download/release-2026_05_30/emu-win-release.7z https://github.com/luskaner/ageLANServer/releases/download/v1.14.1/ageLANServer_full_1.14.1_linux_x86-64.tar.gz
-
Move debs to ~/aoe2de/debs. They will need to be installed on any system that uses this package.
-
Explode GE-Proton11-1 to ~/aoe2de.
tar -zx -C ~/aoe2de -f ~/aoe2de/prepare/GE-Proton11-1.tar.gz
-
Prepare files from Goldberg Emulator fork.
cd ~/aoe2de/prepare
7za x emu-win-release.7z
cd ~/aoe2de/
cp -pi prepare/release/steamclient_experimental/{ColdClientLoader.ini,steamclient*.dll,steamclient_loader_x64.exe} .
Prepare the ColdClientLoader.ini. Here is the non-comment values I used.
[SteamClient]
Exe=AoE2DE\AoE2DE_s.exe
ExeRunDir=
ExeCommandLine=NOSTARTUP SKIPINTRO
AppId=813780
SteamClientDll=steamclient.dll
SteamClient64Dll=steamclient64.dll
[Injection]
ForceInjectSteamClient=0
ForceInjectGameOverlayRenderer=0
DllsToInjectFolder=dlls
IgnoreInjectionError=1
IgnoreLoaderArchDifference=0
[Persistence]
Mode=0
[Debug]
ResumeByDebugger=0
-
Prepare configs for steam emulator
cd ~/aoe2de
mkdir -p dlls steam_settings saves
-
Load dlls.
cd ~/aoe2de/dlls
7za x ~/aoe2de/prepare/ageLANServerLauncherCompanion_Age2FakeOnline_1.0.0.0.zip
cp -pi ../prepare/release/steamclient_experimental/GameOverlayRenderer64.dll ../prepare/release/steamclient_experimental/extra_dlls/steamclient_extra_x64.dll .
-
Prepare steam_settings.
Prepare these based on Reference 5.
File achievements.json is lengthy and not shown here.
The DLCs that I own are these, for file configs.app.ini.
[app::dlcs]
unlock_all=0
# Expansions
2141580=Age of Empires II: Definitive Edition - Return of Rome
2555420=Age of Empires II: Definitive Edition - The Mountain Royals
#2805510=Age of Empires II: Definitive Edition - Victors and Vanquished
2805520=Age of Empires II: DE - Chronicles: Battle for Greece
3080080=Age of Empires II: DE - The Three Kingdoms
#3793540=Age of Empires II: DE - Chronicles: Alexander the Great
3219700=Age of Empires II: DE – The Last Chieftains
1389240=Age of Empires II: Definitive Edition - Lords of the West
1869820=Age of Empires II: Definitive Edition - Dynasties of India
1557210=Age of Empires II: Definitive Edition - Dawn of the Dukes
# Animated Icons
#2672800=Age of Empires II: Definitive Edition – La Hire’s Dry Humor Animated Icons
#2672810=Age of Empires II: Definitive Edition – Joan’s Marvelous Moving Masterpieces Animated Icons
#2672820=Age of Empires II: Definitive Edition – Barbarossa’s Barrel of Pickled Goods Animated Icons
# Other
#1039811=Enhanced Graphics Pack
Prepare file configs.user.ini.
[user::general]
# Fill your account name as you would normally see.
account_name=SpacesAreEvil65
# Fill with your real steamid or leave empty for it to be auto-generated.
account_steamid=
# Choose one from steam_settings\supported_languages.txt (described in https://partner.steamgames.com/doc/store/localization/languages) or leave empty to be set as 'english'
language=
# Choose from 'Alpha-2' country code: https://www.iban.com/country-codes or leave empty to be set as 'US'
ip_country=
[user::saves]
local_save_path=saves
File supported_languages.txt is exactly as is from Reference 5.
english
french
italian
german
japanese
koreana
brazilian
russian
schinese
latam
tchinese
turkish
vietnamese
spanish
polish
hindi
malay
-
Prepare launcher script aoe2de.sh.
|
#!/bin/sh
|
|
PROTON_DISABLE_LSTEAMCLIENT=1 WINEPREFIX=~/.wine-aoe2de PROTONPATH=~/aoe2de/GE-Proton11-1 umu-run ~/aoe2de/steamclient_loader_x64.exe NOSTARTUP SKIPINTRO
|
The first time you run, umu wants to download components from the Internet for your user. Client scripts set-initial-umu.sh might be able to prevent that requirement.
-
Prepare scripts/ files.
files/2026/listings/aoe2de-get-account-steamid.sh (Source)
|
#!/bin/sh
if test -z "${INFILE}" ;
then
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
# find first one. IGNORE the saves/settings/configs.user.ini which is the auto-generated one.
INFILE="$( find "${scriptdir}" "${scriptdir}/.." "${scriptdir}/../.." -ipath '*/steam_settings/configs.user.ini' -print -quit )"
fi
final_steamid="$( awk -F'=' '$1~/account_steamid/{print $NF}' "${INFILE}" )"
echo "account_steamid = ${final_steamid}"
|
files/2026/listings/aoe2de-get-username.sh (Source)
|
#!/bin/sh
if test -z "${INFILE}" ;
then
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
# find first one
INFILE="$( find "${scriptdir}" "${scriptdir}/.." "${scriptdir}/../.." -ipath '*/steam_settings/configs.user.ini' -print -quit )"
fi
awk -F'=' '$1~/account_name/{print $NF}' "${INFILE}"
|
files/2026/listings/aoe2de-set-account-steamid.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 |
#!/bin/sh
# Useful because the emulator seems to pick the same number on every system when it needs to generate its own account_steamid.
# Dependencies:
# dep-devuan: moreutils
# Env vars: APPLY VERBOSE
if test -z "${INFILE}" ;
then
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
# find first one. IGNORE the saves/settings/configs.user.ini which is the auto-generated one.
INFILE="$( find "${scriptdir}" "${scriptdir}/.." "${scriptdir}/../.." -ipath '*/steam_settings/configs.user.ini' -print -quit )"
fi
# Steam id is 17 digits long, decimal, and starts with 765611982
new_steamid="765611982$( </dev/random tr -dc '0-9' | head -c8 )"
# modconf.py breaks on set account_steamid because of the underscore. I will have to do this with awk or sed or similar 2026-06-30-3 23:55
#if test -n "${VERBOSE}" ; then echo "/usr/libexec/bgscripts/py/modconf.py ${APPLY:+-a} ${VERBOSE:+-v} -s '[user::general]' \"${INFILE}\" set account_steamid \"${new_steamid}\"" ; fi
#/usr/libexec/bgscripts/py/modconf.py ${APPLY:+-a} ${VERBOSE:+-v} -s '[user::general]' "${INFILE}" set account_steamid "${new_steamid}"
# So use basic awk instead
if test -n "${VERBOSE}" ;
then
echo "awk -v \"b=${new_steamid}\" -F'=' 'BEGIN{OFS=\"=\"} \$1~/account_steamid/{\$2=b} {print}' \"${INFILE}\" | sponge \"${INFILE}\""
fi
if test -n "${APPLY}" ;
then
awk -v "b=${new_steamid}" -F'=' 'BEGIN{OFS="="} $1~/account_steamid/{$2=b} {print}' "${INFILE}" | sponge "${INFILE}"
# Regardless if it worked, read the value and show it.
final_steamid="$( awk -F'=' '$1~/account_steamid/{print $NF}' "${INFILE}" )"
echo "account_steamid = ${final_steamid}"
fi
# modconf.py has a bug where it adds an additional newline after that updated line, so
# collapse multiple empty lines into a single empty line: ref https://unix.stackexchange.com/a/72749
awk '!NF {if (++n <= 1) print; next}; {n=0;print}' "${INFILE}" | sponge "${INFILE}"
if test -z "${APPLY}" ; then echo "Dry run only! Use APPLY=1" 1>&2 ; fi
|
files/2026/listings/aoe2de-set-cert-from-server.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 |
#!/bin/sh
IPADDRESS="${IPADDRESS:-${1}}"
if test -z "${INFILE}" ;
then
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
INFILE="$( find "${scriptdir}" "${scriptdir}/.." "${scriptdir}/../.." -ipath '*/certificates/cacert.pem' -print -quit )"
fi
INFILE="$( readlink -f "${INFILE}" )"
if test -z "${IPADDRESS}" ;
then
echo "Fatal! Provide \$1 or IPADDRESS (IP address or hostname) to fetch certificate. Aborted." 1>&2
exit 1
fi
cert="$( </dev/null openssl s_client -connect "${IPADDRESS}:443" 2>/dev/null | openssl x509 -in /dev/stdin )"
# Exit if the connection failed. Openssl x509 already printed an error, so do not print another.
if test -z "${cert}" ; then exit 1 ; fi
next_next_to_last="$( echo "${cert}" | awk '{a[NR]=$0} END {print a[NR-2]}' )"
if ! grep -q -e "${next_next_to_last}" "${INFILE}" ;
then
echo "You need the cert! File ${INFILE} does not have the cert."
if test -n "${APPLY}" ;
then
echo "Applying the the cert." 1>&2
echo "${cert}" >> "${INFILE}"
else
echo "Dry run only! Please run with APPLY=1 to add the cert."
fi
else
echo "File ${INFILE} has the cert already."
fi
|
files/2026/listings/aoe2de-set-etc-hosts.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 |
#!/bin/sh
# Dependencies:
# dep-devuan: bgscripts
# TODO:
# clean up #ageLANServer entries
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
INFILE="${INFILE:-/etc/hosts}"
mkdir -p "${scriptdir}/backups"
# needs bgscripts
sudo bup "${INFILE}" "${scriptdir}/backups"
IPADDRESS="${IPADDRESS:-${1}}"
if test -z "${IPADDRESS}" ;
then
echo "Fatal! Need \$1 or IPADDRESS. Aborted." 1>&1
exit 1
fi
# I need to remove the loopback address for this host, only if this is the server
echo "WARNING: for server only, please modify /etc/hosts and remove 127.0.0.1-type entries. Not implemented automatically yet." 1>&2
# nice idea, but I don't want to depend on this
# This only adds the relevant api.ageofempires.com entries.
#sudo "${scriptdir}/../ageLANServer/linux/launcher/bin/config-admin" setup --game age2 --ip "${IPADDRESS}"
_resolved="$( getent hosts "${IPADDRESS}" | awk '{print $1}' )"
echo "Using resolved ip address ${_resolved}" 1>&2
for word in \
aoe-api.reliclink.com \
aoe-api.worldsedgelink.com \
api.ageofempires.com \
cdn.ageofempires.com \
pb-live-release1-api.worldsedgelink.com \
pb-live-release2-api.worldsedgelink.com \
pb-live-release3-api.worldsedgelink.com \
pb-live-release4-api.worldsedgelink.com \
pb-live-release5-api.worldsedgelink.com \
pb-live-release6-api.worldsedgelink.com \
pb-live-release7-api.worldsedgelink.com \
pb-live-release8-api.worldsedgelink.com \
pb-live-release9-api.worldsedgelink.com \
; do
long="${word}#ageLANServer"
# depends on bgscripts
if test -n "${VERBOSE}" ; then
echo "sudo updateval -v ${INFILE}" \"${_resolved} ${long}\" \"${_resolved} ${long}\"
fi
if test -n "${APPLY}" ; then
sudo updateval -a "${INFILE}" "${_resolved} ${long}" "${_resolved} ${long}"
fi
done
|
files/2026/listings/aoe2de-set-initial-mods.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
#!/bin/sh
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
INFILE="${INFILE:-/mnt/public/Support/Games/aoe2de-on-linux/aoe2de-mods-subscribed.2026-06-26.tgz}"
steamid="$( "${scriptdir}/get-account-steamid.sh" | awk '{print $NF}' )"
WINEPREFIX="${WINEPREFIX:-${HOME}/.wine-aoe2de}"
destdir="${WINEPREFIX}/drive_c/users/steamuser/Games/Age of Empires 2 DE/${steamid}/mods"
if test -n "${VERBOSE}" ;
then
echo "tar -zx -C \"${destdir}\" -f \"${INFILE}\""
fi
if test -n "${APPLY}" ;
then
mkdir -p "${destdir}"
tar -zx -C "${destdir}" -f "${INFILE}"
else
echo "Dry run only! Please run with APPLY=1 to apply the initial mods."
fi
|
files/2026/listings/aoe2de-set-initial-profile.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
#!/bin/sh
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
indir="$( readlink -f "${scriptdir}/../initial-files" )"
steamid="$( "${scriptdir}/get-account-steamid.sh" | awk '{print $NF}' )"
WINEPREFIX="${WINEPREFIX:-${HOME}/.wine-aoe2de}"
destdir="${WINEPREFIX}/drive_c/users/steamuser/Games/Age of Empires 2 DE/${steamid}"
if test -n "${VERBOSE}" ;
then
echo "cp -pr \"${indir}/profile\" \"${destdir}\""
fi
if test -n "${APPLY}" ;
then
mkdir -p "${destdir}"
cp -pr "${indir}/profile" "${destdir}"
else
echo "Dry run only! Please run with APPLY=1 to apply the initial profile."
fi
|
files/2026/listings/aoe2de-set-initial-registry.sh (Source)
|
#!/bin/sh
PROTON_DISABLE_LSTEAMCLIENT=1 WINEPREFIX=~/.wine-aoe2de PROTONPATH=~/aoe2de/GE-Proton11-1 umu-run regedit "x:\aoe2de\initial-files\aoe2de-partial.reg"
|
files/2026/listings/aoe2de-set-initial-umu.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
#!/bin/sh
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
indir="$( readlink -f "${scriptdir}/../initial-files" )"
destdir="${HOME}/.local/share"
if test -n "${VERBOSE}" ;
then
echo "cp -pr \"${indir}/umu\" \"${destdir}\""
fi
if test -n "${APPLY}" ;
then
mkdir -p "${destdir}"
cp -pr "${indir}/umu" "${destdir}"
else
echo "Dry run only! Please run with APPLY=1 to apply the initial umu files."
fi
|
files/2026/listings/aoe2de-set-username.sh (Source)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
#!/bin/sh
# Dependencies:
# dep-devuan: bgscripts, moreutils
# Env vars: APPLY VERBOSE
USERNAME="${USERNAME:-${1}}"
if test -z "${USERNAME}" ; then echo "Fatal! Need \$1 or USERNAME. Aborted." 1>&2 ; exit 1 ; fi
if test -z "${INFILE}" ;
then
scriptdir="$( dirname "$( readlink -f "${0}" )" )"
# find first one
INFILE="$( find "${scriptdir}" "${scriptdir}/.." "${scriptdir}/../.." -ipath '*/steam_settings/configs.user.ini' -print -quit )"
fi
# This depends on bgscripts.
/usr/libexec/bgscripts/py/modconf.py ${APPLY:+-a} ${VERBOSE:+-v} -s '[user::general]' "${INFILE}" set account_name "${USERNAME}"
# modconf.py has a bug where it adds an additional newline after that updated line, so
# collapse multiple empty lines into a single empty line: ref https://unix.stackexchange.com/a/72749
awk '!NF {if (++n <= 1) print; next}; {n=0;print}' "${INFILE}" | sponge "${INFILE}"
if test -z "${APPLY}" ; then echo "Dry run only! Use APPLY=1" 1>&2 ; fi
|
-
Prepare ageLANServer assets for server.
These assets are only needed for the machine that will run the server.
mkdir -p ~/aoe2de/ageLANServer/linux
tar -zx -C ~/aoe2de/ageLANServer/linux -f ~/aoe2de/prepare/ageLANServer_full_1.14.1_linux_x86-64.tar.gz
Adjust battle-server-manager/resources/config.age2.toml
Path = '../../../AoE2DE/BattleServer/BattleServer.exe'
Adjust server/resources/config/config.toml
I could have written sed statements, but I didn't bother.
-
Prepare initial files.
I copied what I think is a reasonably configured "low graphics" user profile from ~/.wine-aoe2de.attempt2/drive_c/users/steamuser/Games/Age\ of\ Empires\ 2\ DE/7656119EXAMPLE892. Place it as ~/aoe2de/initial-files/profile.
Prepare initial-files/README.md.
# Profile
This initial profile already sets graphics to low. Most, but probably not all, my preferred settings are loaded already.
The destination for `profile/` is the following.
${WINEPREFIX}/drive_c/users/steamuser/Games/Age of Empires 2 DE/7656119EXAMPLE892
# Umu
This is a snapshot of `${HOME}/.local/share/umu` from 2026-07-01.
# Registry key
It appears some values are in registry, and some are in `${WINEPREFIX}/drive_c/users/steamuser/Games/Age\ of\ Empires\ 2\ DE/${account_steamid}/profile/Player.nfp`. So this is the ones from the registry. However, it also appears to use key `HKEY_USERS\{sid}-{UID}-1000\Software\Microsoft\Microsoft Games\Age of Empires II DE` which is not predictable.
Prepare the initial umu from a working environment. I found one that works for clients that is less than 1GB, with only steamrt4/.
cp -pr ~/.local/share/umu ~/aoe2de/initial-files/
NOTE: It appears some values are in registry, and some are in ${WINEPREFIX}/drive_c/users/steamuser/Games/Age\ of\ Empires\ 2\ DE/${account_steamid}/profile/Player.nfp.
This command exports the registry keys for the game to ${HOME}\aoe2de-partial.reg. This depends on symlink ${WINEPREFIX}/dosdevices/x: -> ${HOME}
PROTON_DISABLE_LSTEAMCLIENT=1 WINEPREFIX=~/.wine-aoe2de PROTONPATH=~/aoe2de/GE-Proton11-1 umu-run regedit /E "x:\aoe2de\initial-files\aoe2de-partial.reg" "HKEY_CURRENT_USER\Software\Microsoft\Microsoft Games\Age of Empires II DE"
-
Build release asset #2.
tar -zc -C ~ -f ~/aoe2de-other-components-2026-07-01.tgz --exclude 'AoE2DE' --exclude 'prepare' aoe2de
This tar operation only took about r0:03.30.
Description of this working environment
Operations
See also /mnt/public/Support/Games/aoe2de-on-linux/aoe2de-without-steam.md
Installing this offline bundle
A server and client get the same assets. The server needs some additional steps.
-
Explode tarball of AoE2DE itself, to ~/aoe2de.
tar -zxf /mnt/public/Support/Games/aoe2de-on-linux/aoe2de-alldlcs-raw.2026-06-28.tgz -C ~
-
Explode the other components.
tar -zxf /mnt/public/Support/Games/aoe2de-on-linux/aoe2de-other-components-2026-07-01.tgz -C ~
Installing a client
In ~/aoe2de, run some of the `scripts/set-*.sh`.
APPLY=1 ./set-account-steamid.sh # randomize the steamid in the emulator
APPLY=1 ./set-initial-profile.sh
APPLY=1 ./set-initial-umu.sh
APPLY=1 ./set-initial-mods.sh # optional
APPLY=1 ./set-username.sh "Steve Harvee 3"
./set-initial-registry.sh
Some can only be run after the server is up and running; see section "Running a client".
Installing a server
Run each step from the "Installing a client" first, except the ones for after a server is running. When you adjust /etc/hosts, remove or comment any 127.0.0.1 <hostname>-style records.
It is possible that on a new system, you have to run this.
sudo setcap CAP_NET_BIND_SERVICE=+eip ~/aoe2de/ageLANServer/linux/server/server
Initialize a certificate.
~/aoe2de/ageLANServer/linux/server/bin/genCert.sh
Running a client
If you will play multiplayer, you need to know the IP address or hostname of the server. This sets the entries in /etc/hosts which can be done manually if necessary.
APPLY=1 ./set-etc-hosts.sh 192.168.1.45 # IP address or hostname of server
APPLY=1 ./set-cert-from-server.sh 192.168.1.45
Run the short launcher.
Running a server
Run the battle server manager in a terminal. It will spawn a new one to run, and return this prompt to you for the next command.
~/aoe2de/ageLANServer/linux/battle-server-manager/start_age2.sh
Run the server.
~/aoe2de/ageLANServer/linux/server/start_age2.sh
Then run the client as described above in "Running a client".
Adding mods
With script
From the second asset, use ~/aoe2de/scripts/set-initial-mods.sh. It depends on this network path for this file.
/mnt/public/Support/Games/aoe2de-on-linux/aoe2de-mods-subscribed.2026-06-26.tgz
Manually
Find the generated userid from ~/aoe2de/saves/settings.configs.user.ini.
eval $( awk '/account_steamid/' ~/aoe2de/saves/settings/configs.user.ini | tr -dc 'a-zA-Z=0-9_' )
Visit the user's mods directory and copy in the mods I have provided.
cd ~/".wine-aoe2de/drive_c/users/steamuser/Games/Age of Empires 2 DE/${account_steamid}/mods"
tar -zxf /mnt/public/Support/Games/aoe2de-on-linux/aoe2de-mods-subscribed.2026-06-26.tgz
Updating the game
A full copy of the official game from steam needs to be updated, and then built into a tarball. The path would be similar to /mnt/vm2/pcb-009-steam/steamapps/common/AoE2DE.
cd /mnt/vm2/pcb-009-steam/steamapps/common
tar -zcf "AoE2DE-$( date "+%F" ).tgz" AoE2DE
Note that this would not have the exact same directory structure as the original first asset which was aoe2de/AoE2DE/.
Updating "other components"
These dependencies might have newer versions. Check the references, and follow the "Building the package" steps.
Updating mods
Build a new tarball from the upstream machine that has the desired mods.
tar -zc -C "/mnt/vm2/pcb-009-steam/steamapps/compatdata/813780/pfx/drive_c/users/steamuser/Games/Age of Empires 2 DE/${account_steamid}/mods" -f /mnt/public/Support/Games/aoe2de-on-linux/aoe2de-mods-subscribed.$( date "+%F" ).tgz
Related files
- aoe2de-alldlcs-raw.2026-06-28.tgz
- aoe2de-other-components-2026-07-01.tgz
- aoe2de-mods-subscribed.2026-06-26.tgz
References
- Installing Proton on Linux: A Comprehensive Guide — linuxvox.com
- proton ge: https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton11-1/GE-Proton11-1.tar.gz from Releases · GloriousEggroll/proton-ge-custom
- Open-Wine-Components/umu-launcher: Unified launcher for Windows games on Linux
-
UMU Database Search shows nothing for "Empires" about AoE2, so GAMEID can be left undefined.
- luskaner/ageLANServerLauncherCompanion: Libraries to enhance or fix the game behaviour when using a custom launcher in Age LAN Server
- Releases · Detanup01/gbe_fork
- luskaner/ageLANServer: Web Server (and its launcher) for AoE 1, 2, 3 (all DE), AoE 4 and AoM: RT supporting offline multiplayer
-
Age of Empires II: Definitive Edition DLCs · SteamDB to find ids for the two DLCs I own that were not demonstrated in the configs.app.ini