API Reference — Generated Code
All classes NetCrafter generates from your schema, plus the runtime components that ship permanently with the package.
Field Type Mapping#
How schema field types map to C# types and SFS3 wire methods. Arrays of any type are represented as List<T> in C# and SFSArray on the wire.
| Schema type | C# type | Write (send) | Read (receive) |
|---|---|---|---|
int | int | obj.PutInt(key, value) | obj.GetInt(key) |
float | float | obj.PutFloat(key, value) | obj.GetFloat(key) |
bool | bool | obj.PutBool(key, value) | obj.GetBool(key) |
string | string | obj.PutString(key, value) | obj.GetString(key) |
PlayerId | int | obj.PutInt(key, value) | obj.GetInt(key) |
ItemId | string | obj.PutString(key, value) | obj.GetString(key) |
Vector2 | Vector2 | obj.PutFloatArray(key, new float[]{x,y}) | obj.GetFloatArray(key) |
Vector3 | Vector3 | obj.PutFloatArray(key, new float[]{x,y,z}) | obj.GetFloatArray(key) |
Quaternion | Quaternion | obj.PutFloatArray(key, new float[]{x,y,z,w}) | obj.GetFloatArray(key) |
| ModelName | ModelName | obj.PutSFSObject(key, model.ToSFSObject()) | ModelName.FromSFSObject(obj.GetSFSObject(key)) |
Any [] | List<T> | SFSArray with typed Add* per element | SFSArray with typed Get* per element |
Request Classes#
Generated from ClientToServer (and ClientToServerToAll) messages. One file per message, placed in Definitions/{Name}/Generated/Client/.
Members
| Member | Description |
|---|---|
| Public fields | One public field per message field, typed as shown in the mapping table above. |
void Send(SmartFox Sfs) | Serialises all fields into an SFSObject and sends an ExtensionRequest with the message name as the command string. |
Example
Schema message PlayerMove with fields playerId: PlayerId, position: Vector3, speed: float generates:
var req = new PlayerMoveRequest
{
playerId = sfs.MySelf.Id,
position = transform.position,
speed = currentSpeed
};
req.Send(sfs);
public class PlayerMoveRequest
{
public int playerId;
public Vector3 position;
public float speed;
public void Send(SmartFox Sfs)
{
var obj = new SFSObject();
obj.PutInt("playerId", playerId);
obj.PutFloatArray("position", new float[] { position.x, position.y, position.z });
obj.PutFloat("speed", speed);
Sfs.Send(new ExtensionRequest("PlayerMove", obj));
}
}
Event Classes#
Generated from ServerToClient messages. One file per event, placed in Definitions/{Name}/Generated/Client/.
Members
| Member | Description |
|---|---|
| Public fields | One public field per event field. |
static {EventName}Event FromSFSObject(ISFSObject data) | Factory method. Deserialises all fields from the ISFSObject received in the EXTENSION_RESPONSE event and returns a populated instance. |
Example
Schema event PlayerStateUpdate with a nested model field state: PlayerState generates:
// Called automatically by SmartFoxConnectionManager
private void OnPlayerStateUpdate(PlayerStateUpdateEvent ev)
{
Debug.Log($"Health: {ev.state.health}, Position: {ev.state.position}");
}
public class PlayerStateUpdateEvent
{
public PlayerState state;
public static PlayerStateUpdateEvent FromSFSObject(ISFSObject data)
{
var ev = new PlayerStateUpdateEvent();
ev.state = PlayerState.FromSFSObject(data.GetSFSObject("state"));
return ev;
}
}
Model Classes#
Generated from Data Definitions. One file per model, placed in Definitions/{Name}/Generated/Client/.
Members
| Member | Description |
|---|---|
| Public fields | One public field per model field. |
ISFSObject ToSFSObject() | Serialises all fields into a new SFSObject and returns it. Use when embedding a model inside a request. |
static {ModelName} FromSFSObject(ISFSObject obj) | Deserialises all fields from an SFSObject. Use when extracting a model from an event. |
Example
// Embed in a request
var state = new PlayerState
{
position = transform.position,
health = currentHealth,
username = playerName,
isAlive = true
};
request.state = state;
// Extract from an event
PlayerState s = PlayerState.FromSFSObject(sfsObj.GetSFSObject("state"));
Debug.Log(s.username);
SmartFoxConnectionManager#
Generated once per schema. Placed in Generated/Client/SmartFoxConnectionManager.cs.
Lifecycle
| Method | When it runs |
|---|---|
Awake() | Initialises the singleton. Destroys duplicate instances. Calls DontDestroyOnLoad. |
Update() | Calls sfs.ProcessEvents() every frame to dispatch queued SFS3 events. |
OnApplicationQuit() | Disconnects from the server cleanly. |
Public API
| Member | Description |
|---|---|
static SmartFoxConnectionManager Instance | Singleton accessor. Available after the first Awake. |
void Connect() | Creates the SmartFox instance, configures it, registers listeners, and calls sfs.Connect(cfg). Safe to call multiple times — ignored if already connected. |
bool IsConnected { get; } | Returns true when the SFS3 client is connected. Implements INetCrafterConnection. |
int LocalUserId { get; } | The local player's SFS3 user ID. Returns -1 if not logged in. Available after a successful Login() call. |
string LocalUserName { get; } | The local player's SFS3 username. Returns string.Empty if not logged in. |
void SendExtensionRequest(string cmd, ISFSObject data) | Sends an ExtensionRequest to the server. No-op if not connected. Implements INetCrafterConnection. |
Inspector Fields
All connection parameters are exposed as Inspector fields, pre-filled from your SmartFox Settings at generation time. You can override them per-scene without touching the asset.
| Field | Description |
|---|---|
host | Server hostname |
port | TCP port |
zone | Zone name |
useWebSocket | Use WebSocket transport |
encrypt | Enable HTTPS tunnel encryption |
useHttpTunnel | Enable BlueBox HTTP tunnel |
httpPort / httpsPort | BlueBox ports |
logLevel | SFS3 log level (default INFO) |
Event Routing
The generated manager registers one EXTENSION_RESPONSE listener that routes events by command name. Each switch case deserialises the payload, dispatches to NetCrafterEventDispatcher, then calls the private stub:
private void OnExtensionResponse(ApiEvent evt)
{
string cmd = (string)evt.Params[EventParam.Cmd];
ISFSObject data = (ISFSObject)evt.Params[EventParam.ExtParams];
switch (cmd)
{
case "PlayerStateUpdate":
{
var ev = PlayerStateUpdateEvent.FromSFSObject(data);
NetCrafterEventDispatcher.Instance?.Dispatch("PlayerStateUpdate", ev);
OnPlayerStateUpdate(ev);
break;
}
// ... one case per event in your schema
}
}
private void OnPlayerStateUpdate(PlayerStateUpdateEvent ev)
{
// Your game logic here — override in a subclass or subscribe via EventDispatcher
}
Both paths always fire
The Dispatch call and the stub method always execute. Handle events by subscribing to NetCrafterEventDispatcher from any script, by overriding the stub in a subclass, or both — they are independent.
NetCrafterEventDispatcher#
A runtime MonoBehaviour that ships permanently with NetCrafter in Scripts/NetCrafterEventDispatcher.cs. Not generated.
Provides a publish–subscribe bus for server events. Any script in your project can subscribe to a command name and receive the already-deserialised typed event object, without subclassing or modifying the generated SmartFoxConnectionManager.
Members
| Member | Description |
|---|---|
static NetCrafterEventDispatcher Instance | Singleton accessor. Available after Awake. Persists across scene loads (DontDestroyOnLoad). |
void Subscribe(string cmd, Action<object> callback) | Registers callback to receive events for cmd. Multiple callbacks for the same command are supported. |
void Unsubscribe(string cmd, Action<object> callback) | Removes a previously registered callback. Safe to call if the callback was never registered. |
void Dispatch(string cmd, object eventObject) | Called internally by the generated SmartFoxConnectionManager. Invokes all registered callbacks for cmd. Each callback runs in an individual try/catch. |
Usage Example
using PivecLabs.Netcrafter;
public class ChatController : MonoBehaviour
{
private void OnEnable()
{
NetCrafterEventDispatcher.Instance.Subscribe("ChatBroadcast", OnChat);
NetCrafterEventDispatcher.Instance.Subscribe("PlayerStateUpdate", OnPlayerState);
}
private void OnDisable()
{
// Always unsubscribe — failing to do so leaves a dangling reference
NetCrafterEventDispatcher.Instance.Unsubscribe("ChatBroadcast", OnChat);
NetCrafterEventDispatcher.Instance.Unsubscribe("PlayerStateUpdate", OnPlayerState);
}
private void OnChat(object payload)
{
var ev = (ChatBroadcastEvent)payload;
Debug.Log($"{ev.senderName}: {ev.message}");
}
private void OnPlayerState(object payload)
{
var ev = (PlayerStateUpdateEvent)payload;
Debug.Log($"Player health: {ev.state.health}, position: {ev.state.position}");
}
}
Notes
- Command names are the schema event names verbatim. Schema event
ChatBroadcast→ subscribe with"ChatBroadcast". - Thread safety. All SFS3 callbacks arrive on the Unity main thread via
sfs.ProcessEvents()inUpdate.Dispatchmust only be called from the main thread. - Exception isolation. One failing subscriber cannot block others receiving the same event. Errors are logged with the command name and full stack trace.
- Always call Unsubscribe in
OnDisableorOnDestroy. A dangling reference causes the callback to fire for the lifetime of the dispatcher.
INetCrafterConnection#
A decoupling interface that lets NetCrafterSyncManager send data through the generated SmartFoxConnectionManager without referencing its user-defined namespace.
Members
| Member | Description |
|---|---|
bool IsConnected { get; } | Returns true when the SFS3 client is connected. |
void SendExtensionRequest(string cmd, ISFSObject data) | Sends an ExtensionRequest to the server. No-op if not connected. |
Why it exists: NetCrafterSyncManager needs to send data through the generated SmartFoxConnectionManager, which lives in a user-defined namespace unknown to the runtime. INetCrafterConnection provides a namespace-agnostic contract. SyncManager finds the implementor at Start by scanning FindObjectsByType<MonoBehaviour>().
NetCrafterSyncManager#
Singleton MonoBehaviour that owns the object registry and routes all sync traffic between NetCrafterSyncBinding components and the server.
Members
| Member | Description |
|---|---|
static NetCrafterSyncManager Instance | Singleton. Persists across scene loads via DontDestroyOnLoad. |
MonoBehaviour connectionManagerOverride | Inspector field. Drag the scene's ConnectionManager here. If null, auto-detection scans for any INetCrafterConnection in the scene. |
void RegisterBinding(int objectId, NetCrafterSyncBinding binding) | Called by NetCrafterSyncBinding.Start. Maps objectId to the binding. |
void UnregisterBinding(int objectId) | Called by NetCrafterSyncBinding.OnDestroy. |
void SubscribeToSyncRule(string ruleName) | Subscribes the manager to incoming sync payloads for ruleName via NetCrafterEventDispatcher. Deduplicates: only one subscription per rule name regardless of how many remote bindings share it. |
bool TrySendSync(string cmd, ISFSObject payload) | Sends a sync payload through the INetCrafterConnection. Returns false and does nothing if not ready or not connected. |
Graceful degradation: If no INetCrafterConnection is found during Start, a Debug.LogError is emitted and _ready is set to false. All subsequent TrySendSync calls return false immediately.
NetCrafterSyncBinding#
Per-object MonoBehaviour that drives the sync tick loop, builds outbound payloads, and applies inbound values. Attach to each networked GameObject.
Inspector Fields
| Field | Type | Description |
|---|---|---|
| Rule | SyncRuleDefinition | The sync rule asset from Definitions/{Name}/SyncRules/. Determines what is synced and how. |
| Object Id | int | Unique integer identifying this object in the network session. Assign from game logic (e.g. sfs.MySelf.Id after login). |
| Has Authority | bool | true = this client owns and sends sync data. false = receives and applies incoming data. |
Sync Modes
| Mode | Behaviour |
|---|---|
Always | Sends every FixedUpdate. Use for values that change every frame. |
OnChange | Sends only when the value has changed by more than an epsilon since the last send. Epsilons: 0.001 units (Vector3), 0.1 degrees (Quaternion). |
Interval | Sends every N seconds (SyncRuleDefinition.interval). |
Sync Targets
| Enum value | Component | Property | Wire fields |
|---|---|---|---|
Transform_Position | Transform | position | x, y, z |
Transform_Rotation | Transform | rotation | x, y, z, w |
Transform_Scale | Transform | localScale | x, y, z |
Rigidbody_Velocity | Rigidbody | linearVelocity | x, y, z |
Rigidbody_AngularVelocity | Rigidbody | angularVelocity | x, y, z |
Usage Example
private void OnLogin(ApiEvent evt)
{
int myId = sfs.MySelf.Id;
// Local player — authority binding
var localPlayer = Instantiate(playerPrefab);
var binding = localPlayer.GetComponent<NetCrafterSyncBinding>();
binding.objectId = myId;
binding.hasAuthority = true;
// Remote players have hasAuthority = false and must have their
// objectId set before Start runs (before the object is activated).
}
Notes
NetCrafterSyncBinding.Startvalidates that aSyncRuleDefinitionand aNetCrafterSyncManagerare present. If either is missing, the component self-disables with aDebug.LogWarning.- Remote bindings (non-authority) subscribe to their rule via
NetCrafterSyncManager.SubscribeToSyncRule, which wires theNetCrafterEventDispatchercallback that routes payloads toApplyIncoming. ApplyIncomingisinternal— onlyNetCrafterSyncManagercalls it.- Sync callbacks receive a raw
ISFSObjectas the payload, unlike normal event callbacks which receive a deserialised typed event object.