Skip to content

C# Client API

The C# API allows developing multiplayer games and applications for all major operating systems and platforms via Unity, Godot or native .Net.

The API is distributed as a set of DLL libraries targeted at each specific development platform. The DLLs include the main API, the Audio API and a few more dependancies for the latter. XML files are also provided for IntelliSense support.

Download the API zip file from the SmartFoxServer website and extract the folder corresponding to your platform of choice, then follow the instructions below.

API documentation

Consult the API Doc

Main API

The main API exposes all classes needed to interact with SmartFoxServer from your client.

.Net

Copy the following files to your project:

  • SmartFox3.DotNet.dll
  • SmartFox3.DotNet.xml

Then edit the project's .csproj file to add a reference to the API library:

<ItemGroup>
    <Reference Include="SmartFox3.DotNet">
        <HintPath>SmartFox3.DotNet.dll</HintPath>
    </Reference>
</ItemGroup>

Files can also be placed in a subfolder of your project; if you do, adjust the path in the snippet above accordingly.

Thread-safe mode

When developing native applications/games for .Net, always remember to set the API's configuration value ConfigData.ThreadSafeMode to false explicitly! The default true value requires an event queue processing thread, like in Unity or Godot.

Godot

Copy the following files to your project:

  • SmartFox3.DotNet.dll
  • SmartFox3.DotNet.xml

Then edit the project's .csproj file to add a reference to the API library:

<ItemGroup>
    <Reference Include="SmartFox3.DotNet">
        <HintPath>SmartFox3.DotNet.dll</HintPath>
    </Reference>
</ItemGroup>

Files can also be placed in a subfolder of your project; if you do, adjust the path in the snippet above accordingly.

Unity

Editor and non-WebGL builds

Copy the following files to your project's Assets/Plugins/ folder:

  • SmartFox3.Unity.dll
  • SmartFox3.Unity.xml

In Unity's Project tab select the .dll file, then go to the Inspector tab and under Exclude Platforms check the WebGL option. Finally click on the Apply button.

Unity inspector

WebGL builds

In addition to the Unity Editor setup described before, create the Assets/Plugins/WebGL/ folder and copy the following files in it:

  • SmartFox3.Unity_WebGL.dll
  • SmartFox3.Unity_WebGL.jslib

Unity automatically applies the platform-specific default settings to the files based on their path. It will use the DLL in the Assets/Plugins/ folder when working in the Editor, and the other libraries in the Assets/Plugins/WebGL/ folder when building the project for the web.

Unity inspector

Multi-platform projects

If you need to build the same Unity project for both WebGL and non-WebGL platforms, you will need a bit of conditional compilation in your code. The reason is that the WebGL build connects to SmartFoxServer via websocket, while all the other builds connect via regular socket connection. Also, different ports are used to communicate with the server.

The following code snippet shows how to use websocket protocol when configuring the SmartFox class instance before establishing a connection.

var cfg = new ConfigData();
...
#if UNITY_WEBGL
    cfg.UseWebSocket = true;
#endif

Audio API

The audio API adds audio streaming capabilities to the SmartFox client. Although the audio-related requests and interfaces are included and documented in the main API, their actual implementation is distributed as a separate DLL and a few dependancies.

The API is currently compatible with Windows (x86-64) and macOS (Universal Binary). More operating systems will be added as development progresses.

UDP protocol

Although not strictly necessary, we recommend using the UDP protocol for audio streaming. If enabled, it is automatically detected by the audio API and used for audio data transmission. Check this document for more information.

The audio API can be configured by means of the ConfigData.AudioCfg class.

.Net

Copy the following files to your project; the native libraries to include depend on the target operating system/s of your build:

  • SmartFox3.DotNet.Audio.dll
  • Concentus.dll
  • audioengine.dll and libspeexdsp-1.dll (native Windows libraries)
  • libaudioengine.dylib and libspeexdsp.dylib (native macOS libraries)

Then edit the project's .csproj file to add a reference to the API library and dependancies:

<ItemGroup>
    <Reference Include="SmartFox3.DotNet.Audio">
        <HintPath>SmartFox3.DotNet.Audio.dll</HintPath>
    </Reference>
</ItemGroup>

<ItemGroup>
    <Reference Include="Concentus">
        <HintPath>Concentus.dll</HintPath>
    </Reference>
</ItemGroup>

<!-- macOS native libraries -->
<ItemGroup>
    <None Include="libaudioengine.dylib;libspeexdsp.dylib" CopyToOutputDirectory="PreserveNewest" Link="%(Filename)%(Extension)"/>
</ItemGroup>

<!-- Windows native libraries -->
<ItemGroup>
    <None Include="audioengine.dll;libspeexdsp-1.dll" CopyToOutputDirectory="PreserveNewest" Link="%(Filename)%(Extension)"/>
</ItemGroup>

If you placed the DLLs in a subfolder of your project, adjust the paths in the snippet above accordingly.

Godot

Copy the following files to your project:

  • SmartFox3.DotNet.Audio.dll
  • Concentus.dll

Then edit the project's .csproj file to add a reference to the API library and managed dependancy:

<ItemGroup>
    <Reference Include="SmartFox3.DotNet.Audio">
        <HintPath>SmartFox3.DotNet.Audio.dll</HintPath>
    </Reference>
</ItemGroup>

<ItemGroup>
    <Reference Include="Concentus">
        <HintPath>Concentus.dll</HintPath>
    </Reference>
</ItemGroup>

If you placed the DLLs in a subfolder of your project, adjust the paths in the snippet above accordingly.

Now, according to the target operating system/s of your build, copy the following files to the root folder of your project:

  • audioengine.dll and libspeexdsp-1.dll (native Windows libraries)
  • libaudioengine.dylib and libspeexdsp.dylib (native macOS libraries)

Then again edit the project's .csproj file to add a reference to the native dependancies:

<!-- macOS native libraries -->
<ItemGroup>
    <None Include="libaudioengine.dylib;libspeexdsp.dylib" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>

<!-- Windows native libraries -->
<ItemGroup>
    <None Include="audioengine.dll;libspeexdsp-1.dll" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>

In Godot, you have two audio modes available:

  • Embedded Audio (default)
    Based on the open-source, cross-platform, audio playback and capture library MiniAudio. Allows configuring the capture and playback sample rate.

  • Godot Native Audio
    Based on Godot's audio engine, uses dedicated audio bus and audio streams. Audio stream player type can be configured and handled internally by the API or passed to the application to be attached to nodes for spatial audio. Requires a predefined sample rate and specific configuration of the Godot's project.

Both modes offer full control on the capture and playback devices selection at runtime and support audio devices hot-plugging. They also integrate Audio Echo Cancellation and Automatic Gain Control through the system-native, open-source library SpeexDSP, and automatic pitch-shifting for delay compensation.

Whatever the selected mode is, when exporting the project always give it permissions to access the microphone in the configured export presets.

Embedded Audio

This audio mode is enabled by setting the ConfigData.AudioCfg.UseEmbeddedAudioLib parameter to true (default).

Native Audio

This audio mode is enabled by setting the ConfigData.AudioCfg.UseEmbeddedAudioLib parameter to false. This mode requires the sample rate (ConfigData.AudioCfg.SampleRate parameter) to be changed to 48 kHz. Also, in Godot's Project Settings, go to General, enable the Advanced Settings and under Audio > Driver check Enable Input and set the Mix Rate to 48000.

Godot project settings

In this mode, the audio API needs to instantiate and interact with classes belonging to Godot's audio engine, to capture and play audio. Since the SFS API internal threads cannot directly access Godot's scene tree and most engine APIs, we need to call those APIs in Godot's primary execution thread, which continuously runs the game loop. In order to do so, an empty Node must be passed to the IAudioManager.SetSceneObject() method right after the SFSAudioEvent.INIT event is fired by the SFS client.

In some scenarios, you may need to associate specific audio streams to specific scene objects. For example, in a 3D environment where players move around and can talk to each other, each user avatar should have its own audio stream attached in order to obtain positional sound effects, like distance attenuation and directionality. This can be achieved by instructing the API to expose the AudioStreamPlayer object created internally by means of the ConfigData.ExposeAudioAsset parameter (set to true). The object will be passed to the SFSAudioEvent.STREAM_ADD event listener when a new stream from a client is started.

In this case, the type of AudioStreamPlayer is relevant (2D, 3D or non-positional). Again, you can instruct the audio API to use a specific type by means of the ConfigData.GodotStreamPlayerType setting.

Unity

Experimental API

In Unity, the audio API is still experimental due to Unity's API compatibility level still limited to .Net Standard 2.1. Due to this and other Unity constraints, the API has the following limitations:

  • Embedded Audio mode (see Godot > Embedded Audio above) currently disabled.
  • WebGL builds not yet supported (Unity doesn't natively support microphone in WebGL).
  • Audio Echo Cancellation and Automatic Gain Control not supported.
  • Automatic pitch-shifting for delay compensation not supported.
  • No playback devices selection available at runtime.
  • Audio devices hot-plugging not supported.
  • Noticeable delay in audio stream playback (approx. 1 second).

Copy the following files to your project's Assets/Plugins/ folder together with the main API:

  • SmartFox3.Unity.Audio.dll
  • Concentus.dll
  • audioengine.dll and libspeexdsp-1.dll (Windows only)
  • libaudioengine.dylib and libspeexdsp.dylib (macOS only)
  • Link.xml

In Unity, you currently have a single audio mode available:

  • Unity Native Audio
    Based on Unity's audio engine, uses a dedicated audio source.

When exporting the project, always give it permissions to access the microphone in the player settings.

Native Audio

This audio mode is enabled by setting the ConfigData.AudioCfg.UseEmbeddedAudioLib parameter to false.

In this mode, the audio API needs to instantiate and interact with classes belonging to Unity's audio engine, to capture and play audio. Since the SFS API internal threads cannot directly access Unity's scene tree and most engine APIs, we need to call those APIs in Unity's primary execution thread, which continuously runs the game loop. In order to do so, an empty GameObject must be passed to the IAudioManager.SetSceneObject() method right after the SFSAudioEvent.INIT event is fired by the SFS client.

Basic example

The following is a simple .Net client that connects to SmartFoxServer running on the local machine:

public class SFS3Connector
{
    private SmartFox? sfs;

    public SFS3Connector()
    {
        // Create SmartFox instance
        sfs = new SmartFox();

        // Configure client
        var cfg = sfs.Config;
        cfg.Host = "localhost";
        cfg.Zone = "Playground";
        cfg.ThreadSafeMode = false;

        // Set up event handlers
        sfs.AddEventListener(SFSEvent.CONNECTION, OnConnection);
        sfs.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
        sfs.AddEventListener(SFSEvent.LOGIN, OnLogin);
        sfs.AddEventListener(SFSEvent.LOGIN_ERROR, OnLoginError);

        Console.WriteLine("SFS API version: " + sfs.Version);

        // Connect to server
        sfs.Connect();
    }

    // ----------------------------------------------------------------------
    // Event Handlers
    // ----------------------------------------------------------------------

    private void OnConnection(ApiEvent evt)
    {
        bool success = (bool?)evt.GetParam(EventParam.Success) == true;

        if (success)
        {
            Console.WriteLine("Connection successful");

            // Login as guest
            sfs?.Send(new LoginRequest());
        }
        else
            Console.WriteLine("Connection failed; is the server running?");
    }

    private void OnConnectionLost(ApiEvent evt)
    {
        string? reason = (string?)evt.GetParam(EventParam.DisconnectionReason);

        Console.WriteLine("Connection lost; reason is " + reason);
    }

    private void OnLogin(ApiEvent evt)
    {
        User? user = (User?)evt.GetParam(EventParam.User);

        Console.WriteLine("Logged in as " + user.Name);
    }

    private void OnLoginError(ApiEvent evt)
    {
        string? errorMsg = (string?)evt.GetParam(EventParam.ErrorMessage);

        Console.WriteLine("Login error: " + errorMsg);
    }
}

Exernal configuration

In order to configure the client, you can use the ConfigData.Load method. It loads an external configuration file that overrides the values of the configuration settings. The file must contain a name=value pair per line. Use dot notation for nested properties (i.e. BlueBox.IsActive=true). Lines starting with # are skipped.

This is the modified version of the example above:

// Create SmartFox instance
sfs = new SmartFox();

// Configure client
sfs.Config.Load("config.dat");

// Set up event handlers
...
Host=13.36.166.18
Zone=Playground
ThreadSafeMode=false