velven
Docs
Menu

Achievements and stats

An achievement is a goal a player unlocks once, worth 10 points on their Velven profile when your space is listed and has a creator. A stat is a named counter per player, and an achievement with a trigger unlocks by itself when its stat gets there. You declare both; Velven keeps them, draws a toast for each unlock and lists them on your space's Velven page.

View guide as Markdown

Declare achievements and stats

Declare them in the page's block, beside the boards. An unlock of a key you never declared answers no_achievement, and a stat you never declared answers no_stat.

index.html
<script type="application/velven+json">{"boards":[{"key":"main","trust":"client"}], "stats":[{"key":"kills","label":"Kills"}], "achievements":[   {"key":"first-blood","title":"First Blood","description":"Win a round"},   {"key":"centurion","title":"Centurion","description":"100 kills","trigger":{"stat":"kills","atLeast":100}},   {"key":"hidden-door","title":"Found it","secret":true,"icon":"icons/door.png"} ]}</script>

Velven reads the block when the space is listed and on its background check every 6 hours; “Check my page now” on the edit page's Leaderboards tab reads it at once. There are 2 other places to declare them:

  • A space hosted on Velven declares them in velven.json, with the same stats and achievements keys: a version that names them syncs them when it goes live; a preview uses the live space's. Hosting has the file.
  • Without a deploy, send { "stats": [...], "achievements": [...] } with PUT /api/spaces/<slug>/achievements and your API token. Only what you name is written, and the page's next sync overwrites a key it also names. GET on the same address answers what Velven holds.

Note: Remove an achievement or a stat from the block and it is withdrawn: hidden, with the players' unlocks and values kept. Name it again and it comes back.

Fields

An achievement takes these fields; only key and title are required:

key1 to 32 lowercase letters, digits, - or _
The id your calls use. Unique among the space's achievements.
title1 to 60 characters
The name the toast, the space's page and the player's profile show.
descriptionUp to 200 charactersDefault empty
What earns it.
secrettrue or falseDefault false
Hidden, title and all, until the player earns it. list answers it with a null title and description until then.
iconUp to 500 characters
An https address, or a path read against your page's address: a file next to a linked page, or a file in a hosted upload. Anything else shows no icon.
trigger{ "stat": key, "atLeast": number }
Unlocks the achievement when the named stat reaches atLeast. The stat must be declared in the same place.

A stat takes key (the same rule) and an optional label of up to 40 characters, for you to draw. Up to 50 achievements and 50 stats per space, withdrawn ones aside; declaring more answers too_many.

Unlock and count

Unlock when the player earns it, and write stats as they change. Each call needs a signed-in player.

JavaScript
const got = await Velven.achievements.unlock("first-blood");// { ok: true, achievement: "first-blood", title, unlocked, points: 10, total }, points 0 where it counts noneconst kills = await Velven.stats.add("kills", 1);   // or stats.set("kills", 42)// { ok: true, stat: "kills", value: 43, unlocked: [ ... ] }, the triggers this value reachedconst now = await Velven.stats.get("kills");        // { ok: true, stat: "kills", value: 43 }, 0 before a first writeconst all = await Velven.achievements.list();// { ok: true, achievements: [{ key, title, description, icon, secret, trigger, points, unlocked, unlockedAt, holders, players, share }] }
  • An unlock is idempotent: unlocked is false when the player already held it, so call it whenever the goal is met. total is the player's points across Velven.
  • Points count on a listed space with a creator: its creator's own unlocks count none, and an achievement you stop declaring stops counting. Where an unlock counts none (your own, a page published without an account, the sandbox), it answers points: 0 and Velven's toast shows no points.
  • stats.add takes a negative number to take away. A value that is not a finite number, or a key that is not one, throws a TypeError before anything is sent.
  • list answers every achievement in the order you declared them, with the player's own unlocks. share is the part of the space's players who hold it, from 0 to 1: holders out of players, where a player is anyone with an achievement or a stat in the space.

onAchievement hears every unlock the player earns, from unlock or from a stat reaching a trigger:

JavaScript
const stop = Velven.onAchievement((a) => console.log(`${a.title} +${a.points}`)); // { key, title, description, icon, points }

The page and your server (with the space's secret) unlock the same achievements. An unlock from your server is marked trusted, and a page unlock your server repeats becomes trusted, so for a goal your server referees, such as beating a boss, unlock it there.

The unlock toast

Velven draws a toast over the corner of the frame for each unlock, such as “Achievement unlocked: First Blood, +10”, so you need draw nothing. If your space draws its own from onAchievement, turn Velven's off in one of 3 ways:

<script src="https://velven.ai/sdk/v1.js" data-toasts="false"></script>

velven.json is for a space hosted on Velven, where Velven adds the script tag for you.

On your space's Velven page

The space's Velven page has an Achievements section: every achievement with its icon, the share of players who hold it and, for a signed-in player, which ones they have. A secret achievement shows as hidden until the player earns it. An unlock that counts adds 10 points to the player's profile, where the total and their recent unlocks show; the section shows points only where they count.

Error codes

Code
signed_out
Meaning
No player is signed in. Offer signIn() from a button.
Code
no_achievement, no_stat
Meaning
The space declares no such key, or it was withdrawn.
Code
invalid_value
Meaning
The stat's value is not a finite number: an answer to your server, since the page's call throws first.
Code
unavailable
Meaning
Not inside Velven, on a space not published with a verified owner, or on a Velven page too old to know achievements.
Code
banned, rate_limited, failed
Meaning
As for scores.

On localhost achievements and stats come from your block and live in memory: an unlock reaches onAchievement, and a stat reaching a trigger unlocks it. Local testing has the rest.