Skip to content

Trigger Lander Capsule

Spawn a LanderCapsule under a living player, move the player into it, and trigger the descent animation without going through the death / respawn flow. Reach for this recipe when a mod wants a cinematic "the player just arrived" effect, or a time-skip cover window that locks the player's camera inside a capsule while world state mutates.

When to use

  • A mod wants to drop a capsule on a living player for a time-skip cover window.
  • A mod wants to re-create the "just arrived" cinematic without the expensive full respawn that rebuilds organs and empties inventory.
  • A scripted event wants to time a world mutation behind a ~13.5 second capsule sequence.

The LanderCapsule is completely independent of the death / respawn system. The respawn flow uses it through XML spawn data config, but the capsule itself has no awareness of whether the player is alive, dead, or respawning.

Prerequisites

  • Server-side code path (OnServer.Create / OnServer.MoveToSlot / OnServer.Interact).
  • A live Human reference with a valid ThingTransform.
  • Prefab.Find<LanderCapsule>("LanderCapsule") resolves to the capsule prefab (vanilla registers it at load).

Steps

// Create capsule at player's position
var pos = human.ThingTransform.position;
var rot = human.ThingTransform.rotation;
var capsule = OnServer.Create<LanderCapsule>(
    Prefab.Find<LanderCapsule>("LanderCapsule"), pos, rot);

// Move player into the seat (Slots[1])
OnServer.MoveToSlot(human, capsule.Slots[1]);

// Trigger descent (capsule teleports 100m up and drops back)
OnServer.Interact(capsule.InteractMode, 1);

Three calls. The capsule handles everything else.

API signatures

Source: $(StationeersPath)\rocketstation_Data\Managed\Assembly-CSharp.dll :: Assets.Scripts.Objects.Prefab, OnServer.

All four calls are public statics:

// Assets.Scripts.Objects.Prefab
public static T Find<T>(string prefabName) where T : Thing
public static T Find<T>(int prefabHash) where T : Thing

// OnServer (no namespace, global)
public static T Create<T>(Thing prefab, Vector3 position, Quaternion rotation) where T : Thing
public static void MoveToSlot(DynamicThing childThing, Slot slot)
public static void Interact(Interactable interactable, int state, bool skipAnimation = false)

Important typing details:

  • Prefab.Find<T> has no parameterless overload. The original recipe snippet Prefab.Find<LanderCapsule>() would not compile. The parameter is either the prefab name (string) or the precomputed Animator.StringToHash (int). The canonical prefab name for the lander capsule matches the type name, "LanderCapsule".
  • OnServer.MoveToSlot takes DynamicThing, not Thing. Human : Entity : DynamicThing, so passing a Human is valid.
  • capsule.InteractMode is an Interactable (inherited from Thing.InteractMode, a property). The int state parameter is the state index on Interactable, which for Action == InteractableType.Mode indexes LanderMode: 0 = AtRest, 1 = Descending, 2 = Venting. Passing 1 triggers LanderCapsule.OnInteractableStateChanged with newState == 1, which calls BeginDescent().Forget().
  • capsule.Slots is public List<Slot> (inherited from Thing.Slots). Slots[0] is the door, Slots[1] is the seat.

Using as time-skip cover

Players are locked inside the capsule for ~13.5 seconds (descent + door open + unlock). During this window:

  • Players can look around (FreeLook = true) but cannot exit or interact.
  • World changes can be made: repair items, advance sun, drain hunger, spawn debris.
  • The 13-second window can be extended by patching WaitThenOpen() to delay longer than 3 seconds, or by combining with stun (knock them to ~80 stun inside the capsule for a groggy descent, wake-up takes additional seconds).

Verification

  • Snapshot the target Human before and after the three calls: the ParentSlot should reference capsule.Slots[1] after the second call.
  • Observe the descent animation in-game; the capsule teleports 100m up and drops back down.
  • Confirm no new Human was created: the full respawn flow (Human.CreateCharacter()) resets all stats, creates new organs, empties inventory (old items go into a CardboardBox on the ground), and the old body becomes a DynamicBodyBag. None of this happens when you just create a LanderCapsule and move a living player into it.

Pitfalls

  • Client-side paths will silently no-op or desync; guard on GameManager.IsServer.
  • The 13.5 second window is a soft figure from observed behaviour (descent + door open + unlock). It is not a precise API-exposed constant; plan any world-mutation work to fit within that window rather than assume it is exact.
  • Moving a player into the capsule's Slots[1] locks their interaction input. If a mod wants the player to stay inside longer, patch WaitThenOpen() rather than repeatedly re-moving them into the slot.

Verification history

  • 2026-04-20: page created from the Research migration; verbatim content lifted from F0090 and F0095p (Plans/LLM/RESEARCH.md:471-491).
  • 2026-04-21: corrected Prefab.Find<LanderCapsule>() to Prefab.Find<LanderCapsule>("LanderCapsule"). The parameterless form does not exist in Assets.Scripts.Objects.Prefab; only Find<T>(string) and Find<T>(int) overloads are defined. The original snippet would not have compiled. Added "API signatures" sub-section with full typing details. Verified in 0.2.6228.27061.

Open questions

  • The prefab name used with Prefab.Find<LanderCapsule>(...) is asserted as "LanderCapsule" based on the Stationeers convention that Thing.PrefabName equals the GameObject name (see Prefab.cs:2297 / :2333: thing2.PrefabName = thing.name;) and the type being named LanderCapsule. In-game validation (call Prefab.Find<LanderCapsule>("LanderCapsule") and confirm non-null) is still pending.