A kept device id and config for the signed-in player
- A device id the SDK makes once and keeps (
ThisDeviceId, Blueprint Flock Get This Device Id): leave the device id empty inLoginWithDevice,RegisterWithDeviceandLinkDevice(or their nodes) to use it. A game that already passes an id of its own keeps passing it, so its players are unchanged. See Players and auth. - Config read after sign-in gives the player’s own values: a gameplay or feature config comes with the overrides of the player’s segments and the player’s own. Read again after sign-in; other configs and reads with nobody signed in keep the game-wide values. See Remote config.
- The generated currency list holds game currencies only: a real-money item’s currency is no longer a member. Run Sync Schemas again.
- A passing store setup check no longer logs a warning and an error for the made-up receipt it sends.
A kept device id and config for the signed-in player
- A device id the SDK makes once and keeps (
Authentication.ThisDeviceId): leave the id out ofLoginWithDeviceAsync,RegisterWithDeviceAsyncandLinkDeviceAsyncto use it. A game that already signs players in with an id of its own must keep passing it, or those players get a new account. See Players and auth. - Config read after sign-in gives the player’s own values: a gameplay or feature config comes with the overrides of the player’s segments and the player’s own. Read again after sign-in; other configs and reads with nobody signed in keep the game-wide values. See Remote config.
FlockFundIdlists game currencies only: a real-money item’s currency is no longer a member. Run Sync Schemas again.- A web checkout whose read stopped before it ended reports an unknown outcome (
OutcomeUnknown) instead of a failure, so the item is not offered again while the player can still pay its page. - Advanced Settings has an Offline Cache card (Enable Offline Cache, Offline Cache Directory), and the Quick Start sample registers a device on its first launch.
Real-money purchases from Blueprint, and the shop sample
- Store nodes (Flock | Store): connect the store, show its prices, restore, check its setup, and start or read a web checkout; buying stays the ordinary Flock Purchase node. Flock Redeem Store Receipt redeems a purchase a game’s own store code made.
- Two events on Flock’s events hub,
OnStorePurchaseCompletedandOnStorePurchaseNotDelivered, so a binding made once at start hears every store connection. - A store setup check is ready on a web checkout when nothing was found to fix; it read not ready on every web checkout, so a shop gated on it was hidden on Windows, Mac and Linux.
- A purchase waiting for its payment still answers when the Blueprint that started it is gone.
- The shop sample, made of Blueprints only (
Content/Samples/Shop): a shop screen that signs a device in, shows the wallet, the prices and what the player owns, and buys, uses and restores. See Shops and inventory. - A logger set at any time reaches every part of the SDK, and the first node of a Blueprint chain can be left unwired.
- The SDK compiles for Android on UE 5.8 again.
Real-money purchases
- Sell shop items for real money with the same call as every other item,
FFlockShopProvider::Purchase.UFlockStore::Connectconnects the platform’s own way to pay: Google Play on Android and the App Store on iOS, through the engine’s online subsystem, and a web checkout through Stripe, Tap or Moyasar on Windows, Mac and Linux. Nothing more to install. See Web checkout and Shops and inventory. - Flock’s server checks every purchase before delivering it, once per store purchase. The store’s
purchase is finished only once Flock delivered it, so one interrupted by a crash is sent again at the next
launch;
Restorerestores what the player bought before, andRedeemStoreReceiptredeems a store purchase a game made itself. A web checkout the player left open is found at the next sign-in and reported once paid. - A shop screen’s reads: whether an item costs real money (
IsRealMoney) and its product id in each store, the player’s wallet by currency code (FFlockPlayerProvider::GetWallet), the items they own and have not used (GetOwnedItemCounts,ConsumeOne) and the price to show (GetPrice: the store’s own on a phone, the item’s own on a web checkout). - An item set to Inactive is refused before the store’s dialog opens, and a purchase the player already paid for is still delivered.
- Every payment failure names its cause and its fix: 19 new error codes, and a store that did not take
the payment says why (
FlockStoreFailureReasons,Expiredamong them). A purchase whose answer was lost says so (bOutcomeUnknown); a wallet purchase is sent again safely under its one key, a payment never twice. - Google Play needs UE 5.8 or later. A game sold on Steam must not take payments through a web checkout, and a Steam build that connects one logs a warning. Mac and Linux run the same code as Windows but have not been tested yet.
Playtests linked to the player, and logos on the feedback form
- A playtest session started while a player is signed in carries their sign-in, so Protokite can link the session to their Qwacks Community account. With nobody signed in, the session starts as before.
- The feedback form carries the game’s own logos (Feedback Form Logos and Feedback Form Logo Height) in a row above its title, and Powered by Qwacks at its bottom left, which Feedback Form Footer Logo replaces with the game’s own. See Protokite in Unreal.
- A token renewal still on its way when the game shuts Flock down no longer reaches the next initialization, and a renewal refused because another run renewed the sign-in first carries on with that renewal instead of signing the player out.
- An API URL written without quotes in a config file (read by the engine as
http:alone) stops initialization and says why.
Playtests linked to the player, and logos on the feedback form
- A playtest session started while a player is signed in carries their sign-in, so Protokite can link the session to their Qwacks Community account. With nobody signed in, the session starts as before.
- The feedback form carries the game’s own logos in a row above its title, and Powered by Qwacks at its bottom left, which a footer logo of the game’s own replaces. See Protokite in Unity.
- A sign-in renewal answered after
FlockClient.Shutdown()saves its new tokens for the nextCreate, a renewal refused because another run renewed first carries on with that renewal, and a client that has shut down announces nothing to the next one’s listeners.
Real-money purchases
- Sell shop items for real money with one call for every item,
Shop.PurchaseAsync.FlockStore.ConnectAsyncconnects the platform’s own way to pay: Google Play on Android and the App Store on iOS, both through Unity IAP 5, and a web checkout through Stripe, Tap or Moyasar on desktop and WebGL. See Real-money purchases and Web checkout. - Flock’s server checks every purchase before delivering it, once per store purchase. One
finished while the game was closed, or interrupted by a crash, is delivered at the next launch;
RestoreAsyncrestores what the player bought before. - A shop screen’s reads: the player’s wallet (
Player.GetWalletAsync), the items they own and have not used (Shop.GetOwnedItemCountsAsync,ConsumeOneAsync) and the price to show (GetPrice: the store’s own on a phone, the item’s own on a web checkout). - An item set to Inactive is refused before the store’s dialog opens, and a purchase the player already paid for is still delivered.
- Every payment failure names its cause and its fix. A purchase whose answer was lost says so
(
OutcomeUnknown); a wallet purchase is sent again safely, a payment never twice.
Networks that block UDP
- A player whose network blocks UDP to Flock’s relay now reaches it another way: UDP over IPv6, then TCP, then TLS. Some phone hotspots, offices, schools and hotels drop UDP over IPv4, and such a player could not host or join through the relay. A blocked way costs about 2 seconds, another port of the same kind half a second.
- A player on a network with IPv6 alone reaches the relay at its IPv6 address, and plays with everyone else.
- A joining player reaches the host’s relay by any way in, so a host on UDP and a player on TLS play together.
- When no way in works,
relay_unreachablenames each way tried and why it failed. InitializeWithConfighonors its config’s Enable Debug Logs when the SDK logged before it (as it does with Auto-Initialize On Load off); the settings’ flag was used instead.
Networks that let only web traffic through
- A player on a network that lets only web traffic through reaches the relay in about 5 seconds, not 10. Flock is adding the relay’s web ports (80 and 443); the SDK tries another port of the same kind half a second after one that does not answer, and other ways 2 seconds apart.
Networks that block UDP
- A player whose network blocks UDP to Flock’s relay now reaches it another way: UDP over IPv6, then TCP, then TLS. Some phone hotspots, offices, schools and hotels drop UDP over IPv4, and such a player could not host or join through the relay. A blocked way costs about 2 seconds.
- A player on a network with IPv6 alone reaches the relay at its IPv6 address, and plays with everyone else.
- A joining player reaches the host’s relay by any way in, so a host on UDP and a player on TLS play together.
- When no way in works,
relay_unreachablenames each way tried and why it failed.
A relay that stops answering
- A relay that stops answering this device is told lost within a minute, so
RelayLostbrings the game back: starting the netcode again opens another relay. Until now it was told lost only when the relay came up for renewal, minutes later. - A playtest recording on an NVIDIA graphics card no longer risks crashing the game when it ends. The encoder is let go only once it has finished its own work.
- Analytics events queued within the same instant are sent in the order they came, on Windows too.
- Log lines and failure messages read the same on every machine: decimals are written with a point whatever the machine’s language settings, and saved files are named for the Gregorian date.
Android
- The SDK builds and runs on Android. It did not compile for Android before, and once it did, it could not look up the relay’s name there, so a player on Android could not reach Flock’s relay. Measured on a phone on mobile data, playing through Cloudflare’s relay and then on a direct path with a host on another network.
Direct paths for relayed players
- A player who came through Flock’s relay moves to a direct path once it and the host reach each
other (
WhenNeeded), and back to the relay when that path goes quiet for 4 seconds. The game’s connection carries on through both, and the relay carries nothing for that player meanwhile.Alwaysnever moves, so every address stays hidden. See Direct paths. - A relayed player whose game connects again is back in within seconds, rather than once the engine had timed its old connection out a minute later.
Multiplayer
- Parties, matchmaking and sessions. Friends form a party with an invite code, find a match alone or as a party, or join a friend’s game by its join code. The SDK keeps each seat, follows the party, the search and the session in the background, and raises events when they change. See Multiplayer.
- Travel To Session connects a session’s players over the engine’s own networking: the host opens its level listening and says where to reach it, and each player travels to it. Players on the host’s network connect directly; everyone else goes through Flock’s relay, so nobody forwards a port. The host’s game mode lets in only the session’s players. See Connecting players.
- When the host leaves, another player takes over (1.35.0): each game calls Travel To Session again on On Host Changed, and on On Relay Lost when its relay stops working.
- Blueprint: a node for every call, and Flock Game Mode Base for the host’s check.
- Sample (1.36.0): a multiplayer sample made of Blueprints only, in the plugin’s Content/Samples/Multiplayer folder.
- A relay that stops answering is told lost within a minute (1.37.0), so On Relay Lost brings the game back: found playing through Flock’s relay on a real network.
- Multiplayer error codes, each with a fix, under
EFlockErrorCode.
Multiplayer
- Parties, matchmaking and sessions. Friends form a party with an invite code, find a match alone or as a party, or join a friend’s game by its join code. The SDK keeps each seat, follows the party, the search and the session in the background, and raises events when they change. See Multiplayer.
session.StartNetcodeAsync(networkManager)connects a session’s players over Netcode for GameObjects 1.x or 2.x. Players on the host’s network connect directly; everyone else goes through Flock’s relay, so nobody forwards a port. The host lets in only the session’s players. See Connecting players.- Relayed players move to a direct path to the host when the two can reach each other, and
the relay stays ready in case that path goes quiet (
WhenNeededonly). - Flock’s relay on Cloudflare’s network (1.84.0): each player tells the host its relay address, so relays that give every player’s address an IP of its own work, and the SDK keeps trying until it finds a way through to a relay server that does not answer every connection. Phones on mobile data now find their own address too, so they reach other players directly more often.
- When the host leaves, another player takes over. Each game starts its netcode again on
HostChanged, and onRelayLostwhen its relay stops working. - Samples: Play With Friends and Quick Match, one component each, in the package’s Samples/Multiplayer folder.
- Multiplayer error codes, each with a fix hint, under
FlockErrorCode.
Unreal Engine 5.4
- Unreal Engine 5.4 is supported, so the range is now 5.4 to 5.8, and a 5.4 project installs the plugin unchanged. 5.4 is built and linked in a real project; the full test suite has not been run on it yet, as it is on 5.5 to 5.8.
- Known engine issue on 5.4 and 5.5: a Development package ends with an access violation about 60 seconds after it quits. It is the engine’s, fixed by Epic in 5.6. See the Unreal SDK guide.
Shop rewards and server-backed reminders
- Purchases grant their contents server-side, and the SDK tells you what was granted.
Purchasecompletes withFFlockPurchaseResult— the rewards handed out, the wallet afterwards, and the inventory entry if the item created one. See Shops and Inventory. - New:
Consume(InventoryId)spends an owned item and returns what it granted, with the same money safety as a purchase: an ambiguous failure surfaces instead of being re-sent, so a reward is never granted twice. In Blueprint, Flock Consume Inventory Item. Rewardson a catalog item advertises what it will give before it is bought, andTypedistinguishes a currency pack from a consumable or a standard item.- Breaking:
Purchasecompletes withFFlockPurchaseResultinstead ofFFlockPlayerInventory. The inventory entry moved to.Inventory, and it is empty for a currency pack, which hands its contents over outright and creates nothing to own — use Has Inventory Row before reading it. A generatedPurchasemacro’s output pin is renamed; regenerate after upgrading. - New: Flock Cancel All Scheduled Notifications and Flock Get Pending Schedules Blueprint nodes. Both were C++-only, so a “clear my reminders” button could not be built in a graph — and the obvious substitute, a ForEach over Flock Cancel Scheduled Notification, fires every cancel in one frame where they race over the stored list. The node walks them sequentially.
- New pure nodes for reward kinds — Is Currency Reward, Flock Currency Reward Type — because a reward’s type is a string the server owns. Comparing it to a hand-typed value risks a typo reading as “not a currency reward” and silently skipping the grant.
GetScheduled()asks the server which reminders a player has pending, so it sees reminders set before a reinstall or on another device. Filter withFlockScheduledNotificationStatuses::Pending/::Delivered/::Canceled, or the Flock Schedule Status nodes in Blueprint. See Notifications.CancelAllScheduled()now cancels everything the player has pending, wherever it was scheduled. It falls back to the local record only when the server cannot be reached.GetPendingSchedules()is unchanged and still synchronous and network-free; it is now the offline fallback rather than the primary list.
Read a player's scheduled reminders
GetScheduledAsync()asks the server which reminders a player has pending. Until now the only list was the SDK’s own record of what this install had scheduled, so a reinstall or a second device lost the handle and the player could not cancel their own reminders. See Notifications.- Filter by state with
ScheduledNotificationStatuses.Pending,.Deliveredor.Canceled. Pending is the default. CancelAllScheduledAsync()now cancels everything the player has pending, wherever it was scheduled — not just what the current install tracked. It falls back to the local record when the server cannot be reached, so an offline caller still cancels what it knows about.GetPendingSchedules()is unchanged and still synchronous and network-free; it is now the offline fallback rather than the primary list.
Shop items that grant rewards
- Purchases grant their contents server-side, and the SDK tells you what was granted. A
purchase returns
PurchaseResult— the rewards handed out, the wallet afterwards, and the inventory entry if the item created one — so a game can show “+500 Gold” without a second call. See Shops and Inventory. - New:
ConsumeAsync(inventoryId)spends an owned item and returns what it granted. Consuming moves currency, so it carries a purchase’s money safety: an ambiguous failure surfaces instead of being re-sent, and a reward is never granted twice. ShopItem.Rewardsadvertises what an item will give before it is bought, andShopItem.Typedistinguishes a currency pack from a consumable or a standard item.- Breaking:
PurchaseAsyncreturnsPurchaseResultinstead ofPlayerInventory. The inventory entry moved toresult.Inventory. Call sites that used the return value directly need that one change; the compiler will point at each of them. GrantedandRewardsare never null — an item that grants nothing yields an empty list.
Errors that name the fix
- Errors say what to do, not just what broke. A failed call used to read
Validation failed (HTTP 400), with the server’s own explanation buried in the raw response body.FlockException.Messagenow carries the call that failed, the server’s reason, the coded identifier, and aFix:line — a device login against an unregistered device namesRegisterWithDeviceAsyncoutright. See Error handling. - The fix is specific to the credential: the same
player.invalid_login_credentialsreads as “register this device first” on device sign-in and “wrong password” on email sign-in. - New on the exception:
ServerMessage,HintandOperation, so you can compose your own text instead of parsing the message.FlockErrorHints.For(errorCode)returns the same next-step wording for any code. Keep branching onErrorCode— codes are stable, wording is not. - Malformed-request errors are readable. Responses that name an offending field now surface as
body.player_data: Input should be a valid dictionaryinstead of a bare “Validation failed”. - A missing generated accessor now explains itself. Calling a codegen accessor before running Sync Schemas is a compile error, so no SDK error could ever fire for it. The SDK now watches compilation and prints the missing step, and the Code Generation tab shows whether a sync has ever run. See Work with your game data.
Game notifications
- Game notifications. A per-player inbox with unread counts and read/mark-all-read, reminders your game schedules and cancels server-side, the readable template catalog, and push device-token registration. Every call has a Blueprint node. See Notifications.
- Scheduling is addressed by the template’s name — what you see on the dashboard — with the ID resolved for you.
- Push tokens are registered, not fetched. Get the token from your push plugin (Firebase Cloud
Messaging, OneSignal) and hand it to
RegisterDeviceToken. Unreal ships no way to obtain an Android token itself, so a plugin is required there rather than optional. - Registering on a platform push does not support fails with a validation error rather than
guessing one — check
Flock Get Current Device Platformbefore offering the option. - Inbox reads are offline-cached; read receipts are never queued, and scheduling is never retried after an ambiguous failure, so a network blip cannot double-book a reminder.
Leaderboards
- Leaderboards. Read the top of a board, the signed-in player’s own rank, and the players around them, filtered by window and country. Boards are addressed by name. Scores need no submit call — they come from the player data field the board is configured against. See Leaderboards.
- Standings, board configuration and placements are offline-cached, so a leaderboard screen shows the last-known board when the network is down.
Leaderboards, notifications, and account linking
- Leaderboards. Read the top of a board, the signed-in player’s own rank, and the players around them, filtered by window and country. Scores need no submit call — they come from the player data field the board is configured against. See Leaderboards.
- Game notifications. A per-player inbox with unread counts, read/mark-all-read, push device
registration, and locally scheduled reminders your game can cancel. The template catalog is
readable from the game, and
FlockEvents.OnNotificationReceivedfires as new items arrive. See Notifications. - Account linking. One player can hold several credentials — device, email, Google, Apple, Facebook, Steam, Discord — and link or unlink them at runtime. Every call returns the updated credential list. See Linking Accounts.
- Breaking:
Notification.ScheduleAsyncnow takes the template’s name, not its ID. The parameter is still a string in the same position, so existing calls keep compiling and fail at runtime instead. Migration: pass the name you gave the template on the dashboard. - Auth surface completed — password reset, email verification, server-side token revocation, and a display-name availability preflight.
- Every error now carries a code. Catch
FlockExceptionand branch on the typedErrorCode, e.g.FlockErrorCode.ShopInsufficientFunds, instead of matching message text. - Fixed:
Commands.UpdatePlayerDataAsyncfailing with HTTP 422, and a stray space in the configured API URL breaking every request on WebGL.
Verified engine range 5.5–5.8
- The Unreal SDK is available — player auth, save data, economy, remote config, downloadable assets, and analytics as a native plugin. Every feature works from Blueprint as a self-contained async node, with no Target pin to wire. See the Unreal SDK guide.
- Typed code generation from your own schemas. One click turns templates, configs, and shops into typed Blueprint structs, enums, and one-node reads, writes, and purchases — no C++ and no compile step. Projects that prefer C++ can switch the target and get a generated module instead.
- Offline-safe by design. Config, game, shop-catalog and template reads are cached to disk and served without a connection; player-data writes queue and replay. Currency grants deliberately do not queue, so they cannot double-credit.
- Engine support is a verified range: UE 5.5 to 5.8 — every version in the range is compiled and run against the full test suite before release. Newer engines warn rather than block.
- Leaderboards, notifications, and account linking are Unity-only for now.
Termination tracking & synchronous log API
- Unexpected-termination detection. A run that dies without a clean quit is reported on the
next launch as an automatic
app_terminationevent, classifiedbackground_killorabnormal— see Analytics and Events. - Breaking:
LogExceptionAsync/LogErrorAsync/LogEventAsyncare now synchronousLogException/LogError/LogEvent. They only ever enqueued locally, so the oldawaitresolved on enqueue, not delivery. Migration: drop theawaitand theAsyncsuffix. - New
Analytics.FlushAsync()— a real await that drains everything queued to the server, for the rare moment delivery must be confirmed. Automatic flushing still runs as before. - Unreal SDK: matching update in progress.
Dashboard features
- Leaderboards — rank players on any numeric player-data field, with weekly and seasonal windows, country scopes, and player exclusions.
- Game Notifications — templates, campaigns (all players or a segment; now, scheduled, or recurring), and a per-player inbox across in-app, email, and push.
- Developer Alerts — log-threshold alert rules with severities, cooldowns, and a trigger history in the Alert Center.
- Public developer documentation portal, with Unity and Unreal SDK guides.