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.
raku_engine_init();
RakuLicenseResult result = raku_license_activate("YOUR-LICENSE-KEY");
if (result == RAKU_LICENSE_OK) {
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.
raku_updater_init("https://updates.yourgame.com/manifest.json");
raku_updater_set_current_version("1.2.0");
raku_updater_set_channel("stable");
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) {
raku_updater_download_and_install();
} else {
raku_updater_show_prompt(
"A new version is available. Update now?"
);
}
}
}
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.
raku_achievements_init();
raku_achievement_define("first_kill",
"First Blood",
"Defeat your first enemy",
"icons/first_blood.png"
);
raku_achievement_define("collect_100",
"Hoarder",
"Collect 100 items",
"icons/hoarder.png"
);
raku_achievement_set_target("collect_100", 100);
Unlock and track progress
Unlock one-shot achievements directly, or increment progress for cumulative ones.
raku_achievement_unlock("first_kill");
raku_achievement_add_progress("collect_100", 1);
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.
raku_leaderboard_create("high_scores",
RAKU_LEADERBOARD_DESCENDING
);
raku_leaderboard_submit("high_scores", 42500);
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.
raku_lobby_init();
RakuLobbyConfig config = {
.game_mode = "deathmatch",
.max_players = 8,
.visibility = RAKU_LOBBY_PUBLIC,
.region = "auto"
};
RakuLobby* lobby = raku_lobby_create(&config);
const char* code = raku_lobby_get_code(lobby);
raku_log_info("Room code: %s", code);
Join a lobby
Players join by room code or through the matchmaking system.
RakuLobby* lobby = raku_lobby_join_code("XKCD-42");
raku_lobby_find_match("deathmatch", on_match_found);
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.
raku_lobby_broadcast(lobby, game_state_data, data_size,
RAKU_CHANNEL_RELIABLE
);
raku_lobby_broadcast(lobby, position_data, pos_size,
RAKU_CHANNEL_UNRELIABLE
);
void on_data_received(RakuPeer* peer, const void* data, size_t size) {
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.
raku_cloud_save_init();
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.
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.
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);
}
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.