Items.All → IReadOnlyList<ItemInfo> Every item in the game (315 entries). Cached after first access.
Shared C# layer the other mods build on.
Stable wrappers over Cairn's IL2CPP internals — items, inventory, world interaction, prompts, teleport — so mods don't re-derive the plumbing.
Features
Requires
MelonLoader only.
Read-only catalog of every item in the game.
Items.All → IReadOnlyList<ItemInfo> Every item in the game (315 entries). Cached after first access.
Items.Get(id) → ItemInfo Resolve a single item config by enum id.
id | InventoryItemStringIdEnum | The item's enum identifier. |
ItemInfo Per-item metadata.
.Id | InventoryItemStringIdEnum | Enum identifier. |
.Name | string | Display name. |
.StoredIn | StorageType | Which storage slot holds this item. |
.MaxStack | int | Maximum stack count. |
.UnitWeight | float | Weight per unit. NaN for non-physical items. |
foreach (var info in Items.All)
MelonLogger.Msg($"{info.Name} stored={info.StoredIn} w={info.UnitWeight:F2}");
var rope = Items.Get(InventoryItemStringIdEnum.Rope_Standard); Add items to and query the player's inventory.
Inventory.Add(id, count) → AddResult Add items to the appropriate storage slot. Stops cleanly at capacity.
id | InventoryItemStringIdEnum | Item to add. |
count | int | How many to add. |
AddResult Return value from Inventory.Add.
.Ok | bool | True if all requested items were added. |
.Added | int | How many were actually added. |
.Error | string | Failure reason when Ok is false. |
Inventory.Count(id) → int How many of an item the player currently holds.
id | InventoryItemStringIdEnum | Item to count. |
Inventory.StorageWeight(storage) → float Current total weight in a storage slot.
storage | StorageType | Which slot to query. |
Inventory.MaxBagWeight() → float The bag's weight capacity.
var result = Inventory.Add(InventoryItemStringIdEnum.Food_Nuts, 3);
if (!result.Ok) MelonLogger.Warning(result.Error);
else MelonLogger.Msg($"Added {result.Added}");
int count = Inventory.Count(InventoryItemStringIdEnum.Food_Nuts);
float load = Inventory.StorageWeight(StorageType.Bag); Warp the climber to any position in the current zone or across zones.
Teleport.Busy → bool True while a warp is in flight.
Teleport.To(position, done) Warp the climber to a world position in the current zone.
position | Vector3 | Target world position. |
done | Action<bool> | Callback — receives true on success. |
Teleport.ToZone(zone, position, done) Cross-zone warp. Streams the target zone if needed, then warps.
zone | ZoneSceneData | Target zone. Use World to resolve. |
position | Vector3 | Target world position inside that zone. |
done | Action<bool> | Callback — receives true on success. |
Teleport.To(targetPos, ok => {
if (!ok) MelonLogger.Warning("warp failed or busy");
});
var zone = World.ResolveZone(World.Current, "03_TheNeedle");
Teleport.ToZone(zone, targetPos, ok => { }); Enumerate authored worlds and zones, resolve zone assets by name.
World.Current → WorldZoneData The active world currently being streamed.
World.Worlds() → IEnumerable<WorldZoneData> Every authored world in the game.
World.Zones(world) → IEnumerable<ZoneSceneData> All zones belonging to a world.
world | WorldZoneData | World to enumerate. |
World.ResolveZone(world, name) → ZoneSceneData Find a zone by its asset name.
world | WorldZoneData | World to search within. |
name | string | Zone asset name, e.g. "01_FirstRidge". |
World.WorldOf(zone) → WorldZoneData Reverse-map a zone back to its owning world.
zone | ZoneSceneData | Zone to look up. |
foreach (var world in World.Worlds())
foreach (var zone in World.Zones(world))
MelonLogger.Msg($"{world.name}/{zone.name}");
var zone = World.ResolveZone(World.Current, "01_FirstRidge");
var owningWorld = World.WorldOf(zone); Enumerate story-beat sensors in the current scene.
Beats.Available → bool True when the story manager is live. Check before calling Snapshot.
Beats.Snapshot() → List<Beat> Every story-beat sensor in the current scene, sorted by label. Pure — no caching.
Beat A story-beat sensor location.
.Label | string | Authored beat name. |
.Position | Vector3 | World-space center of the sensor trigger. |
if (Beats.Available)
{
var beats = Beats.Snapshot();
foreach (var b in beats)
MelonLogger.Msg($"{b.Label} @{b.Position}");
if (beats.Count > 0)
Teleport.To(beats[0].Position, _ => { });
} Query game state and subscribe to screen-lifecycle events.
Screen.PawnSpawned → bool True when the climber pawn is live. The reliable "in gameplay" check.
Screen.IsMenu → bool True while the main menu is active.
Screen.IsInGame → bool True while in a gameplay state, including when a pause menu overlaps.
Screen.IsCutscene → bool True during a cutscene.
Screen.IsGameOver → bool True on the game-over screen.
Screen.IsBivouac → bool True while the bivouac (rest) screen is active.
Screen.CurrentMenu → Menu? Foreground menu canvas, or null when no menu is open.
Screen.MainMenuStep → int Current sub-step within the main menu flow.
Screen.OnGameStateChanged → event Fires on every GameState push or pop.
from | GameState | Previous state. |
to | GameState | New state. |
Screen.OnMenuChanged → event Fires when the foreground menu changes. Receives null when the stack empties.
menu | Menu? | New foreground menu, or null. |
Screen.OnCanvasOpened → event Fires when any menu or HUD canvas opens.
canvas | Canvas | The opened canvas. |
Screen.OnCanvasClosed → event Fires when any menu or HUD canvas closes.
canvas | Canvas | The closed canvas. |
Screen.OnTransitionStarted → event Fires at the start of any scene transition.
Screen.OnTransitionCompleted → event Fires when a scene transition finishes.
Screen.OnEnteringMenu → event Fires on the game→menu path, before the menu scene loads.
if (Screen.IsMenu) MelonLogger.Msg($"step={Screen.MainMenuStep}");
if (Screen.PawnSpawned) MelonLogger.Msg("live in gameplay");
Screen.OnGameStateChanged += (from, to) => MelonLogger.Msg($"{from} -> {to}");
Screen.OnMenuChanged += menu => MelonLogger.Msg(menu?.name ?? "no menu");
Screen.OnTransitionStarted += () => MelonLogger.Msg("transition started");
Screen.OnTransitionCompleted += () => MelonLogger.Msg("transition done");
Screen.OnCanvasOpened += c => MelonLogger.Msg($"opened {c.GetType().Name}"); Four prompt types for different interaction contexts. All take a string label and an optional Glyph; all return a handle.
Fixed screen-space prompt row rendered above the HUD.
ScreenPrompt.Show(text, glyph, parent?) → PromptHandle Render a [glyph] label row on the screen overlay. Pass parent to place it inside your own layout.
text | string | Label text. |
glyph | InputAction | Button icon from Glyph, or null. |
parent opt | Transform | Parent into a custom layout group. |
ScreenPrompt.Move(handle, pos) Reposition on the screen overlay. Coordinates are screen-center-relative.
handle | PromptHandle | Handle from Show. |
pos | Vector2 | Anchored position. |
ScreenPrompt.SetActive(handle, active) Show or hide without destroying. Layout re-flows automatically.
handle | PromptHandle | Handle from Show. |
active | bool | Visible state. |
ScreenPrompt.Hide(handle) Destroy the prompt.
handle | PromptHandle | Handle from Show. |
var h = ScreenPrompt.Show("Open the hatch", Glyph.Action(GameAction.Interact));
ScreenPrompt.Move(h, new Vector2(0, -120));
var h2 = ScreenPrompt.Show("Confirm", Glyph.Key("e"), parent: myRow.transform);
ScreenPrompt.SetActive(h, false);
ScreenPrompt.Hide(h); Floating world-space prompt that billboards to the camera.
WorldPrompt.Show(anchor, text, glyph, style?) → PromptHandle Float a [glyph] label over a world transform.
anchor | Transform | World-space anchor. |
text | string | Label text. |
glyph | InputAction | Button icon, or null. |
style opt | WorldPromptStyle | Tune float radius, wall offset, max height, and anchor tracking. |
WorldPrompt.Hide(handle) Destroy the prompt.
handle | PromptHandle | Handle from Show. |
WorldPromptStyle Display options for WorldPrompt.
.Radius | float | Float distance from the anchor. |
.WallOffset | float | Offset from the wall surface. |
.MaxHeight | float | Maximum vertical position. |
.FollowsAnchor | bool | Track a moving anchor each frame. |
var h = WorldPrompt.Show(thing.transform, "Activate", Glyph.Key("e"));
var style = new WorldPromptStyle { Radius = 0.5f, FollowsAnchor = false };
var h2 = WorldPrompt.Show(fixedAnchor, "Examine", null, style: style);
WorldPrompt.Hide(h); World prompt gated on the climber being within range on the ground (Walking mode only).
ProximityPrompt.Show(anchor, distance, text, glyph, onInteract) → ProximityInteractable Show a prompt and fire a callback when the button is pressed in range.
anchor | Transform | World-space anchor. |
distance | float | Detection radius in metres. |
text | string | Label text. |
glyph | InputAction | Button icon, or null. |
onInteract | Action | Called when the button is pressed in range. |
ProximityInteractable.Destroy() Remove the prompt and interactable.
var p = ProximityPrompt.Show(
chest.transform, 3f,
"Loot", Glyph.Action(GameAction.Interact),
onInteract: () => OpenChest());
p.Destroy(); World prompt gated on a hand physically reaching into the trigger sphere (Climbing mode only).
ReachPrompt.Show(anchor, text, glyph, onInteract, radius?, localOffset?) → ReachInteractable Show a prompt and fire a callback when a hand enters the sphere and the button is pressed.
anchor | Transform | Moving anchor (e.g. a partner climber). |
text | string | Label text. |
glyph | InputAction | Button icon, or null. |
onInteract | Action | Called when triggered. |
radius opt | float | Detection sphere radius. |
localOffset opt | Vector3 | Offset from anchor in local space. |
ReachPrompt.Create(position, text, glyph, onInteract, radius?) → ReachInteractable Fixed world-point variant.
position | Vector3 | Fixed world position. |
text | string | Label text. |
glyph | InputAction | Button icon, or null. |
onInteract | Action | Called when triggered. |
radius opt | float | Detection sphere radius. |
ReachInteractable.Destroy() Remove the prompt and interactable.
var r = ReachPrompt.Show(partner.transform, "Rope up",
Glyph.Action(GameAction.Interact),
onInteract: () => AttachRope(),
radius: 0.5f, localOffset: Vector3.up * 0.2f);
var r2 = ReachPrompt.Create(leverPos, "Pull", Glyph.Key("e"),
onInteract: () => PullLever());
r.Destroy(); Produces InputAction objects for prompt icons. Icons resolve per-device (keyboard vs. gamepad) automatically.
Glyph.Action(action) → InputAction The player's live binding for a named game action. Respects their rebinds.
action | GameAction | The game action to look up. |
Glyph.Key(key) → InputAction A specific keyboard key.
key | string | Key name, e.g. "f" or "space". |
Glyph.Path(path) → InputAction A raw Unity Input System control path.
path | string | Control path, e.g. "<Gamepad>/buttonSouth". |
Glyph.Custom(name, ...paths) → InputAction A multi-binding action usable as both a glyph icon and a polled input trigger.
name | string | Action name (arbitrary). |
paths | string[] | One or more control paths. |
var g = Glyph.Action(GameAction.Interact);
var g2 = Glyph.Key("f");
var g3 = Glyph.Path("<Gamepad>/buttonSouth");
var g4 = Glyph.Custom("MyAction", "<Keyboard>/g", "<Gamepad>/buttonWest");
if (g4.WasPerformedThisFrame()) DoThing();