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
Humanreference with a validThingTransform. 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 snippetPrefab.Find<LanderCapsule>()would not compile. The parameter is either the prefab name (string) or the precomputedAnimator.StringToHash(int). The canonical prefab name for the lander capsule matches the type name,"LanderCapsule".OnServer.MoveToSlottakesDynamicThing, notThing.Human : Entity : DynamicThing, so passing aHumanis valid.capsule.InteractModeis anInteractable(inherited fromThing.InteractMode, a property). Theint stateparameter is the state index onInteractable, which forAction == InteractableType.ModeindexesLanderMode:0 = AtRest,1 = Descending,2 = Venting. Passing1triggersLanderCapsule.OnInteractableStateChangedwithnewState == 1, which callsBeginDescent().Forget().capsule.Slotsispublic List<Slot>(inherited fromThing.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
Humanbefore and after the three calls: theParentSlotshould referencecapsule.Slots[1]after the second call. - Observe the descent animation in-game; the capsule teleports 100m up and drops back down.
- Confirm no new
Humanwas created: the full respawn flow (Human.CreateCharacter()) resets all stats, creates new organs, empties inventory (old items go into aCardboardBoxon the ground), and the old body becomes aDynamicBodyBag. None of this happens when you just create aLanderCapsuleand 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, patchWaitThenOpen()rather than repeatedly re-moving them into the slot.
At 0.2.6428.27798: the capsule saves the world when it opens on the local player¶
LanderCapsule.WaitThenOpen (312201-312214 in the 0.2.6428.27798 decompile) ends by saving the world when the seat holds the local player's entity:
if (GameManager.RunSimulation && SeatSlot.Get<Entity>() == InventoryManager.Parent)
{
SaveHelper.Save(XmlSaveLoad.Instance.CurrentStationName, default(CancellationToken)).Forget();
}
So this recipe, run on the player in single player or on a listen host's own player, ends its cover window with a save of the world under its current name, about 3.5 s after the capsule lands. Seating a joiner on a listen host, or anyone on a dedicated server (where InventoryManager.Parent is never set), does not save. A mutation made during the window is therefore written to disk at its end, and a patch that delays WaitThenOpen delays the save with it. Measured for the game's own arrival capsules, not for this recipe: see LanderCapsule, "At 0.2.6428.27798: the descent waits for Running, and the opening saves the world for the local player".
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>()toPrefab.Find<LanderCapsule>("LanderCapsule"). The parameterless form does not exist inAssets.Scripts.Objects.Prefab; onlyFind<T>(string)andFind<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. - 2026-09-27: added "At 0.2.6428.27798: the capsule saves the world when it opens on the local player" under "Pitfalls", from the 0.2.6428.27798 decompile of both compiles; the save is measured for the game's arrival capsules on the LanderCapsule page, not for this recipe. Additive; the other sections keep their 0.2.6228.27061 stamps and were not re-read. The open question gains a note on the arrival capsule's prefab name.
Open questions¶
- The prefab name used with
Prefab.Find<LanderCapsule>(...)is asserted as"LanderCapsule"based on the Stationeers convention thatThing.PrefabNameequals the GameObject name (seePrefab.cs:2297/:2333:thing2.PrefabName = thing.name;) and the type being namedLanderCapsule. In-game validation (callPrefab.Find<LanderCapsule>("LanderCapsule")and confirm non-null) is still pending. Note for whoever checks: the capsule the game itself spawns for an arriving player is the prefabLanderCapsuleSmall(startconditions.xmlspawnLanderCapsuleSmall, and the test rig's reads of 2026-09-27 at 0.2.6428.27798); whether any prefab is named plainLanderCapsulewas not checked.