Class GameLaunch
One BepInEx game process's launch, as data: the executable, its working directory and arguments, the variables set for it, the entries put in front of a search list's existing value, and the inherited variables removed. It reproduces what BepInExPack_Valheim's start scripts export, without the script, so the started process ID is the game's own. ForServer(string, IEnumerable<string>, IReadOnlyDictionary<string, string>?, ServerPlatform?) builds one for a dedicated server and ForClient(string, IEnumerable<string>, IReadOnlyDictionary<string, string>?, ClientPlatform?, ClientArchitecture?, bool, IEnumerable<string>?) one for a game client. A launch is built for this machine (render it with ToStartInfo()) or, given a host platform, for a host of a multi-machine session, where the hosting layer's server or interactive-client start runs it. It also says what an install on this machine is: DetectServer(string) and DetectClient(string) read the platform from the files, RequireServerExecutable(string) and RequireClientExecutable(string) the executable, and ClientLaunchArchitectures(string) the slices a client can start as.
public sealed class GameLaunch
- Inheritance
-
objectGameLaunch
Remarks
Both kinds share one rule set. The caller's Doorstop variables and --doorstop-* arguments are refused, inherited Doorstop
variables are removed apart from the ones the launch sets, and SteamAppId defaults to 892970. On Linux and macOS,
Doorstop is enabled for BepInEx's preloader and its library directories are put in front of the existing value. A launch for
this machine checks the runtime's or install's files before it is built. A launch for a host checks only the path rules there, and
the host checks RequiredFiles when it starts.
Fields
ClientMacBundle
public const string ClientMacBundle = "Valheim.app"
Field Value
- string
ClientWindowsExecutable
public const string ClientWindowsExecutable = "valheim.exe"
Field Value
- string
ConsoleArgument
public const string ConsoleArgument = "-console"
Field Value
- string
MacArchLauncher
public const string MacArchLauncher = "/usr/bin/arch"
Field Value
- string
ServerLinuxExecutable
public const string ServerLinuxExecutable = "valheim_server.x86_64"
Field Value
- string
ServerMacExecutable
The macOS dedicated server (Steam app 896660's macOS depot), relative to the runtime's root: a universal Mach-O
(x86_64 and arm64) beside Unity's player and Mono libraries, with its Data folder next to it. Not an app bundle.
public const string ServerMacExecutable = "valheim_server/Valheim"
Field Value
- string
ServerWindowsExecutable
public const string ServerWindowsExecutable = "valheim_server.exe"
Field Value
- string
SteamAppId
The game's Steam app id. Both the client and the dedicated server read it from SteamAppId.
public const string SteamAppId = "892970"
Field Value
- string
Properties
Arguments
The game's arguments, in order.
public IReadOnlyList<string> Arguments { get; }
Property Value
- IReadOnlyList<string>
Environment
Variables set for the game, the caller's first.
public IReadOnlyDictionary<string, string> Environment { get; }
Property Value
- IReadOnlyDictionary<string, string>
Executable
The game executable's full path. On macOS, ToStartInfo() starts it through /usr/bin/arch, so the start
info's file name is that launcher.
public string Executable { get; }
Property Value
- string
LocalServerPlatform
The dedicated-server platform this machine runs: Windows, macOS, or Linux for any other Unix.
public static ServerPlatform LocalServerPlatform { get; }
Property Value
Prepended
Entries put in front of a search list's existing value (LD_LIBRARY_PATH, LD_PRELOAD, macOS's DYLD_*), as the pack's scripts do.
public IReadOnlyDictionary<string, string> Prepended { get; }
Property Value
- IReadOnlyDictionary<string, string>
RequiredFiles
Files the game and BepInEx loader need: relative to the game directory for a normal install, or absolute loader paths when a disposable profile supplies it.
public IReadOnlyList<string> RequiredFiles { get; }
Property Value
- IReadOnlyList<string>
SecretVariables
Names of variables whose values come from this process's environment at launch and reach only the game's environment (a client's join password, for example); never logged or written as evidence. A launch for this machine inherits them anyway.
public IReadOnlyList<string> SecretVariables { get; }
Property Value
- IReadOnlyList<string>
Unset
Inherited variables removed before the launch: Doorstop's, apart from the ones set here.
public IReadOnlyList<string> Unset { get; }
Property Value
- IReadOnlyList<string>
WorkingDirectory
The directory the process starts in: its game directory, or an owned loader profile for a Unix profile launch.
public string WorkingDirectory { get; }
Property Value
- string
Methods
ClientLaunchArchitectures(string)
The architectures this install can be launched as, host aside: x64 for Windows; on macOS, the slices both the game executable and one of the install's Doorstop libraries contain, arm64 only when that core also runs natively (ForClient(string, IEnumerable<string>, IReadOnlyDictionary<string, string>?, ClientPlatform?, ClientArchitecture?, bool, IEnumerable<string>?) explains the rule). Empty when no Doorstop library matches.
public static IReadOnlyList<ClientArchitecture> ClientLaunchArchitectures(string installDirectory)
Parameters
installDirectorystring
Returns
- IReadOnlyList<ClientArchitecture>
DetectClient(string)
Decides the platform from the install's contents, never from the host: valheim.exe or a Valheim.app bundle.
Refuses an install holding more than one, an empty one, the bundle itself instead of the directory holding it, a
dedicated-server runtime (which ForServer(string, IEnumerable<string>, IReadOnlyDictionary<string, string>?, ServerPlatform?) launches) and a Linux client (valheim.x86_64) with
System.PlatformNotSupportedException: Linux hosts run the dedicated server only.
public static ClientPlatform DetectClient(string installDirectory)
Parameters
installDirectorystring
Returns
DetectServer(string)
Decides the platform from the runtime's contents, never from the host: ServerWindowsExecutable,
ServerLinuxExecutable, or ServerMacExecutable with its Data folder. Refuses an ambiguous or
empty runtime, and a macOS game client (a Valheim.app bundle, or a directory holding one) with
System.PlatformNotSupportedException.
public static ServerPlatform DetectServer(string runtimeDirectory)
Parameters
runtimeDirectorystring
Returns
ForClient(string, IEnumerable<string>, IReadOnlyDictionary<string, string>?, ClientPlatform?, ClientArchitecture?, bool, IEnumerable<string>?)
The launch of one BepInEx game client. A client needs an interactive desktop session with a display, a GPU and a running,
signed-in Steam client. Starting it inside that session is ClientSession's job on this machine and
an interactive client's on a host. -console is added first unless console is false or the
caller passed it; other arguments follow unchanged. On Windows the pack's winhttp.dll proxy loads BepInEx and no
variable is needed. On macOS, Doorstop is enabled for BepInEx's preloader and its library inserted.
Without hostPlatform it is for this machine. install is then the install directory here,
whose contents decide the platform (DetectClient(string)). BepInEx's preloader and the platform's Doorstop
loader must be present, and on Windows doorstop_config.ini must enable Doorstop and target BepInEx's preloader. macOS
starts the bundle through /usr/bin/arch as the requested architecture, inserting a Doorstop library
that has that slice. arch fails rather than run another slice, so an arm64 request never falls back to Rosetta. On
Apple Silicon, arm64 is the default; x64 selects the Rosetta compatibility path explicitly. Arm64 also needs a BepInEx core
whose MonoMod.RuntimeDetour.dll is version 25 or later (legacy MonoMod cannot hook on arm64); an install without it is
refused here, before anything starts. The machine must be the client's own OS. A Linux machine or host is refused with
System.PlatformNotSupportedException: Linux hosts run the dedicated server only; start the client on Windows or macOS.
With hostPlatform (Windows or macOS) the launch is for a host of that platform.
install is then an absolute path there: a drive or UNC path on Windows, and on macOS a path without
':', ';' or '='. The caller's variables must be plain names. The Windows client is x64 only.
public static GameLaunch ForClient(string install, IEnumerable<string> arguments, IReadOnlyDictionary<string, string>? environment = null, ClientPlatform? hostPlatform = null, ClientArchitecture? architecture = null, bool console = true, IEnumerable<string>? secretVariables = null)
Parameters
installstringargumentsIEnumerable<string>environmentIReadOnlyDictionary<string, string>hostPlatformClientPlatform?architectureClientArchitecture?consoleboolsecretVariablesIEnumerable<string>For a host only: variables (for example the join password's) read from this process at launch and given only to the game; never logged or written as evidence. A launch for this machine inherits this process's environment and refuses them.
Returns
ForServer(string, IEnumerable<string>, IReadOnlyDictionary<string, string>?, ServerPlatform?)
The launch of one owned BepInEx dedicated server. Without hostPlatform it is for this machine.
runtime is then a runtime directory here, whose files decide the platform (DetectServer(string)).
BepInEx's preloader and core and the platform's Doorstop loader must be present, and on Windows
doorstop_config.ini must enable Doorstop and target BepInEx's preloader. On macOS the server starts through
/usr/bin/arch as the machine's own architecture (arm64 on Apple Silicon). Doorstop is enabled for BepInEx's preloader,
with a Doorstop library at the runtime's root that has that slice inserted (DYLD_INSERT_LIBRARIES, passed with
-e because the kernel strips DYLD_* from the SIP-protected arch). The stock BepInExPack's Doorstop and core are
x86_64-only, so a native launch needs a universal libdoorstop.dylib and a BepInEx core that runs natively. On Linux
the runtime's linux64 and doorstop_libs go in front of LD_LIBRARY_PATH, and
libdoorstop_x64.so in front of LD_PRELOAD. A caller's own values are kept behind them. A server runs only
on its own OS, except that a Windows machine may build a Linux launch for inspection. Any other mismatch refuses with
System.PlatformNotSupportedException.
With hostPlatform the launch is for a host of that platform. runtime is then an absolute
path there: a drive path on Windows, and on Unix a path without ':', ';' or '=', which the loader's search lists and
env cannot hold. The caller's variables must be plain names, and on Linux they may not set
LD_LIBRARY_PATH/LD_PRELOAD, which the host session supplies.
public static GameLaunch ForServer(string runtime, IEnumerable<string> arguments, IReadOnlyDictionary<string, string>? environment = null, ServerPlatform? hostPlatform = null)
Parameters
runtimestringargumentsIEnumerable<string>environmentIReadOnlyDictionary<string, string>hostPlatformServerPlatform?
Returns
RequireClientExecutable(string)
Returns the detected client executable's full path (inside the bundle on macOS). A client runs only on its own OS: another host refuses with System.PlatformNotSupportedException, a Linux one too (Linux hosts run the dedicated server only). On macOS it must carry the user-execute bit.
public static string RequireClientExecutable(string installDirectory)
Parameters
installDirectorystring
Returns
- string
RequireServerExecutable(string)
Returns the detected server executable's full path. A server runs only on its own OS (a Windows host may resolve a Linux server for inspection); another host refuses with System.PlatformNotSupportedException. On Linux and macOS the server must carry the user-execute bit.
public static string RequireServerExecutable(string runtimeDirectory)
Parameters
runtimeDirectorystring
Returns
- string
ToStartInfo()
The start info for a launch built for this machine. The caller's variables are set, inherited Doorstop variables are removed apart from the ones the launch sets, and Prepended entries go in front of this process's own value. On Windows a dedicated server gets a console of its own (with no window), so stopping it signals that console rather than the runner's. A launch for a host refuses with System.InvalidOperationException.
public ProcessStartInfo ToStartInfo()
Returns
- ProcessStartInfo