Steam Timeline
Steam Game Recording keeps a timeline beside the recording, and a game can write on it: what the player is doing now, and moments worth finding again. Players see it while scrubbing a recording, and Steam uses it to suggest clips.
None of it is required and none of it costs anything when the player is not recording.
Methods
setTimelineTooltip(description, delta?)
Says what the player is doing right now. delta shifts it in seconds against now — negative for a moment already past.
javascript
await steam.setTimelineTooltip('Fighting the Warden');setTimelineStateDescription() is the same call under the name Steam gave it first. Either will do.
clearTimelineTooltip(delta?)
Takes the description back off.
clearTimelineStateDescription() is the same call.
addTimelineEvent(icon, title, description?, priority?, startOffset?, duration?, clipPriority?)
Marks a moment.
icon— one of Steam's built-in icon names (steam_attack,steam_death,steam_achievement,steam_challenge,steam_bookmarkand the rest), or one your app ships.title— the short label on the timeline.priority—0–255; what survives when the timeline gets crowded.startOffset— seconds back from now, for something that already happened.duration— give this to mark a stretch of time rather than a moment.clipPriority—0none,1standard,2featured: how much Steam should consider clipping it on its own.
javascript
await steam.addTimelineEvent('steam_attack', 'Warden down', 'No deaths', 80, 0, 0, 2);Examples
Following the game's state
javascript
async function enterArea(area) {
await steam.setTimelineTooltip(`Exploring ${area.name}`);
}
async function enterBossFight(boss) {
await steam.setTimelineTooltip(`Fighting ${boss.name}`);
}
async function returnToMenu() {
await steam.clearTimelineTooltip();
}Marking what a player would want to find again
javascript
async function onBossDefeated(boss, secondsFought, deaths) {
await steam.addTimelineEvent(
'steam_attack',
`${boss.name} defeated`,
deaths === 0 ? 'No deaths' : `${deaths} deaths`,
deaths === 0 ? 100 : 60, // a clean kill matters more
secondsFought, // the fight started this long ago
secondsFought, // and lasted that long
deaths === 0 ? 2 : 1 // worth a clip if it was clean
);
}
async function onPlayerDeath(cause) {
await steam.addTimelineEvent('steam_death', 'Died', cause, 30);
}A personal best
javascript
async function onLapFinished(time, isBest) {
if (!isBest) return;
await steam.addTimelineEvent(
'steam_challenge',
'Personal best',
formatTime(time),
120, 0, 0, 2
);
}Notes
- Keep descriptions short. They are read at a glance while scrubbing.
- Spend high
priorityandclipPrioritysparingly, or everything is important and nothing is. - Without Steam running these answer
falseand do nothing.