Class PlayerPlacement
Puts a joined client's player where a check needs it and proves it stands there: protection, arrival arranged by the
server, and stationary support read on the client. The server moves the player with the game's own teleport
(cli_teleport_peer), which runs on the player's client and needs nothing installed there, so this works on a
client that is not an admin and has cheats off. Arrival is established only by the client's own observations; a
teleport reply is not arrival.
public static class PlayerPlacement
- Inheritance
-
objectPlayerPlacement
Fields
ArrivalCapabilities
What Arrive(GameActor?, GameActor, HeightExpectation, TimeSpan, CancellationToken, bool, bool) needs from the client's ValheimCLI: the default plugin's bounded teleport commands
(cli_wait_teleportable, cli_teleport_trace_arm/cli_teleport_trace_wait), World Tools' support
wait, and its support reading (the flying check). ClientRounds checks them for an arriving client.
public static readonly IReadOnlyList<string> ArrivalCapabilities
Field Value
- IReadOnlyList<string>
Methods
Arrive(GameActor?, GameActor, HeightExpectation, TimeSpan, CancellationToken, bool, bool)
Teleports the player to point, a little above it so the character settles onto the ground, exactly
once, at the game's ordinary teleport timing, and returns once the client's own observation shows the player supported
there (Supported(Observation, HeightExpectation, float, float, float)). Who moves the player: with a server, the server
teleports its only connected player (OnlyPeer(GameActor); cli_teleport_peer, which needs nothing on the
client); with none, the client teleports its own player (cli_teleport), which needs the client's test access
(cheats acknowledged and, on a client joined to a server, ValheimCLI's AllowOnServerClients) and is the way to
place one of several players. Unless skipIntro is false it first ends a first-join intro
(SkipIntro(GameActor, TimeSpan)), a no-op for a character that has spawned before. The intro skip is one mutating game
command and cannot be cancelled while it is in flight. The subsequent read-only game waits use bounded intervals,
without repeatedly reading remote state: ValheimCLI waits until the player can be
teleported (the game silently drops a
teleport within 2 s of a spawn or of the previous teleport), arms a one-hop trace, and after the one teleport request
waits for the teleport to finish with a ready floor, then for supported arrival. A player shown flying is refused
before the teleport (see SetFly(GameActor, bool)). The read-only game waits use short bounded intervals so cancellation
is checked between them; the trace stays armed and the teleport is never issued again. With
loadedGround, the point's height is only the
teleport target: once the floor is ready the client measures the loaded ground there (TerrainProbe,
loaded-ground) and the landing must be supported at that height (Target). Use it
for a check that is not about terrain, where a location's levelling can move the ground from the generator's height;
a terrain check leaves it off, so a different ground fails. The loaded-ground comparison is one observation, not
a sliced game wait. timeout (at most 600 s) covers the intro and every wait. Only a named
in-game wait timeout starts another interval; a lost reply is an unknown outcome,
not a failure to act. Needs ArrivalCapabilities on the client, and valheim.world/terrain with
loadedGround.
public static PlayerPlacement.TeleportArrival Arrive(GameActor? server, GameActor client, HeightExpectation point, TimeSpan timeout, CancellationToken cancellation = default, bool skipIntro = true, bool loadedGround = false)
Parameters
serverGameActorclientGameActorpointHeightExpectationtimeoutTimeSpancancellationCancellationTokenskipIntroboolloadedGroundbool
Returns
OnlyPeer(GameActor)
The server's only connected peer that has a character, as cli_peers numbers it. Refuses none or several:
with more than one player the test cannot tell which one it would move.
public static int OnlyPeer(GameActor server)
Parameters
serverGameActor
Returns
- int
PeerCount(GameActor)
How many peers are connected to the server, from one cli_peers reading (World Tools). Refuses a reply whose
count line (OK: N peer(s)) disagrees with the peers it lists.
public static int PeerCount(GameActor server)
Parameters
serverGameActor
Returns
- int
Protect(GameActor)
Turns on god, ghost and debug modes for the local player (cli_set_player_safety true) and requires the game
to read all three back, and ghost mode to be written where every other peer reads it (ghostReplicated=True):
the game keeps ghost mode in the player's own process, while a creature's AI runs in whichever process owns it, so a
ghost only the local game knows about is still hunted by creatures another client simulates (#261). The command sets
the modes rather than toggling them, so running it again changes nothing; it is issued once and an unconfirmed reply
fails. Debug flying stays off, so support observations remain meaningful. WaitForWorld(string, TimeSpan, CancellationToken, bool)
calls this by default once the world is ready.
public static void Protect(GameActor client)
Parameters
clientGameActor
Protect(GameActor, bool)
Protect(GameActor), or with targetable god and debug modes without ghost mode
(cli_set_player_safety true targetable): the player cannot die but creatures notice it, for a test of AI or
targeting that opts out of ghost mode on purpose (Targetable).
public static void Protect(GameActor client, bool targetable)
Parameters
clientGameActortargetablebool
RequireSupported(GameActor, HeightExpectation, int, TimeSpan?, CancellationToken)
readings client observations interval apart (default three, half a second),
each of which must show the player settled on point: stationary support, not walking usability.
A reading that shows the player flying refuses the check (an System.InvalidOperationException, not a
SupportException): support cannot be measured while fly is on. cancellation also ends
the pause between readings.
public static IReadOnlyList<JsonElement> RequireSupported(GameActor client, HeightExpectation point, int readings = 3, TimeSpan? interval = null, CancellationToken cancellation = default)
Parameters
clientGameActorpointHeightExpectationreadingsintintervalTimeSpan?cancellationCancellationToken
Returns
- IReadOnlyList<JsonElement>
SetFly(GameActor, bool)
Turns the local player's debug fly on or off (cli_fly on|off, which sets rather than toggles) and requires
the game to read the requested state back. Fly is for review and visual steps only, such as looking at a site from
above: a flying player is never supported, so Arrive(GameActor?, GameActor, HeightExpectation, TimeSpan, CancellationToken, bool, bool) and RequireSupported(GameActor, HeightExpectation, int, TimeSpan?, CancellationToken) refuse while
it is on. Turn it off before measuring again.
public static void SetFly(GameActor client, bool on)
Parameters
clientGameActoronbool
SkipIntro(GameActor, TimeSpan)
Ends a new character's first-spawn intro (the Valkyrie ride) as the menu's Skip button does, or stops it before it
starts, and waits until the player has respawned on the ground (cli_skip_intro, not a cheat command).
Returns whether an intro was running; a character that has spawned before returns false and nothing changes.
The game records the skipped intro in the character, as it does after a normal first spawn.
public static bool SkipIntro(GameActor client, TimeSpan timeout)
Parameters
clientGameActortimeoutTimeSpan
Returns
- bool