Client API
Overview
FusionCore::Client is the Fusion networking client.
It manages networked objects, state synchronization, RPCs, ownership, prediction and interest management.
Header: Client.h
Construction and Destruction
C++
explicit Client(RealtimeCore::Matchmaking::RealtimeClient& realtimeClient);
~Client();
| Method | Description |
|---|---|
Client(realtimeClient) |
Construct a Fusion client bound to an existing Realtime connection. |
~Client() |
Destroy the client and release all resources. |
Lifecycle
C++
bool Start();
void Stop();
void Shutdown();
void RefreshRoomCache();
| Method | Description |
|---|---|
Start() |
Begin the Fusion session. Reads fusion_config and fusion_map_data from the joined room, applies the config, fires OnFusionStart, sends the version handshake. Returns false on precondition failure (no room joined, required properties missing or malformed). |
Stop() |
Gracefully stop the Fusion session. |
Shutdown() |
Tear down the client, destroy the Notify connection and all objects. |
RefreshRoomCache() |
Force-refresh cached room state after master-driven property changes. |
Frame Updates
C++
void UpdateFrameBegin(double dt);
void UpdateFrameEnd();
void UpdateServiceOnly();
| Method | Description |
|---|---|
UpdateFrameBegin(dt) |
Begin a frame tick. Call once per frame before reading or writing object state. dt is the frame delta time in seconds. |
UpdateFrameEnd() |
End a frame tick. Queues dirty state and RPCs for sending. |
UpdateServiceOnly() |
Pump the network layer without processing a full frame. Useful during loading screens. |
See Frame Loop for the mandatory 3-step frame sequence.
Status Queries
C++
bool IsRunning() const;
bool IsMasterClient() const;
PlayerId LocalPlayerId() const;
int32_t PlayerCount() const;
double GetRtt() const;
RealtimeCore::Matchmaking::RealtimeClient& GetRealtimeClient();
bool HasRealtimeClient() const;
static SdkVersion GetSdkVersion();
| Method | Description |
|---|---|
IsRunning() |
Returns true if the Notify connection is established and the server config has been received. |
IsMasterClient() |
Returns true if the local player is the current master client. |
LocalPlayerId() |
Returns the local player's PlayerId (a uint16_t). |
PlayerCount() |
Returns the number of players in the room. |
GetRtt() |
Returns the current round-trip time estimate in seconds. |
GetRealtimeClient() |
Returns a reference to the underlying RealtimeClient. |
HasRealtimeClient() |
Returns true if the client still holds a valid RealtimeClient reference. Check before calling GetRealtimeClient() in teardown paths. |
GetSdkVersion() |
Returns the compiled SDK version. See SdkVersion. |
Configuration
C++
void SetDynamicOwnerCooldown(double seconds);
double GetDynamicOwnerCooldown() const;
void SetAuthoritySendRate(double rate);
double GetAuthoritySendRate() const;
| Method | Description |
|---|---|
SetDynamicOwnerCooldown(seconds) |
Configure the cooldown applied between dynamic ownership transitions. Default 1.0/3 seconds. |
GetDynamicOwnerCooldown() |
Returns the current dynamic-owner cooldown in seconds. |
SetAuthoritySendRate(rate) |
Configure the send rate used while operating in SimulationMode::Authority. Default 30 Hz. |
GetAuthoritySendRate() |
Returns the current authority send rate. |
Time Synchronization
C++
double NetworkTime() const;
double NetworkTimeScale() const;
double NetworkTimeDiff() const;
double GetTime(const Object *obj);
Tick GetSendTick() const;
Tick GetReceivedCounter() const;
| Method | Description |
|---|---|
NetworkTime() |
Returns the synchronized network time in seconds. |
NetworkTimeScale() |
Returns the current clock scale factor used for time smoothing. |
NetworkTimeDiff() |
Returns the raw difference between local and server clocks. |
GetTime(obj) |
Returns the last received server time for the given object. |
GetSendTick() |
Returns the current outgoing tick counter as a Tick (uint32_t). |
GetReceivedCounter() |
Returns the number of state packets received as a Tick (uint32_t). |
Traffic Statistics
C++
EMAReport GetSendReport() const;
EMAReport GetRecvReport() const;
EMAReport GetSendStateReport() const;
EMAReport GetRecvStateReport() const;
EMAReport GetSendRpcReport() const;
EMAReport GetRecvRpcReport() const;
| Method | Description |
|---|---|
GetSendReport() |
Returns EMA statistics for all outgoing bytes. |
GetRecvReport() |
Returns EMA statistics for all incoming bytes. |
GetSendStateReport() |
Returns EMA statistics for outgoing state bytes. |
GetRecvStateReport() |
Returns EMA statistics for incoming state bytes. |
GetSendRpcReport() |
Returns EMA statistics for outgoing RPC bytes. |
GetRecvRpcReport() |
Returns EMA statistics for incoming RPC bytes. |
See EMAReport for the report struct.
Object Queries
C++
Object *FindObject(ObjectId id, bool allowDestroyed = false) const;
ObjectRoot *FindObjectRoot(ObjectId id) const;
Object *FindSubObjectWithHash(ObjectRoot *root, uint32_t subObjectHash) const;
std::unordered_map<ObjectId, Object *> &AllObjects();
std::unordered_map<ObjectId, ObjectRoot *> &AllRootObjects();
ObjectRoot *GetRoot(Object *obj) const;
const ObjectRoot *GetRoot(const Object *obj) const;
static bool IsRoot(const Object *object);
static bool HasSubObjects(const Object *root);
static const std::vector<ObjectId> &GetSubObject(const Object *root);
static bool HasBeenUpdatedByPlugin(Object *obj, bool reset);
| Method | Description |
|---|---|
FindObject(id, allowDestroyed) |
Look up any object (root or child) by ObjectId. Returns nullptr if not found. Pass allowDestroyed = true to return objects that are pending destruction. |
FindObjectRoot(id) |
Look up a root object by ObjectId. Returns nullptr if not found. |
FindSubObjectWithHash(root, subObjectHash) |
Find a sub-object of a root by its hash. Returns nullptr if not found. |
AllObjects() |
Returns a mutable reference to the map of all objects (roots and children). |
AllRootObjects() |
Returns a mutable reference to the map of all root objects. |
GetRoot(obj) |
Returns the root object for a given object. Returns itself if already a root. |
IsRoot(object) |
Returns true if the object is a root object. |
HasSubObjects(root) |
Returns true if the root has any sub-objects. |
GetSubObject(root) |
Returns the list of sub-object IDs for a root. |
HasBeenUpdatedByPlugin(obj, reset) |
Returns true if the object received a plugin update. If reset is true, clears the flag. |
Object Creation (Root)
C++
ObjectRoot *CreateMapObject(bool &alreadyPopulated, size_t words, const TypeRef &type,
const RealtimeCore::Common::CharType *header, size_t headerLength,
Map map, uint16_t origin, uint64_t hash, ObjectOwnerModes ownerMode,
uint32_t engineFlags, int32_t requiredObjectsCount);
ObjectRoot *CreateGlobalInstanceObject(bool &alreadyPopulated, size_t words, const TypeRef &type,
const RealtimeCore::Common::CharType *header, size_t headerLength,
Map map, uint64_t hash, ObjectOwnerModes ownerMode,
uint32_t engineFlags, int32_t requiredObjectsCount = 0);
ObjectRoot *CreateObject(size_t words, const TypeRef &type,
const RealtimeCore::Common::CharType *header, size_t headerLength,
Map map, ObjectOwnerModes ownerMode,
uint32_t engineFlags, int32_t requiredObjectsCount = 0,
ObjectId preconfiguredId = ObjectId());
ObjectId GetNewObjectId(Map map);
| Method | Description |
|---|---|
CreateMapObject(...) |
Create or retrieve a map-placed object. The deterministic ID is derived from map, origin and the 64-bit hash. Sets alreadyPopulated if the object already existed. |
CreateGlobalInstanceObject(...) |
Create or retrieve a globally-unique instance object (singleton per map and 64-bit hash). Sets alreadyPopulated if the object already existed. |
CreateObject(...) |
Create a dynamically-spawned root object. Pass a preconfiguredId to use a specific ID or leave default to allocate one automatically. |
GetNewObjectId(map) |
Generate the next unique ObjectId in the given Map for the local player. |
engineFlags is a free uint32_t reserved for engine bindings to stash per-object metadata (formerly the role of the removed ObjectSpecialFlags enum).
Object Creation (Sub-Objects)
C++
ObjectChild *CreateSubObject(ObjectId parent, size_t words, const TypeRef &type,
const RealtimeCore::Common::CharType *header, size_t headerLength,
uint64_t engineHash, ObjectId id, uint32_t engineFlags);
static bool AddSubObject(ObjectRoot *parentObject, ObjectChild *subObject);
bool RevertSubObjectCreation(const ObjectChild *obj);
| Method | Description |
|---|---|
CreateSubObject(...) |
Create a child object attached to a parent root. engineHash identifies which engine sub-object slot this maps to (widened from the old 32-bit targetObjectHash to 64 bits). |
AddSubObject(parentObject, subObject) |
Register an existing sub-object under a parent root. |
RevertSubObjectCreation(obj) |
Undo a local sub-object creation before it was ever sent. Only succeeds for a locally created child that has not been transmitted yet; the object is removed from the object table and deleted. Returns true on success, false otherwise. |
Object Destruction
C++
bool DestroyObjectLocal(ObjectRoot *obj, bool engineObjectAlreadyDestroyed);
bool DestroySubObjectLocal(ObjectChild *obj);
| Method | Description |
|---|---|
DestroyObjectLocal(obj, engineObjectAlreadyDestroyed) |
Destroy a root object locally and notify the server. If engineObjectAlreadyDestroyed is true, skips engine-side cleanup. |
DestroySubObjectLocal(obj) |
Destroy a sub-object locally and notify the server. |
RPCs
C++
Rpc CreateUserRpc(uint64_t id, PlayerId targetPlayer, ObjectId targetObject,
uint64_t eventHash, const char *data, size_t dataLength);
bool SendUserRpc(Rpc &rpc);
| Method | Description |
|---|---|
CreateUserRpc(...) |
Construct an RPC message with the given ID, target, event hash and payload data. The DescriptorTypeHash field of older SDKs has been removed; the routing role moves to EventHash. |
SendUserRpc(rpc) |
Queue an RPC for sending. Takes a non-const reference because the SDK assigns Rpc::Sequence in place. Returns true on success. |
See Rpc for the message struct and RpcFlags for the flag set.
Ownership
C++
PlayerId GetOwner(const Object *obj) const;
bool IsOwner(const Object *obj) const;
bool CanModify(const Object *obj);
bool HasOwner(const Object *obj) const;
void SetWantOwner(Object *obj) const;
void SetDontWantOwner(Object *obj) const;
void RespondToOwnershipRequest(Object *obj, PlayerId requester, bool granted);
void ClearOwnerCooldown(Object *obj) const;
static ObjectOwnerModes SanitizeOwnerMode(ObjectOwnerModes ownerMode);
| Method | Description |
|---|---|
GetOwner(obj) |
Returns the current owner PlayerId of the object. |
IsOwner(obj) |
Returns true if the local player owns this object. |
CanModify(obj) |
Returns true if the local player can write to this object's state. |
HasOwner(obj) |
Returns true if the object has any owner assigned. |
SetWantOwner(obj) |
Request ownership of a dynamic object. |
SetDontWantOwner(obj) |
Release ownership intent on a dynamic object. |
RespondToOwnershipRequest(obj, requester, granted) |
Answer an inbound ownership request received via OnOwnershipRequest. Pass the requester PlayerId from the callback; granted = true grants ownership, granted = false denies it. |
ClearOwnerCooldown(obj) |
Reset the ownership transfer cooldown timer for the object. |
SanitizeOwnerMode(ownerMode) |
Static helper that clamps an owner mode to a valid value. |
See Ownership for usage patterns.
Prediction
C++
SimulationMode GetSimulationMode() const;
PlayerId GetPredictingPlayer(const Object *obj) const;
void SetPredictingPlayer(ObjectRoot *obj, PlayerId player) const;
bool IsPredictingPlayer(const Object *obj) const;
bool HasInputAuthority(const Object *obj) const;
uint32_t GetInputSequence(const Object *obj) const;
void SetInputSequence(ObjectRoot *obj, uint32_t sequence);
uint32_t NextInputSequence();
| Method | Description |
|---|---|
GetSimulationMode() |
Returns the current SimulationMode (Shared or Authority). |
GetPredictingPlayer(obj) |
Returns the PlayerId currently predicting the object (only meaningful for ObjectOwnerModes::PlayerPredicted). |
SetPredictingPlayer(obj, player) |
Assign a predicting player to a root object. |
IsPredictingPlayer(obj) |
Returns true if the local player is predicting the object. |
HasInputAuthority(obj) |
Returns true if the local player has authority to feed inputs into the object's prediction queue. |
GetInputSequence(obj) |
Returns the latest input sequence number applied to the object. |
SetInputSequence(obj, sequence) |
Override the input sequence on a root object (advanced use). |
NextInputSequence() |
Allocate the next monotonic input sequence number for the local player. |
See Ownership > Prediction for the input flow and reset semantics.
Send Rate
C++
static void SetRoomSendRate(const Object *obj, int32_t sendRate);
static void ResetRoomSendRate(const Object *obj);
void SetLocalSendRate(Object *obj, uint32_t sendRate) const;
void ResetLocalSendRate(Object *obj) const;
| Method | Description |
|---|---|
SetRoomSendRate(obj, sendRate) |
Set the server-authoritative send rate for the object (ticks between sends). Replaces the older SetSendRate. |
ResetRoomSendRate(obj) |
Reset the object's room send rate to the default. Replaces the older ResetSendRate. |
SetLocalSendRate(obj, sendRate) |
Set a client-local send rate divisor (skips N-1 out of N sends). |
ResetLocalSendRate(obj) |
Reset the object's local send rate to the default. |
Object Interest Keys
C++
static void SetGlobalInterestKey(Object *obj);
static void SetUserInterestKey(Object *obj, uint64_t key);
static void SetAreaInterestKey(Object *obj, uint64_t key);
static bool HasSetInterestKey(Object *obj);
static void ClearInterestKey(Object *obj);
static InterestKeyType GetInterestKeyType(Object *obj);
| Method | Description |
|---|---|
SetGlobalInterestKey(obj) |
Mark the object as globally visible (always sent to all players). |
SetUserInterestKey(obj, key) |
Assign a user-defined interest key to the object. |
SetAreaInterestKey(obj, key) |
Assign an area-of-interest key to the object (server-managed spatial key). |
HasSetInterestKey(obj) |
Returns true if any interest key is assigned to the object. |
ClearInterestKey(obj) |
Remove the interest key from the object. |
GetInterestKeyType(obj) |
Returns the type of interest key assigned (Global, Area or User). |
Player Interest Key Subscriptions
Player-side interest keys (the subscriptions a client wants to receive) live in an InterestKeySet. The flat client-level setter methods that older SDKs exposed are gone; obtain the local set or another player's set and operate on it.
C++
InterestKeySet &GetLocalInterestKeys();
InterestKeySet &GetPlayerInterestKeys(PlayerId player);
| Method | Description |
|---|---|
GetLocalInterestKeys() |
Returns a mutable reference to the local player's InterestKeySet. |
GetPlayerInterestKeys(player) |
Returns a mutable reference to another player's InterestKeySet (master-client use). |
InterestKeySet is a struct with two public fields and the following methods:
C++
std::map<uint64_t, uint8_t> Keys;
bool Dirty{false};
void Set(uint64_t key, uint8_t sendRate);
void Remove(uint64_t key);
void Clear();
void ClearWithPredicate(const std::function<bool(uint64_t)> &predicate);
void ClearAreaKeys();
void ClearUserKeys();
void SetAreaKeys(const std::vector<std::tuple<uint64_t, uint8_t>> &keys);
void AddUserKey(uint64_t key, uint8_t sendRate = 0);
void RemoveUserKey(uint64_t key);
std::vector<std::tuple<uint64_t, uint8_t>> GetAllAreaKeys() const;
std::vector<std::tuple<uint64_t, uint8_t>> GetAllUserKeys() const;
bool IsDirty() const;
void ClearDirty();
Keys maps each encoded key to its per-key send rate and Dirty marks pending changes; both are public, but prefer the methods so Dirty stays consistent.
ClearWithPredicate(predicate) removes every key for which predicate(encodedKey) returns true.
Internally the set encodes area vs user keys in the low bit ((key << 1) | 1 for area, key << 1 for user), and tracks dirty state automatically.
See Interest Area for usage patterns.
Map Management
C++
Map MapChange(const RealtimeCore::Common::CharType *data, size_t dataLength);
Map MapAdd(const RealtimeCore::Common::CharType *data, size_t dataLength);
void MapRemove(Map map);
bool MapIsValid(Map map) const;
const std::unordered_map<Map, Data> &GetMaps() const;
void StateUpdatesPause();
void StateUpdatesResume();
| Method | Description |
|---|---|
MapChange(data, dataLength) |
Initiate a map change with the given serialized map payload. Returns the new Map index. |
MapAdd(data, dataLength) |
Add an additional map to the session without removing existing maps. Returns the new Map index. |
MapRemove(map) |
Remove a map from the session by index. |
MapIsValid(map) |
Returns true if the given map index is active in the session. |
GetMaps() |
Returns a reference to the map of all active maps (index to serialized data). |
StateUpdatesPause() |
Pause outgoing state updates (e.g. during a map transition). |
StateUpdatesResume() |
Resume outgoing state updates after a pause. |
See Scene Management for the multi-map session model.
Broadcasters
All broadcasters use RealtimeCore::Common::Broadcaster<Signature>.
Subscribe via broadcaster.Subscribe(callback) which returns a Subscription handle.
Subscription is not RAII — see Subscription Lifetime below.
| Broadcaster | Signature | Description |
|---|---|---|
OnFusionStart |
void() |
Fired when the server config is received and the Fusion session is ready. |
OnForcedDisconnect |
void(RealtimeCore::Common::StringType message, ForcedDisconnectReason reason) |
Fired when the server forces a disconnect. message contains the reason text and reason is the structured cause. See ForcedDisconnectReason. |
OnRpc |
void(Rpc &) |
Fired when a user RPC is received. |
OnRpcError |
void(Rpc &) |
Fired when an outgoing RPC ultimately failed delivery (its Flags contain bits from RpcFlags::ErrorFlags). |
OnMapChange |
void(const std::unordered_map<Map, Data> &, bool initial) |
Fired when the active map table changes. initial is true on the first delivery during Start(). |
OnObjectOwnerChanged |
void(ObjectRoot *) |
Fired when an object's owner changes. |
OnObjectOwnerPredictionFailed |
void(ObjectRoot *) |
Fired when the server rejects an optimistic ownership claim on a Dynamic-mode object. The local client had assigned itself as owner; the assignment is rolled back. |
OnPredictionReset |
void(ObjectRoot *) |
Fired when the server rejects an input sequence and the prediction queue is reset. |
OnInput |
void(ObjectRoot *, uint32_t sequence, float dt, Data, bool isNew) |
Fired when an input is delivered to a predicted root. isNew distinguishes first delivery from re-application during reconciliation. |
OnObjectReady |
void(ObjectRoot *) |
Fired when all required objects for a root are resolved and the object is ready for use. |
OnSubObjectCreated |
void(ObjectChild *) |
Fired when a remote sub-object is created. |
OnObjectDestroyed |
void(const ObjectRoot *, DestroyModes) |
Fired when a root object is destroyed. DestroyModes indicates the reason. |
OnSubObjectDestroyed |
void(ObjectChild *, DestroyModes) |
Fired when a sub-object is destroyed. |
OnObjectForceAlive |
void(ObjectRoot *) |
Fired when the server forces a root object back to alive state. |
OnSubObjectForceAlive |
void(ObjectChild *) |
Fired when the server forces a sub-object back to alive state. |
OnInterestEnter |
void(ObjectRoot *) |
Fired when a remote object enters the local player's area of interest. |
OnInterestExit |
void(ObjectRoot *) |
Fired when a remote object exits the local player's area of interest. |
OnDestroyedMapActor |
void(ObjectId) |
Fired for each destroyed map actor during a map change. |
OnOwnershipRequest |
void(ObjectRoot *, PlayerId requester) |
Fired on the current owner when another player requests ownership. Answer asynchronously by calling Client::RespondToOwnershipRequest(obj, requester, granted) with the requester PlayerId from the callback; the reply surfaces on the requester via OnOwnershipResponse. |
OnOwnershipResponse |
void(ObjectRoot *, bool granted) |
Fired on the requester after the current owner replies to an ownership request. |
Subscription Lifetime
RealtimeCore::Common::Subscription is a plain handle.
It has no destructor and does not unsubscribe automatically when it goes out of scope.
C++
class Subscription {
public:
void Unsubscribe();
bool IsSubscribed() const;
explicit operator bool() const;
void Block();
void Unblock();
bool IsBlocked() const;
};
| Method | Description |
|---|---|
Unsubscribe() |
Detach the callback from the broadcaster. |
IsSubscribed() |
Returns true while the callback is attached. |
operator bool() |
Equivalent to IsSubscribed(). |
Block() / Unblock() |
Temporarily suppress or re-enable callback invocation without unsubscribing. |
IsBlocked() |
Returns true while the subscription is blocked. |
For scope-bound (RAII) management use the two holder types from RealtimeCore/Common/ScopedSubscription.h and RealtimeCore/Common/SubscriptionBag.h:
C++
class ScopedSubscription {
public:
ScopedSubscription() = default;
ScopedSubscription(Subscription s); // implicit
~ScopedSubscription(); // unsubscribes
Subscription Release();
const Subscription &Get() const;
explicit operator bool() const;
};
class SubscriptionBag {
public:
SubscriptionBag &operator+=(Subscription s);
void UnsubscribeAll();
std::size_t Count() const;
bool IsEmpty() const;
};
| Type | Description |
|---|---|
ScopedSubscription |
Move-only wrapper that calls Unsubscribe() in its destructor. Constructs implicitly from a Subscription; Release() gives the raw handle back without unsubscribing. |
SubscriptionBag |
Collects subscriptions via operator+=. All entries unsubscribe when the bag is destroyed or when UnsubscribeAll() is called. |
Related
- Architecture -- SDK layered design
- Frame Loop -- The mandatory 3-step frame sequence
- Objects -- Object hierarchy and Words buffer
- Object API -- Object, ObjectRoot, ObjectChild classes
- Types API -- Enums, aliases and utility functions
- Overview
- Construction and Destruction
- Lifecycle
- Frame Updates
- Status Queries
- Configuration
- Time Synchronization
- Traffic Statistics
- Object Queries
- Object Creation (Root)
- Object Creation (Sub-Objects)
- Object Destruction
- RPCs
- Ownership
- Prediction
- Send Rate
- Object Interest Keys
- Player Interest Key Subscriptions
- Map Management
- Broadcasters
- Related