Implement new automatic engine management.

This commit is contained in:
Paul Chote 2017-06-21 18:42:18 +00:00
parent aa7ad84d93
commit 60246de708
12 changed files with 262 additions and 85 deletions

4
.gitmodules vendored
View File

@ -1,4 +0,0 @@
[submodule "engine"]
path = engine
url = https://github.com/OpenRA/OpenRA/
branch = bleed

View File

@ -19,11 +19,14 @@
# make check
#
.PHONY: utility fetch-engine build build-engine clean clean-engine version check-scripts check test
.PHONY: utility build clean engine version check-scripts check test
.DEFAULT_GOAL := build
VERSION = $(shell git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || echo git-`git rev-parse --short HEAD`)
MOD_ID = $(shell awk -F= '/MOD_ID/ { print $$2 }' mod.config)
ENGINE_DIRECTORY = $(shell awk -F= '/ENGINE_DIRECTORY/ { print $$2 }' mod.config)
AUTOMATIC_ENGINE_MANAGEMENT = $(shell awk -F= '/AUTOMATIC_ENGINE_MANAGEMENT/ { print $$2 }' mod.config)
INCLUDE_DEFAULT_MODS = $(shell awk -F= '/INCLUDE_DEFAULT_MODS/ { print $$2 }' mod.config)
MOD_SEARCH_PATHS = "$(shell python -c "import os; print(os.path.realpath('.'))")/mods"
@ -37,13 +40,14 @@ HAS_MSBUILD = $(shell command -v msbuild 2> /dev/null)
HAS_LUAC = $(shell command -v luac 2> /dev/null)
LUA_FILES = $(shell find mods/*/maps/* -iname '*.lua')
utility:
@test -f engine/OpenRA.Utility.exe || (printf "OpenRA.Utility.exe not found! Build the engine first.\n"; exit 1)
engine:
@./fetch-engine.sh || (printf "Unable to continue without engine files\n"; exit 1)
@cd $(ENGINE_DIRECTORY) && make core
fetch-engine:
@test -f engine/OpenRA.sln || git submodule update --init
utility: engine
@test -f "$(ENGINE_DIRECTORY)/OpenRA.Utility.exe" || (printf "OpenRA.Utility.exe not found!\n"; exit 1)
build: build-engine
build: engine
ifeq ("$(HAS_MSBUILD)","")
@xbuild /nologo /verbosity:quiet /p:TreatWarningsAsErrors=true
else
@ -51,21 +55,15 @@ else
endif
@printf "The mod logic has been built.\n"
build-engine: fetch-engine
@cd engine && make
@printf "The engine has been built.\n"
clean: clean-engine
clean: engine
ifeq ("$(HAS_MSBUILD)","")
@xbuild /nologo /verbosity:quiet /p:TreatWarningsAsErrors=true /t:Clean
else
@msbuild /t:Clean /nr:false
endif
@printf "The mod logic been cleaned.\n"
clean-engine:
@cd engine && make clean
@printf "The engine directory has been cleaned.\n"
@printf "The mod logic has been cleaned.\n"
@cd $(ENGINE_DIRECTORY) && make clean
@printf "The engine has been cleaned.\n"
version:
@awk '{sub("Version:.*$$","Version: $(VERSION)"); print $0}' $(MANIFEST_PATH) > $(MANIFEST_PATH).tmp && \
@ -84,14 +82,11 @@ ifneq ("$(LUA_FILES)","")
endif
check: utility
@echo
@echo "Checking for explicit interface violations..."
@MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug engine/OpenRA.Utility.exe $(MOD_ID) --check-explicit-interfaces
@echo
@MOD_SEARCH_PATHS="$(MOD_SEARCH_PATHS)" mono --debug "$(ENGINE_DIRECTORY)/OpenRA.Utility.exe" $(MOD_ID) --check-explicit-interfaces
@echo "Checking for code style violations in OpenRA.Mods.$(MOD_ID)..."
@MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug engine/OpenRA.Utility.exe $(MOD_ID) --check-code-style OpenRA.Mods.$(MOD_ID)
@MOD_SEARCH_PATHS="$(MOD_SEARCH_PATHS)" mono --debug "$(ENGINE_DIRECTORY)/OpenRA.Utility.exe" $(MOD_ID) --check-code-style OpenRA.Mods.$(MOD_ID)
test: utility
@echo
@echo "Testing $(MOD_ID) mod MiniYAML..."
@MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug engine/OpenRA.Utility.exe $(MOD_ID) --check-yaml
@MOD_SEARCH_PATHS="$(MOD_SEARCH_PATHS)" mono --debug "$(ENGINE_DIRECTORY)/OpenRA.Utility.exe" $(MOD_ID) --check-yaml

1
engine

@ -1 +0,0 @@
Subproject commit 60bc114e391dea7a3e0525b73182b6ece5921de6

56
fetch-engine.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/sh
# Helper script used to check and update engine dependencies
# This should not be called manually
command -v curl >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl."; exit 1; }
command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; }
TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))")
TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}")
# shellcheck source=mod.config
. "${TEMPLATE_ROOT}/mod.config"
CURRENT_ENGINE_VERSION=$(cat "${ENGINE_DIRECTORY}/VERSION" 2> /dev/null)
if [ -f "${ENGINE_DIRECTORY}/VERSION" ] && [ "${CURRENT_ENGINE_VERSION}" = "${ENGINE_VERSION}" ]; then
exit 0
fi
if [ "${AUTOMATIC_ENGINE_MANAGEMENT}" = "True" ]; then
echo "OpenRA engine version ${ENGINE_VERSION} is required."
if [ -d "${ENGINE_DIRECTORY}" ]; then
if [ "${CURRENT_ENGINE_VERSION}" != "" ]; then
echo "Deleting engine version ${CURRENT_ENGINE_VERSION}."
else
echo "Deleting existing engine (unknown version)."
fi
rm -rf "${ENGINE_DIRECTORY}"
fi
echo "Downloading engine..."
curl -s -L -o "${AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME}" -O "${AUTOMATIC_ENGINE_SOURCE}" || exit 3
# Github zipballs package code with a top level directory named based on the refspec
# Extract to a temporary directory and then move the subdir to our target location
REFNAME=$(unzip -qql "${AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME}" | head -n1 | tr -s ' ' | cut -d' ' -f5-)
rm -rf "${AUTOMATIC_ENGINE_EXTRACT_DIRECTORY}"
mkdir "${AUTOMATIC_ENGINE_EXTRACT_DIRECTORY}"
unzip -qq -d "${AUTOMATIC_ENGINE_EXTRACT_DIRECTORY}" "${AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME}"
mv "${AUTOMATIC_ENGINE_EXTRACT_DIRECTORY}/${REFNAME}" "${ENGINE_DIRECTORY}"
rmdir "${AUTOMATIC_ENGINE_EXTRACT_DIRECTORY}"
rm "${AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME}"
echo "Compiling engine..."
cd "${ENGINE_DIRECTORY}" || exit 1
make version VERSION="${ENGINE_VERSION}"
exit 0
fi
echo "Automatic engine management is disabled."
echo "Please manually update the engine to version ${ENGINE_VERSION}."
exit 1

View File

@ -19,9 +19,15 @@ if %INCLUDE_DEFAULT_MODS% neq "True" goto start
set MOD_SEARCH_PATHS=%MOD_SEARCH_PATHS%,./mods
:start
cd engine
if not exist %ENGINE_DIRECTORY%\OpenRA.Game.exe goto noengine
cd %ENGINE_DIRECTORY%
:loop
OpenRA.Server.exe Game.Mod=%MOD_ID% Server.Name=%Name% Server.ListenPort=%ListenPort% Server.ExternalPort=%ExternalPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password%
goto loop
goto loop
:noengine
echo Required engine files not found.
echo Run `make all` in the mod directory to fetch and build the required files, then try again.
pause
exit /b

View File

@ -1,13 +1,18 @@
#!/bin/sh
# example launch script, see https://github.com/OpenRA/OpenRA/wiki/Dedicated for details
# Usage:
# $ ./launch-dedicated.sh # Launch a dedicated server with default settings
# $ Mod="d2k" ./launch-dedicated.sh # Launch a dedicated server with default settings but override the Mod
# $ Mod="<mod id>" ./launch-dedicated.sh # Launch a dedicated server with default settings but override the Mod
# Read the file to see which settings you can override
set -e
command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; }
command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; }
command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires mono."; exit 1; }
TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))")
TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}")
# shellcheck source=mod.config
. "${TEMPLATE_ROOT}/mod.config"
MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods"
@ -23,7 +28,14 @@ ADVERTISE_ONLINE="${AdvertiseOnline:-"True"}"
ENABLE_SINGLE_PLAYER="${EnableSingleplayer:-"False"}"
PASSWORD="${Password:-""}"
cd engine
cd "${TEMPLATE_ROOT}"
if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ]; then
echo "Required engine files not found."
echo "Run \`make\` in the mod directory to fetch and build the required files, then try again.";
exit 1
fi
cd "${ENGINE_DIRECTORY}"
while true; do
MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug OpenRA.Server.exe Game.Mod="${LAUNCH_MOD}" \

View File

@ -8,15 +8,27 @@ if %INCLUDE_DEFAULT_MODS% neq "True" goto launch
set MOD_SEARCH_PATHS=%MOD_SEARCH_PATHS%,./mods
:launch
cd engine
set TEMPLATE_DIR=%CD%
if not exist %ENGINE_DIRECTORY%\OpenRA.Game.exe goto noengine
cd %ENGINE_DIRECTORY%
OpenRA.Game.exe Game.Mod=%MOD_ID% Engine.LaunchPath="%TEMPLATE_LAUNCHER%" "Engine.ModSearchPaths=%MOD_SEARCH_PATHS%" "%*"
if %errorlevel% neq 0 goto crashdialog
cd ..
set ERROR=%errorlevel%
cd %TEMPLATE_DIR%
if ERROR neq 0 goto crashdialog
exit /b
:noengine
echo Required engine files not found.
echo Run `make all` in the mod directory to fetch and build the required files, then try again.
pause
exit /b
:crashdialog
echo ----------------------------------------
echo OpenRA has encountered a fatal error.
echo * Log Files are available in Documents\OpenRA\Logs
echo * FAQ is available at https://github.com/OpenRA/OpenRA/wiki/FAQ
echo ----------------------------------------
pause
pause

View File

@ -1,7 +1,14 @@
#!/bin/sh
set -e
command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; }
command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; }
command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires mono."; exit 1; }
TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))")
TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}")
# shellcheck source=mod.config
. "${TEMPLATE_ROOT}/mod.config"
MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods"
@ -9,5 +16,12 @@ if [ "${INCLUDE_DEFAULT_MODS}" = "True" ]; then
MOD_SEARCH_PATHS="${TEMPLATE_PATHS},./mods"
fi
cd engine
mono OpenRA.Game.exe Engine.LaunchPath="${TEMPLATE_LAUNCHER}" "Engine.ModSearchPaths=${MOD_SEARCH_PATHS}" Game.Mod=${MOD_ID} "$@"
cd "${TEMPLATE_ROOT}"
if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ]; then
echo "Required engine files not found."
echo "Run \`make\` in the mod directory to fetch and build the required files, then try again.";
exit 1
fi
cd "${ENGINE_DIRECTORY}"
mono OpenRA.Game.exe Engine.LaunchPath="${TEMPLATE_LAUNCHER}" "Engine.ModSearchPaths=${MOD_SEARCH_PATHS}" Game.Mod="${MOD_ID}" "$@"

135
make.ps1
View File

@ -95,11 +95,10 @@ function Version-Command
function Test-Command
{
if (Test-Path ./engine/OpenRA.Utility.exe)
if (Test-Path $utilityPath)
{
$msg = "Testing " + $modID + " mod MiniYAML"
echo $msg
./engine/OpenRA.Utility.exe $modID --check-yaml
echo "Testing $modID mod MiniYAML"
Invoke-Expression "$utilityPath $modID --check-yaml"
}
else
{
@ -109,14 +108,13 @@ function Test-Command
function Check-Command
{
if (Test-Path ./engine/OpenRA.Utility.exe)
if (Test-Path $utilityPath)
{
echo "Checking for explicit interface violations..."
./engine/OpenRA.Utility.exe $modID --check-explicit-interfaces
Invoke-Expression "$utilityPath $modID --check-explicit-interfaces"
$msg = "Checking for code style violations in OpenRA.Mods." + $modID + "..."
echo $msg
./engine/OpenRA.Utility.exe $modID --check-code-style OpenRA.Mods.$modID
echo "Checking for code style violations in OpenRA.Mods.$modID..."
Invoke-Expression "$utilityPath $modID --check-code-style OpenRA.Mods.$modID"
}
else
{
@ -143,10 +141,10 @@ function Check-Scripts-Command
function Docs-Command
{
if (Test-Path ./engine/OpenRA.Utility.exe)
if (Test-Path $utilityPath)
{
./engine/OpenRA.Utility.exe $modID --docs | Out-File -Encoding "UTF8" DOCUMENTATION.md
./engine/OpenRA.Utility.exe $modID --lua-docs | Out-File -Encoding "UTF8" Lua-API.md
Invoke-Expression "$utilityPath $modID --docs | Out-File -Encoding 'UTF8' DOCUMENTATION.md"
Invoke-Expression "$utilityPath $modID --lua-docs | Out-File -Encoding 'UTF8' Lua-API.md"
echo "Docs generated."
}
else
@ -230,6 +228,36 @@ while($null -ne ($line = $reader.ReadLine()))
{
$env:INCLUDE_DEFAULT_MODS = $line.Replace('INCLUDE_DEFAULT_MODS=', '').Replace('"', '')
}
if ($line.StartsWith("ENGINE_VERSION"))
{
$env:ENGINE_VERSION = $line.Replace('ENGINE_VERSION=', '').Replace('"', '')
}
if ($line.StartsWith("AUTOMATIC_ENGINE_MANAGEMENT"))
{
$env:AUTOMATIC_ENGINE_MANAGEMENT = $line.Replace('AUTOMATIC_ENGINE_MANAGEMENT=', '').Replace('"', '')
}
if ($line.StartsWith("AUTOMATIC_ENGINE_SOURCE"))
{
$env:AUTOMATIC_ENGINE_SOURCE = $line.Replace('AUTOMATIC_ENGINE_SOURCE=', '').Replace('"', '')
}
if ($line.StartsWith("AUTOMATIC_ENGINE_EXTRACT_DIRECTORY"))
{
$env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY = $line.Replace('AUTOMATIC_ENGINE_EXTRACT_DIRECTORY=', '').Replace('"', '')
}
if ($line.StartsWith("AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME"))
{
$env:AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME = $line.Replace('AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME=', '').Replace('"', '')
}
if ($line.StartsWith("ENGINE_DIRECTORY"))
{
$env:ENGINE_DIRECTORY = $line.Replace('ENGINE_DIRECTORY=', '').Replace('"', '')
}
}
$env:MOD_SEARCH_PATHS = (Get-Item -Path ".\" -Verbose).FullName + "\mods"
@ -241,51 +269,76 @@ if ($env:INCLUDE_DEFAULT_MODS -eq "True")
# Run the same command on the engine's make file
if ($command -eq "all" -or $command -eq "clean")
{
if (Test-Path ./engine/OpenRA.sln)
$templateDir = $pwd.Path
$versionFile = $env:ENGINE_DIRECTORY + "/VERSION"
if ((Test-Path $versionFile) -and [System.IO.File]::OpenText($versionFile).ReadLine() -eq $env:ENGINE_VERSION)
{
cd ".\engine\"
$exp = ".\make.cmd " + $command
Invoke-Expression $exp
cd $env:ENGINE_DIRECTORY
Invoke-Expression ".\make.cmd $command"
echo ""
cd ..
cd $templateDir
}
elseif ($env:AUTOMATIC_ENGINE_MANAGEMENT -ne "True")
{
echo "Automatic engine management is disabled."
echo "Please manually update the engine to version $env:ENGINE_VERSION."
WaitForInput
}
else
{
if (Get-Command 'git' -ErrorAction SilentlyContinue)
{
$gitRepo = git rev-parse --is-inside-work-tree
if ($gitRepo)
{
git submodule update --init
echo "OpenRA engine version $env:ENGINE_VERSION is required."
if (Test-Path ./engine/OpenRA.sln)
{
cd ".\engine\"
$exp = ".\make.cmd " + $command
Invoke-Expression $exp
echo ""
cd ..
}
else
{
echo "Failed to initialize the submodule. You need to download the engine by hand."
WaitForInput
}
if (Test-Path $env:ENGINE_DIRECTORY)
{
if ((Test-Path $versionFile) -and [System.IO.File]::OpenText($versionFile).ReadLine() -ne "")
{
echo "Deleting engine version $currentEngine."
}
else
{
echo "Not a git repository. You need to download the engine by hand."
WaitForInput
echo "Deleting existing engine (unknown version)."
}
rm $env:ENGINE_DIRECTORY -r
}
else
echo "Downloading engine..."
if (Test-Path $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY)
{
echo "Unable to locate Git. You need to download the engine by hand."
WaitForInput
rm $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY -r
}
$url = $env:AUTOMATIC_ENGINE_SOURCE
$url = $url.Replace("$", "").Replace("{ENGINE_VERSION}", $env:ENGINE_VERSION)
mkdir $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY > $null
$dlPath = Join-Path $pwd (Split-Path -leaf $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY)
$dlPath = Join-Path $dlPath (Split-Path -leaf $env:AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME)
$client = new-object System.Net.WebClient
$client.DownloadFile($url, $dlPath)
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::ExtractToDirectory($dlPath, $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY)
rm $dlPath
$extractedDir = Get-ChildItem -Recurse | ?{ $_.ToString().StartsWith("OpenRA-") -and $_.PSIsContainer }
Move-Item $extractedDir.FullName -Destination $templateDir
Rename-Item $extractedDir.Name (Split-Path -leaf $env:ENGINE_DIRECTORY)
rm $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY -r
cd $env:ENGINE_DIRECTORY
Invoke-Expression ".\make.cmd version $env:ENGINE_VERSION"
Invoke-Expression ".\make.cmd $command"
echo ""
cd $templateDir
}
}
$utilityPath = $env:ENGINE_DIRECTORY + "/OpenRA.Utility.exe"
$execute = $command
if ($command.Length -gt 1)
{

View File

@ -1,8 +1,20 @@
# The id of the mod to launch by default. This must exist as a directory in the mods directory
MOD_ID="example"
ENGINE_VERSION="3e5c211"
# Import the default OpenRA mods for use as external mod references
# in your mod.yaml. Accepts values "True" or "False".
# WARNING: This setting is provided to simplify early mod development
# and must be disabled before installers can be generated
INCLUDE_DEFAULT_MODS="False"
# Automatically manage engine dependencies
AUTOMATIC_ENGINE_MANAGEMENT="True"
AUTOMATIC_ENGINE_SOURCE="https://github.com/OpenRA/OpenRA/archive/${ENGINE_VERSION}.zip"
# Temporary file/directory names used when automatically downloading the engine
AUTOMATIC_ENGINE_EXTRACT_DIRECTORY="./engine_temp"
AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME="engine.zip"
ENGINE_DIRECTORY="./engine"

View File

@ -9,7 +9,9 @@ if %INCLUDE_DEFAULT_MODS% neq "True" goto start
set MOD_SEARCH_PATHS=%MOD_SEARCH_PATHS%,./mods
:start
cd engine
set TEMPLATE_DIR=%CD%
if not exist %ENGINE_DIRECTORY%\OpenRA.Game.exe goto noengine
cd %ENGINE_DIRECTORY%
:loop
echo.
@ -20,10 +22,16 @@ echo Press enter to view a list of valid utility commands.
echo.
set /P command=Please enter a command: OpenRA.Utility.exe %MOD_ID%
if /I "%command%" EQU "--exit" (cd .. & exit /b)
if /I "%command%" EQU "--exit" (cd %TEMPLATE_DIR% & exit /b)
echo.
echo ----------------------------------------
echo.
echo OpenRA.Utility.exe %MOD_ID% %command%
call OpenRA.Utility.exe %MOD_ID% %command%
goto loop
goto loop
:noengine
echo Required engine files not found.
echo Run `make all` in the mod directory to fetch and build the required files, then try again.
pause
exit /b

View File

@ -1,10 +1,17 @@
#!/bin/sh
# Usage:
# $ ./utility.sh # Launch the OpenRA.Utility with the default mod
# $ Mod="d2k" ./launch-utility.sh # Launch a dedicated server with a specific mod
# $ Mod="<mod id>" ./launch-utility.sh # Launch the OpenRA.Utility with a specific mod
set -e
command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; }
command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; }
command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires mono."; exit 1; }
TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))")
TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}")
# shellcheck source=mod.config
. "${TEMPLATE_ROOT}/mod.config"
MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods"
@ -14,5 +21,12 @@ fi
LAUNCH_MOD="${Mod:-"${MOD_ID}"}"
cd engine
cd "${TEMPLATE_ROOT}"
if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ]; then
echo "Required engine files not found."
echo "Run \`make\` in the mod directory to fetch and build the required files, then try again.";
exit 1
fi
cd "${ENGINE_DIRECTORY}"
MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug OpenRA.Utility.exe "${LAUNCH_MOD}" "$@"