-
Notifications
You must be signed in to change notification settings - Fork 0
Inventory
Since v0.6.0. steam.items is the curated layer over ISteamInventory: read
and change the player's Steam Inventory Service items, the item definition
catalogue, and store prices.
Nearly every raw ISteamInventory call writes a SteamInventoryResult_t handle,
finishes later with a SteamInventoryResultReady_t callback, and has to be
destroyed or it leaks. Every method here runs that whole cycle: start the call,
wait for the result, decode the items, destroy the handle. A non-OK EResult
becomes a SteamResultError. See Errors.
Item definitions are the catalogue you configure on the partner site, a
separate thing from items: they arrive with
loadDefinitions, and everything reading them is synchronous
afterwards. The instance is cached lazily on the Steam object, and is called
items because the generated accessor owns steam.inventory, where the
unwrapped calls live.
getAll(): Promise<InventoryItem[]>Every item stack the player owns for this app. Empty for a player who owns nothing.
getByIds(itemIds: bigint[]): Promise<InventoryItem[]>The named stacks only, cheaper than getAll when you know the ids. Ids the
player does not own are left out; an empty input skips the native call.
loadDefinitions(): Promise<void>Downloads the item definition catalogue and resolves once Steam has it. Call it once at startup: listDefinitions, definitionProperty and definitionProperties read the cache it fills, and return nothing before it is filled.
listDefinitions(): number[]The definition ids in the loaded catalogue, or an empty array while the catalogue is not loaded.
definitionProperty(definition: number, name: string): string | nullOne property of one definition, or null when the definition or the property
does not exist. Every property is a string whatever its type on the partner
site: a boolean is "true", a number its digits. An empty name returns the
definition's comma-separated list of property names.
definitionProperties(definition: number): Record<string, string>Every property of one definition, as one object: one flat call for the key
list, then one per key. Empty when the definition does not exist or the
catalogue is not loaded. Null prototype, so a __proto__ key stays an entry.
consume(itemId: bigint, quantity?: number): Promise<InventoryItem[]>Consumes some of one stack, permanently: the "use the potion" call. quantity
defaults to 1. Resolves with the stack afterwards, empty once the last is gone.
exchange(generate: { definition: number; quantity: number }[], destroy: { itemId: bigint; quantity: number }[]): Promise<InventoryItem[]>Crafts items out of other items in one step. Steam checks it against the recipes on the partner site and refuses anything else, so this cannot mint items on its own.
transfer(sourceItemId: bigint, quantity: number, destinationItemId?: bigint): Promise<InventoryItem[]>Moves quantity between two stacks. With no destination (the default,
k_SteamItemInstanceIDInvalid) it moves into a brand new stack, which is how
you split one. With a destination the two stacks merge, which only works when
both are of the same definition.
generate(items: { definition: number; quantity: number }[]): Promise<InventoryItem[]>Creates items out of nothing, to seed a test inventory. Developer accounts
only: it fails with k_EResultAccessDenied in a shipped build.
grantPromoItems(): Promise<InventoryItem[]>Grants every promo item this player is eligible for, by the promo rules on the partner site. Granting one they already have is a no-op, so calling this at startup is safe. Empty when there was nothing to grant.
addPromoItems(definitions: number[]): Promise<InventoryItem[]>The narrow form of grantPromoItems: grants only the named definitions, and only if the player is eligible for them.
triggerDrop(dropListDefinition: number): Promise<InventoryItem[]>Asks Steam whether a timed drop is due, and takes it if it is. Steam decides, so most calls come back with no items and that is not an error. Do not poll it; call it at the end of a match.
sendDropHeartbeat(): voidTells Steam the player is still playing, for playtime-based drops. Send it about once a minute. Steam gives no result, so it cannot fail.
requestPrices(): Promise<string>Downloads the current prices and resolves with their three-letter currency
code, for example EUR. listPrices and price read the
cache it fills, so call this first. Only definitions on sale have a price.
listPrices(): ItemPrice[]Every definition that has a price, empty before requestPrices resolved.
Prices are in the smallest currency unit, so 199 means 1.99 with cents.
price(definition: number): { currentPrice: bigint; basePrice: bigint } | nullThe price of one definition, or null when it is not for sale.
startPurchase(items: { definition: number; quantity: number }[]): Promise<{ orderId: bigint; transactionId: bigint }>Starts a purchase and resolves once Steam accepted the order. The checkout appears in the overlay, so the overlay has to be enabled. Resolving means the order exists, not that the player paid: the items arrive later, which onChange hears about.
onChange(listener: (items: InventoryItem[]) => void): () => voidSubscribes to Steam's own SteamInventoryFullUpdate_t, which fires whenever
the inventory changed outside this process: a purchase, a trade, a market sale.
The listener gets the full item list, already decoded, and the result handle is
destroyed afterwards. Returns an unsubscribe function.
One item stack, decoded from SteamItemDetails_t.
| Field | Type | Meaning |
|---|---|---|
itemId |
bigint |
SteamItemInstanceID_t, unique per stack. 64-bit, so a bigint. |
definition |
number |
SteamItemDef_t: which item definition this stack is of. |
quantity |
number |
How many of the item the stack holds. |
flags |
number |
ESteamItemFlags bits: 1 no trade, 256 removed, 512 consumed. |
One entry from listPrices.
| Field | Type | Meaning |
|---|---|---|
definition |
number |
SteamItemDef_t the price belongs to. |
currentPrice |
bigint |
Price the user pays now, in the smallest currency unit. |
basePrice |
bigint |
Price before any discount, in the smallest currency unit. |
| Shape | When |
|---|---|
SteamResultError |
The result completed with a non-OK EResult. Common values: k_EResultAccessDenied (generate on a non-developer account), k_EResultInvalidParam (an item the player does not own, or a definition that is not for sale), k_EResultInvalidState (no Inventory Service configured). |
Error: steamwand: <call> returned false (invalid handle or argument?) |
The flat call refused to start, which usually means the app has no Inventory Service. Also GetResultItems on a handle Steam already dropped. |
SteamApiCallError |
requestPrices or startPurchase never produced a usable result. See How It Works. |
The rest of ISteamInventory is on the raw generated steam.inventory:
-
TradeItems, the peer to peer trade, andInspectItem, which reads an item from an inspection token. -
SerializeResultandDeserializeResult, which move a result across the wire so a game server can verify what a client claims to own. -
StartUpdateProperties, theSetProperty*family,RemovePropertyandSubmitUpdateProperties, which write per-item dynamic properties. -
RequestEligiblePromoItemDefinitionsIDsandGetEligiblePromoItemDefinitionIDs, which ask what a user could be granted. -
GetResultStatus,GetResultTimestamp,CheckResultSteamIDandGetResultItemProperty, plusDestroyResult, handled for you here.
Those take raw Buffer out params and return flat booleans or call handles.
Flat API explains the calling convention.