Arcademia.Achievements.Cpp 1.1.0

dotnet add package Arcademia.Achievements.Cpp --version 1.1.0
                    
NuGet\Install-Package Arcademia.Achievements.Cpp -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Arcademia.Achievements.Cpp" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Arcademia.Achievements.Cpp" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Arcademia.Achievements.Cpp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Arcademia.Achievements.Cpp --version 1.1.0
                    
#r "nuget: Arcademia.Achievements.Cpp, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Arcademia.Achievements.Cpp@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Arcademia.Achievements.Cpp&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Arcademia.Achievements.Cpp&version=1.1.0
                    
Install as a Cake Tool

Arcademia Achievements SDK (C++)

Unlock achievements from your game and let players collect them on their Arcademia account. You set the achievements up on the Arcademia manager, and your game only ever sends the achievement's API name.

This is the native build of the SDK: a flat C ABI shared library, for anything that isn't Unity or .NET, a custom C++ engine, or any other language with basic C FFI support (Python's ctypes, Go's cgo, Rust and so on). If you're building in Unity, use the Unity package. If you're on .NET (including Godot's C# scripting), use the NuGet package.

Full platform docs: https://manager.arcademia.ac/docs

Windows x64 only for now, since live mode is tied to the arcade cabinets' named-pipe transport.

Install

NuGet (Visual Studio / MSBuild C++ projects)

nuget install Arcademia.Achievements.Cpp

or add it through Visual Studio's NuGet Package Manager. This sets up the include path, library path and a post-build DLL copy for you.

Build from source

Requires CMake 3.20+ and a C++17 compiler targeting Windows (MSVC or MinGW-w64).

cmake -S . -B build
cmake --build build --config Release

Produces arcademia_achievements.dll (plus its import library) and a quickstart sample executable.

This library is completely separate from the leaderboards library. Use one, the other, or both.

Setting up

  1. On the manager, open your game and click the trophy icon to get to Achievements.
  2. Request access. Once it's approved, generate an achievements API key. This is a different key from the leaderboards one.
  3. Pick who competes (see "Scopes" below) and add your achievements. The API name is what your code uses, for example FIRST_BLOOD.
  4. Put the key in an arcademia.json file next to your built executable:
{
  "apiBase": "https://manager.arcademia.ac",
  "achievementsKey": "arc_xxxxxxxx_..."
}

If you also use the leaderboards SDK, keep its apiKey in the same file. Each SDK only reads its own key. You can also call arcademia_achievements_configure(api_base, achievements_key). Pass NULL for either argument to keep the current value.

Quick start

#include <arcademia_achievements.h>

void OnLevelTenCleared()
{
    arcademia_achievements_free(arcademia_achievements_unlock("FIRST_BLOOD"));
}

On a cabinet that's all you need. The launcher shows the toast over your game and offers the player a QR code to claim it when the game closes. On your own PC nothing appears on screen until your game draws the toasts (see Drawing toasts yourself). Unlocking the same achievement again in the same playthrough does nothing, so you don't need to track it yourself.

Every call that returns data gives you a JSON string. Parse it with whatever JSON library you already use, then release it with arcademia_achievements_free, never your own free or delete. Calls block while they talk to the launcher or the server, so run them off your render thread if a short stall matters.

Two modes, one API

Launcher (Live) Sandbox
When The game was started by the Arcademia launcher on a cabinet Anywhere else: your dev machine, a build you're testing
Auth Nothing you set. The launcher and the cabinet handle it Your achievements key
Unlocks land on The live achievements for that cabinet's team A private test area only you can see
Toasts Drawn by the launcher on top of your game Passed to your toast callback for you to draw
Claiming A QR code on the cabinet after the game closes arcademia_achievements_request_sandbox_claim gives you a link

arcademia_achievements_mode() returns ARCADEMIA_ACHIEVEMENTS_MODE_LAUNCHER or ARCADEMIA_ACHIEVEMENTS_MODE_SANDBOX. The SDK picks the mode itself by checking for environment variables the launcher sets.

Scopes

You choose one scope per game on the manager:

  • Sessional: every playthrough starts fresh. Players always claim achievements for themselves.
  • Local: each arcade machine competes on its own.
  • Institutional: each site competes as a team.
  • National: each country competes as a team.

For the team scopes, the first time a team unlocks an achievement it's recorded against the team straight away, even if nobody claims it. A player who claims it afterwards is named as the team's claimer. Each achievement also has a "personal claims" switch. When it's on, players can add the achievement to their own collection too (once per team, so they can collect it again at another site).

API

void        arcademia_achievements_init(void);
void        arcademia_achievements_shutdown(void);
int         arcademia_achievements_mode(void);
void        arcademia_achievements_configure(const char* api_base, const char* achievements_key);

const char* arcademia_achievements_ping(void);
const char* arcademia_achievements_get(void);
const char* arcademia_achievements_unlock(const char* api_name);
const char* arcademia_achievements_open_overlay(void);

const char* arcademia_achievements_poll_toast(void);
const char* arcademia_achievements_icon_file(const char* icon_url_or_path);

void        arcademia_achievements_set_toast_callback(arcademia_achievements_toast_callback cb, void* user_data);
void        arcademia_achievements_set_claim_link_callback(arcademia_achievements_claim_link_callback cb, void* user_data);

void        arcademia_achievements_new_sandbox_session(void);
const char* arcademia_achievements_request_sandbox_claim(void);

void        arcademia_achievements_free(const char* ptr);

init is optional, every call initialises the SDK on first use.

arcademia_achievements_unlock

{
  "Success": true,
  "Status": "unlocked",
  "ApiName": "FIRST_BLOOD",
  "Name": "First Blood",
  "Description": "Win your first round",
  "IconUrl": "https://manager.arcademia.ac/api/Achievements/Icons/default",
  "IconPath": null,
  "AllowPersonal": true,
  "TeamHadIt": false,
  "TeamLabel": "University of Lincoln",
  "TeamClaimedBy": null,
  "Scope": "Institutional",
  "Offline": false,
  "ShowToastInGame": false,
  "Message": null,
  "Mode": "Launcher"
}

Status is one of:

  • unlocked: first time this playthrough.
  • alreadyUnlocked: already unlocked this playthrough. Nothing happens, and the result only has Success, Status, ApiName and Mode.
  • unknown: no achievement with that API name exists for your game.
  • rejected or error: something went wrong, see Message.

TeamHadIt, TeamLabel and TeamClaimedBy tell you whether the player's team already had the achievement. Offline is true when the cabinet has no connection and the unlock was queued to send later.

arcademia_achievements_get

{
  "Success": true,
  "Mode": "Launcher",
  "Offline": false,
  "GameName": "My Game",
  "Scope": "Institutional",
  "TeamLabel": "University of Lincoln",
  "Achievements": [
    {
      "ApiName": "FIRST_BLOOD",
      "Name": "First Blood",
      "Description": "Win your first round",
      "IconUrl": "https://manager.arcademia.ac/api/Achievements/Icons/default",
      "IconPath": "C:\\...\\Achievements\\Icons\\b1258....png",
      "Hidden": false,
      "AllowPersonal": true,
      "SortOrder": 0,
      "UnlockedThisSession": true,
      "HeldByTeam": true,
      "Unlocked": true,
      "TeamUnlockedAt": "2026-09-25T00:21:53.132Z",
      "TeamClaimedBy": null
    }
  ]
}

Achievements with Hidden set are secret. Hide their name and description in your own screens until Unlocked is true.

Drawing toasts yourself

The launcher draws toasts on a cabinet, so you usually don't need to. Your toast callback is called when your game should draw one instead:

  • in sandbox mode, so you can see unlocks while testing, and
  • on a cabinet when the launcher can't draw over your game (true exclusive fullscreen, see below).

The simplest way is to ask for toasts once a frame from your main loop. It returns NULL when nothing is waiting:

while (const char* toast_json = arcademia_achievements_poll_toast())
{
    MyHud::QueueToast(toast_json);
    arcademia_achievements_free(toast_json);
}

Or set a callback. It runs on the thread that called arcademia_achievements_unlock, and the string is only valid during the callback, so copy it if you need it later. Once a callback is set, toasts go to it instead of the poll queue, so using both never shows a toast twice:

static void OnToast(const char* toast_json, void* user_data)
{
    MyHud::QueueToast(toast_json);
}

arcademia_achievements_set_toast_callback(OnToast, nullptr);

If neither is set up, the library writes a warning to stderr and the debugger output each time a toast is dropped.

The JSON has Title and Subtitle as ready-made text, plus Name, Description, IconUrl, IconPath, TeamHadIt, TeamLabel and AllowPersonal. TeamHadIt is true when the player's team already held the achievement, which is worth styling differently. IconPath is a local image file whenever the icon could be loaded: the launcher's copy on a cabinet, or one the library downloaded in sandbox mode, so you can load it the same way as any other texture. arcademia_achievements_icon_file(icon_url) gives you the same for any icon in arcademia_achievements_get, for your own achievements screen. Free its result with arcademia_achievements_free.

Achievements screen

Call arcademia_achievements_open_overlay from a menu button to show a Steam-style list of every achievement over your game. On a cabinet the launcher draws the list and the call blocks until the player closes it with Exit, so call it from a worker thread and pause your game until it returns. Your game still receives controller input while the list is open, so make sure a paused game ignores it.

{ "Success": true, "Status": "closed", "DrawInGame": false, "Message": null, "Mode": "Launcher" }

DrawInGame is true (with Status set to renderInGame) in sandbox mode, where there's no launcher, and when the launcher can't draw over your game. Draw your own screen from arcademia_achievements_get in that case.

Fullscreen

On a cabinet the launcher draws toasts and the list in a window on top of your game. That works with windowed and borderless fullscreen, and with normal fullscreen on Windows 10 and 11. It can't draw over a game in true exclusive fullscreen, so prefer borderless. If the launcher detects exclusive fullscreen anyway, unlocks come back with ShowToastInGame set, your toast callback is called, and the overlay call returns DrawInGame.

Testing

Everything works on your own PC in sandbox mode. Unlocks go to a test area that only you can see.

  • arcademia_achievements_new_sandbox_session() simulates a new playthrough.
  • arcademia_achievements_request_sandbox_claim() creates a claim link for the current sandbox playthrough, so you can try the claim page yourself. The link is written to stderr and the debugger output, and passed to the callback set with arcademia_achievements_set_claim_link_callback. The call blocks until the link is used or expires after 5 minutes. Only the game's owners can claim sandbox playthroughs.
  • The manager's Achievements page has a Sandbox tab showing your test unlocks, with a Reset button.

Sample

samples/quickstart/main.cpp is a console app with a menu that exercises every call. It's built along with the library.

License

MIT, see LICENSE.md.

Product Compatible and additional computed target framework versions.
native native is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 51 9/26/2026
1.0.0 58 9/25/2026