Appearance
Steam Workshop
Workshop integration in GemShell is fully automatic for the common case: subscribe -> download -> mount -> available as gemshell://.... The methods on this page are for cases where you want fine-grained control or UI feedback.
How auto-mount actually works
await gemshell.steam.init()succeeds- GemShell calls
GetSubscribedItems - For every item that is already installed -> mount immediately
- For every item that is subscribed but not installed yet -> trigger a background download via
DownloadItem - A background poll (1 Hz) drains Steam's
DownloadItemResult_tandItemInstalled_tcallbacks, mounts each newly finished item, and firesassets.onWorkshopChanged - Same flow when the user subscribes to a new item while playing - no restart, no manual call required
This means a typical game does not need to touch this page at all. Just call steam.init() and use gemshell:// URLs as normal.
When you actually need this API
- Show a "Downloading X mods..." UI while pending items are still on the way
- Build an in-game mod manager listing subscribed items, their state, and their disk size
- Force-update a single item
Methods
getNumSubscribedItems()
Number of Workshop items the current user is subscribed to for this app.
javascript
const count = await steam.getNumSubscribedItems();
console.log(`Subscribed to ${count} mods`);getSubscribedItems()
List of subscribed Workshop file IDs (as strings - IDs are 64-bit).
javascript
const ids = await steam.getSubscribedItems();
// ['2891234567', '2999887766', ...]getItemState(fileId)
Returns the EItemState bitmap from Steam. Use bitwise AND with the constants below to inspect.
| Bit | Constant | Meaning |
|---|---|---|
| 1 | Subscribed | user is subscribed |
| 4 | Installed | downloaded and ready on disk |
| 8 | NeedsUpdate | installed, creator pushed an update |
| 16 | Downloading | currently downloading |
| 32 | DownloadPending | download queued, not started yet |
javascript
const state = await steam.getItemState(id);
const installed = (state & 4) !== 0;
const downloading = (state & 16) !== 0;getItemInstallInfo(fileId)
Resolve where a Workshop item is installed on disk and how big it is. Returns an object with installed: false (and zero/empty fields) when the item has not been downloaded yet.
typescript
interface WorkshopItemInstallInfo {
installed: boolean; // true if downloaded and ready
folder: string; // absolute path, "" if not installed
sizeOnDisk: number; // bytes, 0 if not installed
timestamp: number; // unix seconds of last update, 0 if not installed
}javascript
const info = await steam.getItemInstallInfo(id);
if (info.installed) {
console.log(`${info.folder} (${info.sizeOnDisk} bytes)`);
}downloadItem(fileId, highPriority?)
Trigger a download or update for a single item. Resolves true if Steam accepted the request; the actual completion is asynchronous and will arrive via assets.onWorkshopChanged.
You typically do not need this - GemShell already triggers downloads for all subscribed-but-not-installed items right after steam.init(). Use it for explicit "force update" buttons in a mod manager.
javascript
await steam.downloadItem(id); // normal priority
await steam.downloadItem(id, true); // high priorityHigh priority pitfall
Passing highPriority: true for many items at once can stall Steam's download pipeline. Use it only for a single user-initiated download.
Common patterns
Show a download progress indicator
javascript
const ids = await steam.getSubscribedItems();
const pending = [];
for (const id of ids) {
const s = await steam.getItemState(id);
if (!(s & 4)) pending.push(id); // not installed yet
}
if (pending.length) showToast(`Downloading ${pending.length} mods...`);
gemshell.assets.onWorkshopChanged((items) => {
showToast(`${items.length} mods ready`);
});List all installed mods on the title screen
javascript
const ids = await steam.getSubscribedItems();
const installed = [];
for (const id of ids) {
const info = await steam.getItemInstallInfo(id);
if (info.installed) installed.push({ id, ...info });
}
titleScreen.showSubtitle(`${installed.length} workshop mods active`);Force-update one item
javascript
async function forceUpdate(id) {
await steam.downloadItem(id, true);
// wait for Steam to finish; assets.onWorkshopChanged fires when it is.
}See also
- Assets API - the lookup order and the
mods/folder for development overrides. - Steamworks Overview - the rest of the Steam API.
