PRO DEVELOPER GUIDE

Build with Pro Features

Step-by-step integration tutorials for auto-updates, achievements, multiplayer, cloud saves, and more.

GETTING STARTED

Getting Started with Pro Features

Pro features are available to all RakuAI Pro subscribers. Once you activate your Pro license, all Pro APIs become available in both the runtime and the SDK. No additional downloads or plugins are required.

1. Activate your Pro license

After subscribing, call raku_license_activate() with your license key at startup. This enables all Pro subsystems.

// Initialize the engine, then activate Pro raku_engine_init(); RakuLicenseResult result = raku_license_activate("YOUR-LICENSE-KEY"); if (result == RAKU_LICENSE_OK) { // All Pro APIs are now available raku_log_info("Pro license activated"); }

2. Check feature availability

You can query whether specific Pro features are enabled at runtime. This is useful for games that support both Free and Pro tiers.

if (raku_license_has_feature("cloud_saves")) { raku_cloud_save_init(); } if (raku_license_has_feature("multiplayer")) { raku_lobby_init(); }
Note: Pro features degrade gracefully. If a Pro API is called without an active license, it returns RAKU_ERROR_LICENSE_REQUIRED instead of crashing. Your game continues to run with Free-tier capabilities.

3. Using Pro features in .raku files

Pro features can also be enabled declaratively in your .raku game files. Add the relevant sections to your JSON and the runtime handles initialization automatically.

{ "pro": { "auto_update": { "enabled": true, "channel": "stable" }, "cloud_saves": { "enabled": true, "max_slots": 5 }, "achievements": { "enabled": true }, "multiplayer": { "enabled": true, "max_players": 8 } } }
AUTO-UPDATE

Integrating Auto-Update Checking

The Auto-Updater lets your exported games check for new versions, download patches, and install updates with minimal player friction. It supports delta patching, update channels, and mandatory vs. optional updates.

Initialize the updater

Point the updater at your update server URL. The engine handles version comparison and download management.

// Initialize auto-updater with your update endpoint raku_updater_init("https://updates.yourgame.com/manifest.json"); // Set the current version (usually read from your build) raku_updater_set_current_version("1.2.0"); // Choose update channel raku_updater_set_channel("stable"); // or "beta"

Check for updates

The check is asynchronous. Register a callback to handle the result without blocking your game loop.

void on_update_check(RakuUpdateInfo* info) { if (info->available) { raku_log_info("Update available: v%s", info->new_version); if (info->mandatory) { // Force update — show blocking dialog raku_updater_download_and_install(); } else { // Optional — show prompt, let player decide raku_updater_show_prompt( "A new version is available. Update now?" ); } } } // Trigger the check (non-blocking) raku_updater_check_async(on_update_check);
Tip: Call raku_updater_check_async() at game startup or from a settings menu. Avoid checking during gameplay to prevent network latency spikes.
ACHIEVEMENTS

Adding Achievements to Your Game

Define achievements with unlock conditions, track progress incrementally, and display notification popups. Achievements sync with Steam and platform-native systems when your game is exported as a standalone.

Define achievements

Register your achievements at startup with an ID, display name, description, and optional icon.

// Initialize the achievement system raku_achievements_init(); // Define achievements raku_achievement_define("first_kill", "First Blood", // display name "Defeat your first enemy", // description "icons/first_blood.png" // icon path ); raku_achievement_define("collect_100", "Hoarder", "Collect 100 items", "icons/hoarder.png" ); // For progress-based achievements, set a target raku_achievement_set_target("collect_100", 100);

Unlock and track progress

Unlock one-shot achievements directly, or increment progress for cumulative ones.

// Unlock a one-shot achievement raku_achievement_unlock("first_kill"); // Shows a notification popup automatically // Increment progress on a cumulative achievement raku_achievement_add_progress("collect_100", 1); // Automatically unlocks when progress reaches the target // Query current progress int progress = raku_achievement_get_progress("collect_100"); bool unlocked = raku_achievement_is_unlocked("collect_100");

Leaderboards

Submit scores and query rankings with the built-in leaderboard system.

// Create a leaderboard raku_leaderboard_create("high_scores", RAKU_LEADERBOARD_DESCENDING // highest score first ); // Submit a score raku_leaderboard_submit("high_scores", 42500); // Query top 10 RakuLeaderboardEntry entries[10]; int count = raku_leaderboard_get_top("high_scores", entries, 10); for (int i = 0; i < count; i++) { raku_log_info("#%d: %s - %d", i+1, entries[i].player_name, entries[i].score); }
MULTIPLAYER

Enabling Multiplayer Lobbies

The Lobby API handles room creation, player discovery, matchmaking, and state synchronization. Built on WebRTC with automatic NAT traversal and relay fallback for reliable connectivity.

Create a lobby

The host creates a lobby with a game mode, player cap, and visibility setting. A shareable room code is generated automatically.

// Initialize multiplayer subsystem raku_lobby_init(); // Create a new lobby RakuLobbyConfig config = { .game_mode = "deathmatch", .max_players = 8, .visibility = RAKU_LOBBY_PUBLIC, // or PRIVATE, FRIENDS_ONLY .region = "auto" }; RakuLobby* lobby = raku_lobby_create(&config); // Get the room code for sharing const char* code = raku_lobby_get_code(lobby); raku_log_info("Room code: %s", code); // e.g. "XKCD-42"

Join a lobby

Players join by room code or through the matchmaking system.

// Join by room code RakuLobby* lobby = raku_lobby_join_code("XKCD-42"); // Or use matchmaking to find a public lobby raku_lobby_find_match("deathmatch", on_match_found); // Listen for player join/leave events raku_lobby_on_player_joined(lobby, on_player_joined); raku_lobby_on_player_left(lobby, on_player_left);

Send and receive game state

Use reliable or unreliable channels depending on whether data must arrive in order.

// Send state to all players (reliable, ordered) raku_lobby_broadcast(lobby, game_state_data, data_size, RAKU_CHANNEL_RELIABLE ); // Send position updates (unreliable, fast) raku_lobby_broadcast(lobby, position_data, pos_size, RAKU_CHANNEL_UNRELIABLE ); // Handle incoming data void on_data_received(RakuPeer* peer, const void* data, size_t size) { // Process incoming game state from peer apply_remote_state(peer->player_id, data, size); } raku_lobby_on_data(lobby, on_data_received);
Tip: Use RAKU_CHANNEL_RELIABLE for game events (damage, pickups, chat) and RAKU_CHANNEL_UNRELIABLE for frequent position/rotation updates to minimize latency.
CLOUD SAVES

Using Cloud Saves

Cloud saves let players continue their progress across devices. The system handles synchronization, conflict resolution, encryption, and offline caching automatically.

Initialize and save

Save arbitrary data to named slots. Each slot is versioned and encrypted at rest.

// Initialize cloud save system raku_cloud_save_init(); // Save game state to a named slot RakuSaveData save = { .slot_name = "slot_1", .data = game_state_buffer, .size = game_state_size }; RakuSaveResult result = raku_cloud_save_write(&save); if (result == RAKU_SAVE_OK) { raku_log_info("Game saved to cloud"); }

Load a save

Load data from any slot. The system syncs with the cloud first, falling back to a local cache if offline.

// Load game state from a slot RakuSaveData loaded; RakuSaveResult result = raku_cloud_save_read("slot_1", &loaded); if (result == RAKU_SAVE_OK) { restore_game_state(loaded.data, loaded.size); raku_cloud_save_free(&loaded); }

List and manage slots

Query available save slots with metadata like timestamps and size.

// List all save slots RakuSaveSlotInfo slots[10]; int count = raku_cloud_save_list(slots, 10); for (int i = 0; i < count; i++) { raku_log_info("Slot: %s | Size: %zu bytes | Last saved: %s", slots[i].name, slots[i].size, slots[i].timestamp); } // Delete a save slot raku_cloud_save_delete("slot_1");
Conflict resolution: When the same slot is modified on two devices, the engine uses last-write-wins by default. Override this with raku_cloud_save_set_conflict_handler() to implement custom merge logic.

Ready to Build?

Full API reference for all Pro systems is available in the documentation. Start building with Pro features today.