> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overlayed.gg/llms.txt
> Use this file to discover all available pages before exploring further.

> All of the game events emitted by Sand Raiders of Sophie.

# Sand Raiders of Sophie

<Info>`overlayed.sand.readyForGameEvents()` must be called before any events will be emitted.</Info>

Each event is marked with its retention — see [Retained vs transient](/games/introduction#retained-vs-transient).

### logged\_in

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge>

`account_id` and `player_joined.player_id` are different ids and never match. Use `platform_id` to
tie the logged-in account to an in-match player.

<CodeGroup>
  ```ts type.ts theme={null}
  interface LoggedInEvent {
  	account_id: string;
  	display_name: string;
  	platform_id: string;
  	playfab_id: string;
  }
  ```

  ```json example.json theme={null}
  {
  	"account_id": "1717066",
  	"display_name": "GhettoAmmo",
  	"platform_id": "76561198996870832",
  	"playfab_id": "A77C293DA30BEDDE"
  }
  ```
</CodeGroup>

### game\_state\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge>

The expedition status. `menu` means no expedition is active.

<CodeGroup>
  ```ts type.ts theme={null}
  interface GameStateChangedEvent {
  	state:
  		| "menu"
  		| "waiting_for_players"
  		| "matchmaking"
  		| "match_found"
  		| "in_progress"
  		| "loot_division"
  		| "extracted"
  		| "all_left"
  		| "aborted"
  		| "failed"
  		| "decayed"
  		| "invalid";
  }
  ```

  ```json example.json theme={null}
  {
  	"state": "in_progress"
  }
  ```
</CodeGroup>

### party\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface PartyChangedEvent {
  	join_code: string;
  }
  ```

  ```json example.json theme={null}
  {
  	"join_code": "K7QP2M"
  }
  ```
</CodeGroup>

### party\_member\_joined

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge> <Badge color="gray" size="sm" shape="pill">Key: account\_id</Badge>

One per party member, including the local player. `display_name` can arrive empty; a later event for
the same `account_id` fills it in.

<CodeGroup>
  ```ts type.ts theme={null}
  interface PartyMemberJoinedEvent {
  	account_id: string;
  	display_name: string;
  	platform_id: string;
  	playfab_id: string;
  	character_id: number;
  	is_captain: boolean;
  }
  ```

  ```json example.json theme={null}
  {
  	"account_id": "1717066",
  	"display_name": "GhettoAmmo",
  	"platform_id": "76561198996870832",
  	"playfab_id": "A77C293DA30BEDDE",
  	"character_id": 88421,
  	"is_captain": true
  }
  ```
</CodeGroup>

### party\_member\_left

<Badge color="orange" size="sm" shape="pill">Transient</Badge> <Badge color="gray" size="sm" shape="pill">Releases: party\_member\_joined</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface PartyMemberLeftEvent {
  	account_id: string;
  }
  ```

  ```json example.json theme={null}
  {
  	"account_id": "1717066"
  }
  ```
</CodeGroup>

### storage\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge>

A full storage snapshot. `crowns`, `mechanical_parts`, `pneumatic_parts`, and `computing_modules`
are totals for items that also appear in `items` — adding them to the `items` total double-counts.

<CodeGroup>
  ```ts type.ts theme={null}
  interface StorageChangedEvent {
  	slots_used: number;
  	slots_total: number;
  	crowns: number;
  	mechanical_parts: number;
  	pneumatic_parts: number;
  	computing_modules: number;
  	items: Array<{
  		definition: string;
  		amount: number;
  	}>;
  }
  ```

  ```json example.json theme={null}
  {
  	"slots_used": 12,
  	"slots_total": 40,
  	"crowns": 2500,
  	"mechanical_parts": 8,
  	"pneumatic_parts": 3,
  	"computing_modules": 1,
  	"items": [
  		{
  			"definition": "item_coinCrown",
  			"amount": 2500
  		},
  		{
  			"definition": "item_resourceMetal_t1",
  			"amount": 8
  		}
  	]
  }
  ```
</CodeGroup>

### storage\_item\_changed

<Badge color="orange" size="sm" shape="pill">Transient</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface StorageItemChangedEvent {
  	definition: string;
  	amount: number;
  	delta: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"definition": "item_coinCrown",
  	"amount": 2500,
  	"delta": 500
  }
  ```
</CodeGroup>

### tech\_tree\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge>

`is_available` means researchable right now, so an already-unlocked node reports it `false`.

<CodeGroup>
  ```ts type.ts theme={null}
  interface TechTreeChangedEvent {
  	unlocked: number;
  	total: number;
  	nodes: Array<{
  		id: string;
  		name: string;
  		tier: number;
  		is_unlocked: boolean;
  		is_available: boolean;
  	}>;
  }
  ```

  ```json example.json theme={null}
  {
  	"unlocked": 2,
  	"total": 3,
  	"nodes": [
  		{
  			"id": "8f14e45f-ceea-467a-9575-0d1e1b0b2c33",
  			"name": "Cannon T4",
  			"tier": 3,
  			"is_unlocked": true,
  			"is_available": false
  		},
  		{
  			"id": "c4ca4238-a0b9-2382-0dcc-509a6f75849b",
  			"name": "Hull T2",
  			"tier": 1,
  			"is_unlocked": false,
  			"is_available": true
  		}
  	]
  }
  ```
</CodeGroup>

### tech\_tree\_item\_unlocked

<Badge color="orange" size="sm" shape="pill">Transient</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface TechTreeItemUnlockedEvent {
  	id: string;
  	name: string;
  	tier: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"id": "8f14e45f-ceea-467a-9575-0d1e1b0b2c33",
  	"name": "Cannon T4",
  	"tier": 3
  }
  ```
</CodeGroup>

### walker\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="blue" size="sm" shape="pill">Menu</Badge>

The walker the account has built. `walker_id` matches `trampler_acquired.master_server_id`.

<CodeGroup>
  ```ts type.ts theme={null}
  interface WalkerChangedEvent {
  	walker_id: number;
  	blueprint_unique_id: string;
  	blueprint_file: string;
  	first_name_index: number;
  	second_name_index: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"walker_id": 4471,
  	"blueprint_unique_id": "b1d9e0f2-3c44-4a8e-9f21-77c0a5d6e881",
  	"blueprint_file": "Dune Runner",
  	"first_name_index": 12,
  	"second_name_index": 3
  }
  ```
</CodeGroup>

### match\_started

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge>

`server_start_time` is when the match began, not when you joined it.

<CodeGroup>
  ```ts type.ts theme={null}
  interface MatchStartedEvent {
  	match_id: number;
  	game_mode: "storm_dive" | "voyage" | "invalid";
  	seed: number;
  	server_start_time: number;
  	world_bounds: {
  		min_x: number;
  		min_z: number;
  		max_x: number;
  		max_z: number;
  	};
  	landmarks: Array<{
  		id: string;
  		name: string;
  		position: {
  			x: number;
  			y: number;
  			z: number;
  		};
  	}>;
  }
  ```

  ```json example.json theme={null}
  {
  	"match_id": 9001,
  	"game_mode": "storm_dive",
  	"seed": 12345,
  	"server_start_time": 1700000000000,
  	"world_bounds": {
  		"min_x": -4096,
  		"min_z": -4096,
  		"max_x": 4096,
  		"max_z": 4096
  	},
  	"landmarks": [
  		{
  			"id": "fort_alpha",
  			"name": "Fort Alpha",
  			"position": {
  				"x": 1024.5,
  				"y": 62,
  				"z": -337.25
  			}
  		}
  	]
  }
  ```
</CodeGroup>

### match\_ended

<Badge color="orange" size="sm" shape="pill">Transient</Badge> <Badge color="gray" size="sm" shape="pill">Releases: all match-level events</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface MatchEndedEvent {
  }
  ```

  ```json example.json theme={null}
  {}
  ```
</CodeGroup>

### world\_time\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface WorldTimeChangedEvent {
  	hour: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"hour": 13
  }
  ```
</CodeGroup>

### player\_joined

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge> <Badge color="gray" size="sm" shape="pill">Key: platform\_id</Badge>

One per player on the player list, which keeps players after they disconnect — there is no leave
event. `player_id` never equals `logged_in.account_id`; correlate on `platform_id`.

<CodeGroup>
  ```ts type.ts theme={null}
  interface PlayerJoinedEvent {
  	player_id: number;
  	username: string;
  	platform_id: string;
  	playfab_id: string;
  }
  ```

  ```json example.json theme={null}
  {
  	"player_id": 1717066,
  	"username": "GhettoAmmo",
  	"platform_id": "76561198996870832",
  	"playfab_id": "A77C293DA30BEDDE"
  }
  ```
</CodeGroup>

### extraction\_added

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge> <Badge color="gray" size="sm" shape="pill">Key: extraction\_id</Badge>

Extractions can arrive throughout the match, not all at `match_started`.

<CodeGroup>
  ```ts type.ts theme={null}
  interface ExtractionAddedEvent {
  	extraction_id: number;
  	radius: number;
  	position: {
  		x: number;
  		y: number;
  		z: number;
  	};
  }
  ```

  ```json example.json theme={null}
  {
  	"extraction_id": 3,
  	"radius": 25.5,
  	"position": {
  		"x": 1024.5,
  		"y": 62,
  		"z": -337.25
  	}
  }
  ```
</CodeGroup>

### extraction\_removed

<Badge color="orange" size="sm" shape="pill">Transient</Badge> <Badge color="gray" size="sm" shape="pill">Releases: extraction\_added</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface ExtractionRemovedEvent {
  	extraction_id: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"extraction_id": 3
  }
  ```
</CodeGroup>

### storm\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge>

Emitted on stage and state transitions only.

<CodeGroup>
  ```ts type.ts theme={null}
  interface StormChangedEvent {
  	stage: number;
  	total_stages: number;
  	state: "idle" | "delay" | "moving" | "invalid";
  	end_time: number;
  	radius: number;
  	center: {
  		x: number;
  		y: number;
  		z: number;
  	};
  	next_radius: number;
  	next_center: {
  		x: number;
  		y: number;
  		z: number;
  	};
  }
  ```

  ```json example.json theme={null}
  {
  	"stage": 1,
  	"total_stages": 6,
  	"state": "moving",
  	"end_time": 1700000060000,
  	"radius": 500,
  	"center": {
  		"x": 0,
  		"y": 62,
  		"z": 0
  	},
  	"next_radius": 250,
  	"next_center": {
  		"x": 128.5,
  		"y": 62,
  		"z": -64.25
  	}
  }
  ```
</CodeGroup>

### inventory\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge> <Badge color="gray" size="sm" shape="pill">Key: player\_id</Badge>

What a player is carrying right now, one event per party member. Only the local player and their
party are reported. `player_id` matches `player_joined.player_id`, not `logged_in.account_id`, which
is the master server's id and a string.

Slots 0-15 are the fixed ones — 0 is the hand, 1 and 2 are weapons, 3 is armor, 4 is the backpack,
5-9 are tools and 10-15 are the belt. Anything higher is a grid slot. Empty slots are omitted, so
`slots_used` is the length of `slots`.

`amount` is the stack size for a stack but the loaded rounds for a weapon, and `0` for a container
the player is holding. What a carried container holds is not reported.

<CodeGroup>
  ```ts type.ts theme={null}
  interface InventoryChangedEvent {
  	player_id: number;
  	slots_used: number;
  	slots: Array<{
  		slot: number;
  		definition: string;
  		amount: number;
  	}>;
  }
  ```

  ```json example.json theme={null}
  {
  	"player_id": 1717066,
  	"slots_used": 3,
  	"slots": [
  		{
  			"slot": 1,
  			"definition": "item_semiAutomaticPistol_decreasedMag",
  			"amount": 5
  		},
  		{
  			"slot": 5,
  			"definition": "item_pistolAmmo",
  			"amount": 45
  		},
  		{
  			"slot": 6,
  			"definition": "item_energyBar",
  			"amount": 3
  		}
  	]
  }
  ```
</CodeGroup>

### inventory\_slot\_changed

<Badge color="orange" size="sm" shape="pill">Transient</Badge>

One slot of one party member changed. A slot that swapped what it holds reports the new stack
arriving rather than the old one growing, so `delta` equals `amount` in that case. An emptied slot
reports an empty `definition`, an `amount` of `0`, and the negative of what it held.

<CodeGroup>
  ```ts type.ts theme={null}
  interface InventorySlotChangedEvent {
  	player_id: number;
  	slot: number;
  	definition: string;
  	amount: number;
  	delta: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"player_id": 1717066,
  	"slot": 5,
  	"definition": "item_pistolAmmo",
  	"amount": 45,
  	"delta": 15
  }
  ```
</CodeGroup>

### inventory\_equipped\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge> <Badge color="gray" size="sm" shape="pill">Key: player\_id</Badge>

What a party member has in their hands. `slot` is the selected slot and `definition` is what sits
in it, which is empty when the slot is. A `slot` of `255` means the game has not reported a
selection yet.

<CodeGroup>
  ```ts type.ts theme={null}
  interface InventoryEquippedChangedEvent {
  	player_id: number;
  	slot: number;
  	definition: string;
  }
  ```

  ```json example.json theme={null}
  {
  	"player_id": 1717066,
  	"slot": 1,
  	"definition": "item_semiAutomaticPistol_decreasedMag"
  }
  ```
</CodeGroup>

### trampler\_acquired

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge> <Badge color="gray" size="sm" shape="pill">Key: trampler\_id</Badge>

`master_server_id` matches `walker_changed.walker_id` when non-zero. `creator_player_id` is the
blueprint's author, not the driver, and matches `player_joined.player_id`.

<CodeGroup>
  ```ts type.ts theme={null}
  interface TramplerAcquiredEvent {
  	trampler_id: number;
  	master_server_id: number;
  	blueprint: string;
  	creator_player_id: number;
  	first_name_index: number;
  	second_name_index: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"trampler_id": 12,
  	"master_server_id": 4471,
  	"blueprint": "EXPEDITION_WALKER",
  	"creator_player_id": 1717066,
  	"first_name_index": 12,
  	"second_name_index": 3
  }
  ```
</CodeGroup>

### trampler\_changed

<Badge color="green" size="sm" shape="pill">Retained</Badge> <Badge color="purple" size="sm" shape="pill">Match</Badge> <Badge color="gray" size="sm" shape="pill">Key: trampler\_id</Badge>

Emitted about every 10 seconds whether or not the trampler moved — a new event is not proof of
motion.

<CodeGroup>
  ```ts type.ts theme={null}
  interface TramplerChangedEvent {
  	trampler_id: number;
  	position: {
  		x: number;
  		y: number;
  		z: number;
  	};
  	yaw: number;
  	speed: number;
  	velocity: {
  		x: number;
  		y: number;
  		z: number;
  	};
  }
  ```

  ```json example.json theme={null}
  {
  	"trampler_id": 12,
  	"position": {
  		"x": 1024.5,
  		"y": 62,
  		"z": -337.25
  	},
  	"yaw": 137.5,
  	"speed": 8.25,
  	"velocity": {
  		"x": 8.25,
  		"y": 0,
  		"z": 0
  	}
  }
  ```
</CodeGroup>

### trampler\_lost

<Badge color="orange" size="sm" shape="pill">Transient</Badge> <Badge color="gray" size="sm" shape="pill">Releases: trampler\_acquired, trampler\_changed</Badge>

<CodeGroup>
  ```ts type.ts theme={null}
  interface TramplerLostEvent {
  	trampler_id: number;
  }
  ```

  ```json example.json theme={null}
  {
  	"trampler_id": 12
  }
  ```
</CodeGroup>
