Table of Contents

Class ClientRunPlan

Namespace
Valheim.Testing.Game
Assembly
Valheim.Testing.Game.dll

The game client a system test joins to its server, as a plan section. owned: the runner launches it from Install and stops only that process (Launch(ClientRunPlan, string, CancellationToken)); it must run in the desktop session where Steam is running and signed in, with a display. attach: an operator launched and signed in the client; the runner only connects to its ValheimCLI port and never touches the process. The join password stays in the client's own process environment, named by PasswordVariable.

public sealed class ClientRunPlan
Inheritance
object
ClientRunPlan

Properties

Architecture

Owned only: the slice a macOS client (Valheim.app) runs as, x64 or arm64. Left out, it is arm64 on Apple Silicon and x64 elsewhere. Select x64 explicitly for Rosetta on Apple Silicon. The native path needs a Doorstop library with an arm64 slice and a BepInEx core built on MonoMod 25 or later, and the launch refuses one without them rather than fall back to Rosetta. A Windows client is x64 only, so arm64 is refused for it. Validate(params string[]) runs the launch's slice and core check on a Valheim.app install on this machine, so a runner refuses such a plan before it starts anything. Recorded in client-process.json.

public string Architecture { get; set; }

Property Value

string

ArrivalSeconds

public int ArrivalSeconds { get; set; }

Property Value

int

BepInExSeconds

Owned only: how long after the launch BepInEx may take to write its first line to this launch's BepInEx/LogOutput.log, 5 to 1800 seconds (default 60; never more than StartSeconds). Doorstop starts BepInEx before the game's first frame, so a game still running without that line runs without BepInEx, and startup ends then instead of at the start deadline.

public int BepInExSeconds { get; set; }

Property Value

int

Capabilities

The ValheimCLI extension commands (owner/command, such as valheim.world/terrain) the run uses beyond what its runner requires itself (ClientRounds adds HostedRounds). Checked against CliManifest before an owned launch, and live once the client answers, owned or attached (Require(GameActor, params string[])).

public string[] Capabilities { get; set; }

Property Value

string[]

Character

An existing, disposable local character (never a cloud character).

public string Character { get; set; }

Property Value

string

CliManifest

Owned only: the full path of the CliCapabilityManifest of a ValheimCLI build (one plugin). For a disposable copy (the default) it names the set the copy stages, its DLLs beside the manifest; left out, the copy stages the toolkit's pinned bundle and checks against that bundle's manifest. With InPlace it names the set the install already holds; left out there, no static check runs and the report says so. Before launch the install (the copy, or the install in place) must hold exactly that set by SHA256 and offer every capability the run uses; a manifest that is missing or malformed is refused, never skipped. An attached client's files are its operator's, so it takes no manifest.

public string? CliManifest { get; set; }

Property Value

string

CliPreflight

Which capability checks apply, for the report's cliPreflight. An owned client: static and live (its copy's staged set, or the in-place install against its named CliManifest); an attached client: live only. An owned client in place without a manifest: live only, and says the static check was not run.

[JsonIgnore]
public string CliPreflight { get; }

Property Value

string

Crossplay

Joins the server's crossplay (PlayFab) lobby instead of its address (JoinCrossplay(string, string, string, string, TimeSpan, bool, CancellationToken, string?)), for a server plan with Crossplay. Leave out Join and PasswordVariable: the crossplay join command would carry a password as text, so the fixture server runs private without one.

public bool Crossplay { get; set; }

Property Value

bool

Environment

Owned only: non-secret process variables for this disposable client. Loader overrides are refused.

public Dictionary<string, string> Environment { get; set; }

Property Value

Dictionary<string, string>

Host

public string Host { get; set; }

Property Value

string

HostWorld

The client hosts this fixture world from its menu (a listen server) instead of joining a server (ClientRounds). Leave out Join, PasswordVariable and Crossplay.

public HostWorldPlan? HostWorld { get; set; }

Property Value

HostWorldPlan

InPlace

Owned only: run Install itself, as it is, instead of a disposable copy (the --in-place option of the toolkit's runners sets it for every client of a run). Nothing is written into the install: no ValheimCLI set is staged and no loader swapped. Preflight refuses an install without BepInEx or ValheimCLI, naming what is missing. The static ValheimCLI check runs only when the plan names a CliManifest; otherwise the report says it was not run (CliPreflight). Running Valheim, the run journal, leases and local-only test characters are checked as for a copy.

public bool InPlace { get; set; }

Property Value

bool

Install

Owned only: the client install. By default the run never launches it: a GameSession or ClientActor copies it into a disposable copy first, stages the pinned ValheimCLI set (the plan's CliManifest, or the toolkit's pinned bundle) and the loader rule into that copy, and launches the copy, so nothing in the install changes. With InPlace the run launches this install as it is, and it must already hold BepInEx and ValheimCLI.

public string Install { get; set; }

Property Value

string

InstallPins

Owned only: the install's game build, loader and patchers by SHA256 (Of(string)), checked against the source before a disposable profile is staged. When omitted for a disposable profile, the staged values are observed and enforced. An in-place client requires them. An attached client's install is its operator's and is not read, so its build is not pinned (the game refuses a join only across network versions).

public InstallPins? InstallPins { get; set; }

Property Value

InstallPins

Join

The server address the client joins, host:port. Left out for a Crossplay or hosting (HostWorld) client.

public string Join { get; set; }

Property Value

string

JoinSeconds

public int JoinSeconds { get; set; }

Property Value

int

JoinsHost

The client is a peer of the run's hosting client (HostingClientActor): it joins the host's world by the host's multiplayer identity (JoinHost(ClientRunPlan, GameActor, string, bool, CancellationToken)), since a listen server is reached through Steam, not at an address. Leave out Join, PasswordVariable, Crossplay and HostWorld.

public bool JoinsHost { get; set; }

Property Value

bool

LaunchArchitecture

Architecture as the launch takes it; an omitted value uses this client's host default.

[JsonIgnore]
public ClientArchitecture LaunchArchitecture { get; }

Property Value

ClientArchitecture

LaunchArguments

public string[] LaunchArguments { get; set; }

Property Value

string[]

MenuExpectations

Strict pins at the menu: plugins only.

public string MenuExpectations { get; }

Property Value

string

Mode

public string Mode { get; set; }

Property Value

string

Owned

public bool Owned { get; }

Property Value

bool

PasswordVariable

The environment variable, in the client's process, that holds the join password.

public string? PasswordVariable { get; set; }

Property Value

string

Pins

Every plugin the client loads by exact MD5, or absent. No world key: the runner adds the server's.

public Dictionary<string, string> Pins { get; set; }

Property Value

Dictionary<string, string>

Port

The client's ValheimCLI port (its [Server] Port setting); it must differ from the server's.

public int Port { get; set; }

Property Value

int

StartSeconds

public int StartSeconds { get; set; }

Property Value

int

Targetable

Protects the joined player without ghost mode (Protect(GameActor, bool)): it cannot die, but creatures see, hear and hunt it. Only for a test of AI, aggro or targeting that needs a player creatures notice; by default every joined player is protected with ghost mode, which holds on every peer that runs ValheimCLI.

public bool Targetable { get; set; }

Property Value

bool

Methods

CheckCliManifest(IEnumerable<string>?)

The static capability check alone: an owned client's install against its CliManifest (Check(string, IEnumerable<string>)), requiring only the ValheimCLI-owned entries in Capabilities and capabilities. A mod's own extensions are checked from the live game after its plugin loads; the ValheimCLI capability manifest cannot declare them. Before a disposable copy exists (Valheim.Testing.Game.ClientRunPlan.CopySource), capabilities are recorded for the copy's check before its launch, and a named CliManifest must offer them already; the result is then null. Null, with nothing read, also for an attached client and an owned one run in place without a manifest, whose capabilities only the live check sees (CliPreflight says so). Refuses a missing manifest (System.IO.FileNotFoundException), a malformed one (System.IO.InvalidDataException) and an install that is not its set or lacks a capability (System.InvalidOperationException). A profile on another host is read there, as its profile owner bound it.

public CliManifestCheck? CheckCliManifest(IEnumerable<string>? capabilities = null)

Parameters

capabilities IEnumerable<string>

Returns

CliManifestCheck

CheckInstallPins()

Checks owned pinned files and always refuses a profile if its source game changed after staging.

public void CheckInstallPins()

Preflight()

The static preflight of the run, after Validate(params string[]) and before anything is copied or started; every fact it needs is on disk here. A hosting client's fixture must still be its pinned files and must hold the world WorldUid names (Preflight()). An owned client's install must pass what its launch checks first: its InstallPins (patchers included) and BepInEx loader (a Doorstop proxy and configuration from different versions included). Then: every pinned plugin build is installed exactly once in BepInEx/plugins or BepInEx/scripts (a hash typed by hand or a wrong staged file matches none), a pinned plugin in scripts has ScriptEngine pinned and set to LoadOnStart, and ValheimCLI's standing expectations file, when its config sets one, parses one pin per line, names a world when strict, and agrees with the plan's pins and hosted world. With a CliManifest, last, the install's ValheimCLI files must be exactly its set and provide its own requested pack capabilities (CheckCliManifest(IEnumerable<string>?)). A mod adapter's extensions are confirmed after the client loads. An attached client's install is its operator's and is not read. Launch(ClientRunPlan, string, CancellationToken) runs the install part itself; ClientRounds runs all of it before it places the fixture.

public void Preflight()

Preflight(IEnumerable<string>)

Preflight(), with capabilities (owner/command) that the runner itself uses added to Capabilities for the manifest check (ClientRounds passes HostedRounds).

public void Preflight(IEnumerable<string> capabilities)

Parameters

capabilities IEnumerable<string>

RequirePasswordSource()

Refuses an owned joined client whose password variable is missing from this runner's process before any game or fixture is copied. The value must not be put in Environment, which is ordinary serialized plan data; the launched local client inherits the runner's variable, and a remote client receives it as a secret variable. Attached clients keep their operator's environment.

public void RequirePasswordSource()

Validate(params string[])

The rules every client section follows, plus absentPlugins, which must be pinned absent when the claim is what a client without them sees (a server-only mod). An owned client pins its install (InstallPins). A disposable profile may omit pins; its owner observes and binds the staged values.

public void Validate(params string[] absentPlugins)

Parameters

absentPlugins string[]

WorldExpectations(string)

Strict pins once joined: plugins and the server's world.

public string WorldExpectations(string worldUid)

Parameters

worldUid string

Returns

string