Steamworks Coverage
GemShell puts 137 Steamworks calls in 23 areas in front of your game as one global steam object. No SDK to link, no native module to compile, no C++ — the calls are ordinary JavaScript that return promises.
This page is generated from the TypeScript definitions that ship with GemShell (gemshell.d.ts), so it lists exactly what exists, not what is planned.
Lifecycle
| Call | What it does |
|---|---|
init(): Promise<boolean> | — |
shutdown(): Promise<void> | — |
isAvailable(): Promise<boolean> | — |
isInitialized(): Promise<boolean> | — |
runCallbacks(): Promise<void> | Run pending Steam callbacks. |
User
| Call | What it does |
|---|---|
getSteamID(): Promise<string> | — |
getPersonaName(): Promise<string> | — |
getAppID(): Promise<number> | — |
getPlayerSteamLevel(): Promise<number> | — |
Achievements
| Call | What it does |
|---|---|
unlockAchievement(id: string): Promise<boolean> | — |
getAchievement(id: string): Promise<boolean> | — |
clearAchievement(id: string): Promise<boolean> | — |
Stats
| Call | What it does |
|---|---|
storeStats(): Promise<boolean> | — |
setStatInt(name: string, value: number): Promise<boolean> | — |
getStatInt(name: string): Promise<number> | — |
setStatFloat(name: string, value: number): Promise<boolean> | — |
getStatFloat(name: string): Promise<number> | — |
requestStats(): Promise<boolean> | — |
requestStatsAndWait(timeoutMs?: number): Promise<boolean> | Request stats and wait until they are loaded (or until timeoutMs elapses). |
areStatsReady(): Promise<boolean> | — |
getStatsState(): Promise<StatsState> | — |
Friends
| Call | What it does |
|---|---|
getFriendCount(): Promise<number> | — |
getFriendByIndex(index: number, flags?: number): Promise<string> | — |
getFriendPersonaName(index: number): Promise<string> | — |
getFriendPersonaState(steamId: string): Promise<number> | — |
getFriendGamePlayed(steamId: string): Promise<FriendGamePlayed | null> | — |
requestUserInformation(steamId: string): Promise<boolean> | — |
getFriends(max?: number): Promise<FriendInfo[]> | Convenience: returns up to max friends with id and name. |
getSmallFriendAvatar(steamId: string): Promise<number> | — |
getMediumFriendAvatar(steamId: string): Promise<number> | — |
getLargeFriendAvatar(steamId: string): Promise<number> | — |
getImageRGBA(handle: number): Promise<{ width: number; height: number; data: number[] } | null> | Returns RGBA pixel data and dimensions for an avatar handle. |
Auth Tickets
| Call | What it does |
|---|---|
getAuthTicketForWebApi(identity?: string | null): Promise<AuthTicketResult> | Request a Steam auth ticket for backend verification. |
cancelAuthTicket(handle: number): Promise<void> | Cancel an active auth ticket. |
Overlay
| Call | What it does |
|---|---|
activateOverlay(dialog: OverlayDialog | string): Promise<boolean> | Open the Steam overlay on a specific dialog. |
activateOverlayToWebPage(url: string): Promise<boolean> | — |
isOverlayEnabled(): Promise<boolean> | — |
Rich Presence
| Call | What it does |
|---|---|
setRichPresence(key: string, value: string): Promise<boolean> | — |
clearRichPresence(): Promise<boolean> | — |
DLC / Apps
| Call | What it does |
|---|---|
isDlcInstalled(appId: number): Promise<boolean> | — |
getDLCCount(): Promise<number> | — |
isSubscribedApp(appId: number): Promise<boolean> | — |
isAppInstalled(appId: number): Promise<boolean> | — |
getAppInstallDir(appId: number): Promise<string> | Installation folder of an app. |
Utils
| Call | What it does |
|---|---|
isSteamDeck(): Promise<boolean> | — |
isSteamInBigPictureMode(): Promise<boolean> | — |
getCurrentGameLanguage(): Promise<string> | — |
getAvailableGameLanguages(): Promise<string> | — |
getServerRealTime(): Promise<number> | — |
getIPCountry(): Promise<string> | — |
getBuildId(): Promise<number> | — |
triggerScreenshot(): Promise<boolean> | — |
Steam Deck keyboard
| Call | What it does |
|---|---|
showFloatingGamepadTextInput(mode: 0 | 1 | 2 | 3, x: number, y: number, width: number, height: number): Promise<boolean> | Opens the floating on-screen keyboard over a text field. |
showGamepadTextInput(inputMode: 0 | 1, lineMode: 0 | 1, description: string, maxChars: number, existingText: string): Promise<boolean> | Opens the Big Picture modal text input dialog. |
getEnteredGamepadTextInput(): Promise<string> | Returns the text submitted via showGamepadTextInput(). |
Steam Cloud (Remote Storage)
| Call | What it does |
|---|---|
fileWrite(fileName: string, data: string): Promise<boolean> | — |
fileRead(fileName: string): Promise<string> | — |
fileExists(fileName: string): Promise<boolean> | — |
fileDelete(fileName: string): Promise<boolean> | — |
fileGetSize(fileName: string): Promise<number> | — |
isCloudEnabledForAccount(): Promise<boolean> | — |
isCloudEnabledForApp(): Promise<boolean> | — |
setCloudEnabledForApp(enabled: boolean): Promise<boolean> | — |
Event polling (low-level)
| Call | What it does |
|---|---|
pollEvents(): Promise<boolean> | Lets Steam hand over whatever it has been holding, and says whether anything is waiting. |
popEvent(): Promise<SteamEvent | null> | The oldest event Steam raised, or null when there is none. |
Leaderboards
| Call | What it does |
|---|---|
findLeaderboard(name: string): Promise<{ handle: string; name: string } | null> | — |
uploadLeaderboardScore( name: string, score: number, method?: LeaderboardUploadMethod ): Promise<boolean> | — |
downloadLeaderboardEntries( name: string, type: LeaderboardDataRequest, start: number, end: number ): Promise<LeaderboardEntry[]> | — |
Lobbies
| Call | What it does |
|---|---|
createLobby(type: LobbyType, maxMembers: number): Promise<string | null> | — |
joinLobby(lobbyId: string): Promise<boolean> | — |
leaveLobby(): Promise<boolean> | — |
getLobbyMembers(): Promise<string[]> | — |
setLobbyData(key: string, value: string): Promise<boolean> | Sets metadata on the joined lobby. |
getLobbyData(lobbyId: string, key: string): Promise<string> | Reads metadata from ANY lobby by ID — no membership required. |
inviteUserToLobby(steamId: string): Promise<boolean> | — |
getLobbyOwner(): Promise<string> | — |
getLobbyMemberLimit(): Promise<number> | — |
setLobbyJoinable(joinable: boolean): Promise<boolean> | — |
setLobbyType(type: LobbyType): Promise<boolean> | Change lobby type at runtime (0=Private, 1=FriendsOnly, 2=Public, 3=Invisible). |
requestLobbyList(distanceFilter?: LobbyDistanceFilter): Promise<string[]> | Searches for public lobbies. |
addRequestLobbyListStringFilter( key: string, value: string, comparison?: LobbyComparison ): Promise<boolean> | — |
addRequestLobbyListNumericalFilter( key: string, value: number, comparison?: LobbyComparison ): Promise<boolean> | — |
addRequestLobbyListDistanceFilter(distance?: LobbyDistanceFilter): Promise<boolean> | — |
addRequestLobbyListFilterSlotsAvailable(slots?: number): Promise<boolean> | — |
addRequestLobbyListResultCountFilter(maxResults?: number): Promise<boolean> | — |
getLobbyByIndex(index: number): Promise<string | null> | — |
P2P
| Call | What it does |
|---|---|
isP2PPacketAvailable(channel: number): Promise<boolean> | — |
readP2PPacket( channel: number, maxSize: number ): Promise<{ data: number[]; steamId: string } | null> | — |
sendP2PPacket( steamId: string, data: number[] | Uint8Array, sendType: P2PSendType, channel: number ): Promise<boolean> | — |
acceptP2PSessionWithUser(steamId: string): Promise<boolean> | — |
closeP2PSessionWithUser(steamId: string): Promise<boolean> | — |
Workshop
| Call | What it does |
|---|---|
getNumSubscribedItems(): Promise<number> | — |
getSubscribedItems(): Promise<string[]> | — |
getItemInstallInfo(fileId: string): Promise<WorkshopItemInstallInfo> | Install info for a Workshop item. |
getItemState(fileId: string): Promise<number> | EItemState bitmap for a Workshop item. |
downloadItem(fileId: string, highPriority?: boolean): Promise<boolean> | Trigger a download (or update) of a Workshop item. |
Steam Input
| Call | What it does |
|---|---|
initInput(explicitlyCallRunFrame?: boolean): Promise<boolean> | — |
shutdownInput(): Promise<boolean> | — |
inputRunFrame(reserved?: boolean): Promise<void> | — |
getConnectedControllers(): Promise<string[]> | — |
getActionSetHandle(name: string): Promise<string> | — |
activateActionSet(controller: string, actionSet: string): Promise<void> | — |
getDigitalActionHandle(name: string): Promise<string> | — |
getAnalogActionHandle(name: string): Promise<string> | — |
getDigitalActionData(controller: string, action: string): Promise<DigitalActionData> | — |
getAnalogActionData(controller: string, action: string): Promise<AnalogActionData> | — |
getInputTypeForHandle(controller: string): Promise<number> | — |
Voice
| Call | What it does |
|---|---|
startVoiceRecording(): Promise<boolean> | Starts recording the player through Steam's own microphone capture. |
stopVoiceRecording(): Promise<boolean> | Stops recording. |
getAvailableVoice(): Promise<VoiceAvailable> | How much compressed voice is waiting. |
getVoice(maxSize?: number): Promise<{ buffer: number[]; written: number } | null> | Reads up to maxSize bytes of compressed voice (8192 by default), or null when there is none. |
decompressVoice( data: number[] | Uint8Array, sampleRate?: number ): Promise<{ buffer: number[]; written: number } | null> | Turns compressed voice back into PCM you can play — 16-bit mono at sampleRate, which defaults to 11025. |
Parental controls
| Call | What it does |
|---|---|
isParentalLockEnabled(): Promise<boolean> | Whether Family View is switched on for this account. |
isAppBlocked(appId: number): Promise<boolean> | Whether Family View keeps this account out of that app. |
isFeatureBlocked(feature: number): Promise<boolean> | Whether Family View blocks one of Steam's own features. |
Timeline (Steam Recording)
| Call | What it does |
|---|---|
setTimelineStateDescription(description: string, delta?: number): Promise<boolean> | Says what the player is doing right now; Steam writes it along the recording timeline, where it shows in Game Recording and clips. |
clearTimelineStateDescription(delta?: number): Promise<boolean> | Takes the description back off the timeline. |
addTimelineEvent( icon: string, title: string, description?: string, priority?: number, startOffset?: number, duration?: number, clipPriority?: number ): Promise<boolean> | Marks a moment on the recording timeline — a boss down, a lap, a death. |
setTimelineTooltip(description: string, delta?: number): Promise<boolean> | The same as setTimelineStateDescription(), under Steam's current name. |
clearTimelineTooltip(delta?: number): Promise<boolean> | Takes the description back off the timeline. |
Music
| Call | What it does |
|---|---|
isMusicEnabled(): Promise<boolean> | Whether Steam Music is there to be controlled at all. |
isMusicPlaying(): Promise<boolean> | Whether Steam Music is playing something right now. |
getMusicPlaybackStatus(): Promise<number> | 0 undefined, 1 playing, 2 paused, 3 idle. |
playMusic(): Promise<boolean> | Plays the player's own Steam Music, as the Steam overlay's controls do. |
pauseMusic(): Promise<boolean> | Pauses the player's own Steam Music. |
playPrevious(): Promise<boolean> | Back a track in the player's own Steam Music. |
playNext(): Promise<boolean> | On a track in the player's own Steam Music. |
setMusicVolume(volume: number): Promise<boolean> | Sets the Steam Music volume, 0 to 1. |
getMusicVolume(): Promise<number> | The Steam Music volume, 0 to 1. |
Inventory
| Call | What it does |
|---|---|
loadItemDefinitions(): Promise<boolean> | Asks Steam for this app's item definitions. |
getAllItems(): Promise<number> | Starts reading everything the player owns, and answers a result handle (-1 when Steam cannot be asked). |
addPromoItem(itemDef: number): Promise<number> | Grants the player a promo item, if they are eligible and do not have it. |
getResultStatus(handle: number): Promise<number> | Steam's EResult for a handle: 1 done, 22 still pending, 8 nothing matched, 6 Steam could not be asked. |
destroyResult(handle: number): Promise<boolean> | Lets Steam forget a result handle. |
triggerItemDrop(listDef: number): Promise<number> | Runs a playtime item drop for that item list, if one is due. |
overlay.isAvailable(): Promise<boolean> | Whether the GemShell overlay was successfully injected. |
overlay.isActive(): Promise<boolean> | Whether the overlay is currently being shown. |
Using it
javascript
if (typeof steam !== 'undefined' && await steam.isAvailable()) {
await steam.unlockAchievement('FIRST_BLOOD')
await steam.setStatInt('kills', kills)
await steam.fileWrite('save.json', JSON.stringify(save))
}Enable Steamworks in your project and set your App ID — see the Steamworks guide. Without Steam running, every call answers a harmless default, so a game can call them unguarded.