Headless Mode
With --headless, the launcher opens no window. It starts CONTROL in the running game, writes status lines to standard output and ends with an exit code.
When To Use It
Use headless mode to:
- start CONTROL from another program or a test harness
- install a
settings.inibefore CONTROL starts - copy a module file or module folder into the modules folder before CONTROL starts
- read the launcher's progress and result from Python or another language
Start the game first
The launcher does not start the game. Start Age of Empires II: Definitive Edition and wait until its window is open and not minimized. Otherwise the launcher ends with exit code 6 or 7.
Command Line
AoE2Control.exe --headless [--timeout-ms <ms>] [--override-settings <file>] [--override-module <file-or-folder>]
An option's value can follow a space or =:
--override-settings "C:\path\to\settings.ini"--override-settings="C:\path\to\settings.ini"
The launcher is a Windows (GUI) program. PowerShell does not wait for it or set $LASTEXITCODE unless you capture its output, as the examples do.
Arguments
| Argument | Description |
|---|---|
--headless |
Runs without a window and writes status lines to standard output. |
--timeout-ms <ms> |
How long to wait, in milliseconds, for CONTROL to report that it is ready or has failed. Default 120000. When CONTROL is still starting in the game from an earlier launch, or still unloading, the launcher first waits up to this long for that, then up to this long again for the new start, so a launch can take up to twice the value. Accepts a whole number from 1 to 4294967295. |
--override-settings <file> |
Replaces %appdata%\CONTROL\AoE2Control\settings.ini with the given file before CONTROL starts. |
--override-module <file-or-folder> |
Copies a module file or module folder into %appdata%\CONTROL\AoE2Control\modules\ before CONTROL starts. |
--rmside-status-json, --rmside-ui=hidden |
Used by the AoE2RMSIDE map editor. Both are required together, need --headless and cannot be combined with the override options. Status lines become JSON, and the CONTROL menu and module drawings stay hidden. |
Any other argument ends the launcher with exit code 2.
RMS IDE Endpoint
While CONTROL runs, it serves the RMS IDE endpoint, the named pipe \\.\pipe\AoE2ControlRmsIdeV1 that AoE2RMSIDE uses. It runs however CONTROL was started, not only after a launch with the RMS IDE options. Every process running under your Windows user can connect to it and call all of its requests, including requests that start a match, end the match and unload CONTROL. Processes of other Windows users cannot connect. If another program already uses the pipe's name when CONTROL starts, the endpoint stays off, and a launch with the RMS IDE options ends with exit code 10.
Override Behavior
The launcher applies overrides after it finds the game window and before it starts CONTROL.
- If the game is not running or its window is not ready, nothing is copied.
- If CONTROL already runs in the game, nothing is copied and the launcher exits with code
3. A running CONTROL keeps its settings in memory and would overwrite the new files. Restart the game first. - If an override fails, the launcher restores the previous files and exits with code
3.
--override-settings
- The source must be a file.
- It replaces
%appdata%\CONTROL\AoE2Control\settings.ini.
--override-module
- The source can be a file or a folder.
- A file is copied to
%appdata%\CONTROL\AoE2Control\modules\<file-name>. - A folder is copied to
%appdata%\CONTROL\AoE2Control\modules\<folder-name>\. A trailing\or\.is ignored, soC:\temp\my_module\installs asmy_module. - An existing file or folder of the same name is replaced as a whole: files in the old folder that the source does not have are deleted. Other modules are not touched.
- The launcher refuses a source folder that contains the CONTROL config folder, and a destination that is a link or junction.
See Config Location for the folder layout.
Output
The launcher writes one line each time its status changes. Output to a pipe or file is UTF-8. The first line is the launcher version. A typical successful start:
v1.1.1
Scanning...
Checking game startup...
Waiting for connection...
Initializing...
Fetching Offsets...
Offsets Ready
Testing D3D11
Ready
The progress lines can change between versions. Scripts should use the last line and the exit code.
These last lines mean success (exit code 0):
| Line | Meaning |
|---|---|
Ready |
CONTROL runs. |
Ready - Partially outdated |
CONTROL runs, but some of its functions do not work on this game version. |
Ready - Requires update |
CONTROL runs, but important functions do not work on this game version. Wait for a CONTROL update. |
Already Running! |
The same CONTROL version already runs in the game. The launcher leaves it running. |
Headless mode exits at the first of these lines. During a match CONTROL checks more game functions; the launcher window can then change Ready to one of the warnings, but a headless launcher has already exited.
Exit Codes
| Exit Code | Meaning | Last line |
|---|---|---|
0 |
Success. | See Output. |
1 |
Another launcher is already running. | Launcher already running |
2 |
Invalid command-line arguments. | For example Unknown argument: --foo, Missing value for --override-module, Invalid value for --timeout-ms |
3 |
An override could not be applied, or CONTROL already runs in the game and overrides were given. | For example Override settings file not found, CONTROL is already running in the game. Restart the game to apply overrides |
4 |
CONTROL failed to start for a reason not listed below. | For example Offset Error: ..., Startup validation failed, Render Hook Failed, Target process exited before startup completed |
5 |
CONTROL in the game has another version or failed to start earlier. Restart the game. | CONTROL <version> is already running in this game. Restart the game to use version <version>, CONTROL failed to start in this game (<reason>). Restart the game |
6 |
The game is not running. | Process not found |
7 |
The game window is not ready: not open, minimized or smaller than 640x360. | Game window not ready |
8 |
Injection failed. | The injection error, for example Process open failed |
9 |
No result within --timeout-ms. |
Timed out waiting for startup status, CONTROL is still starting in this game, CONTROL is still unloading in this game |
10 |
Only with the RMS IDE options: the RMS IDE endpoint is missing or another process serves its pipe. | The RMS IDE endpoint did not start in this game, The RMS IDE endpoint pipe is served by another process |
Offset Error means CONTROL does not support this game version yet. The full line is Offset Error: game version <version> is not supported (rows <numbers>). Wait for a CONTROL update. Details: %APPDATA%\CONTROL\AoE2Control\diagnostics\latest.json. Include the row numbers and latest.json when you report it.
Examples
Start CONTROL and print the exit code (PowerShell):
.\AoE2Control.exe --headless | Out-Host
$LASTEXITCODE
Apply a custom settings file:
.\AoE2Control.exe --headless --override-settings "C:\temp\settings.ini" | Out-Host
Copy a module folder before startup:
.\AoE2Control.exe --headless --override-module "C:\temp\my_module" | Out-Host
Copy a single module entry file before startup:
.\AoE2Control.exe --headless --override-module "C:\temp\my_module.main.lua" | Out-Host
Python Example
This script starts the launcher, prints its status lines and checks the exit code:
from pathlib import Path
import subprocess
launcher_path = Path(r"C:\AoE2Control\AoE2Control.exe")
override_settings = None
override_module = None
args = [str(launcher_path), "--headless"]
if override_settings is not None:
args.extend(["--override-settings", str(override_settings)])
if override_module is not None:
args.extend(["--override-module", str(override_module)])
process = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding="utf-8",
errors="replace",
)
assert process.stdout is not None
for raw_line in process.stdout:
line = raw_line.rstrip("\r\n")
if not line:
continue
print(f"[launcher] {line}")
exit_code = process.wait()
print(f"launcher exit code: {exit_code}")
if exit_code != 0:
raise SystemExit(exit_code)
Set launcher_path to the location of AoE2Control.exe on your system.