This document is about: QUANTUM 3
SWITCH TO

Setup

Installation

  1. (Windows only) Unblock Photon-Quantum-X.X.X.Plugin-SDK.zip by right-click > Properties > Unblock before unzipping it.
  2. Unzip the archive into a folder inside or next to the Quantum Unity project (Quantum tools will auto-detect the location).

MyQuantumProject
├─Assets
├─Library
├─..
└─PluginSDK
    
Or

MyQuantumProject
├─Assets
├─Library
└─..
PluginSDK
    
  1. (Running local Photon Server) Download and copy a Photon Server license from the Photon dashboard into the Photon.Server/bin folder. PS: only Circle membership owners have access to the license file.
  2. The custom plugin projects target net10.0 (Plugin SDK 3.0: netcoreapp3.1), install the matching .NET SDK.

Testing The Server Plugin

  • Open the Quantum.Plugin.Custom.sln in Visual Studio or Rider, set the Quantum.Plugin.Custom.Stock as start-up project and ignore that other project may fail to compile;
  • Press F5 to start the Photon-Server;
  • Open the game server log file under Photon.Server\log\GSGame.log;
  • Open the Unity project, select PhotonServerSettings.asset and press the Local Name Server button;
  • Start an online game using the Quantum Menu.

Testing Server Simulation

  • Select and configure the QuantumDotnetProjectSettings asset in Unity
    • Add include paths to all simulation code or Qtn-file folders or mark the folders with the QuantumDotnetInclude Unity asset label;
    • Simulations folder for example are Assets\Photon\QuantumAsteroids\Simulation;
  • Select the QuantumDotnetBuildSettings asset and press Detect Plugin SDK. If this fails, set the folder (that contains the Photon.Server folder) manually;
  • Select the QuantumDotnetBuildSettings asset and press Sync (or use Tools > Quantum > Export > Plugin SDK - Sync Server Simulation). This step builds the non-Unity simulation dll and exports the Quantum Unity DB:
    • Libraries to the Lib folder;
    • Assets to Photon.Server\Plugins\QuantumPlugin3.1\bin\assets;
Quantum 3.1
Quantum 3.0

  • Open the Quantum.Plugin.Custom.sln in Visual Studio or Rider;
    • Set the Quantum.Plugin.Custom.Sample.ServerSimulation project as the start-up project;
    • Press F5 to start the Photon-Server;
    • Open the game server log file under Photon.Server\log\GSGame.log;
  • Alternatively press Start on the QuantumDotnetBuildSettings asset to build the selected plugin project and launch the Photon Server from Unity;
  • Open the Unity project, select PhotonServerSettings.asset and press the Local Name Server button;
  • While selecting the PhotonServerSettings.asset change the Auth Mode to Auth Once;
  • Start an online game using the Quantum Menu.
Auth Once
Auth Once

SDK Content

Lib Folder

The Lib folder includes the Quantum dependencies required to compile and run the Quantum Photon Server plugin. Quantum.Deterministic.Plugin.dll, Quantum.Deterministic.Server.dll and Quantum.Deterministic.Server.Interface.dll are the main libraries of the Quantum plugin. Quantum.Engine.dll and Quantum.Log.dll are usually replaced by the libraries of the custom simulation build (from Unity), which also adds Quantum.Simulation.dll.

The Photon Server plugin interfaces PhotonHivePlugin.dll and Photon.Plugins.Common.dll are referenced from Photon.Server/LoadBalancing/Master/bin (Plugin SDK 3.0: copied into the Lib folder).

Photon.Server Folder

The folder includes the local Photon Server. The bin folder has the Photon.Server executables, LoadBalancing and NameServer has the server code and Plugins has the server plugins. The log folder contains the server logs (e.g. the game server log GSGame.log).

The plugin configuration file LoadBalancing\GameServer\bin\plugin.config includes the local configuration key value store that online servers get from the Photon Dashboard.

The custom plugin libraries will be outputted to Plugins\QuantumPlugin3.1\bin. This is also the folder that is uploaded to the Photon Enterprise cloud in the end.

Quantum.Plugin.Custom.* Folders

These folders contain sample projects for a custom Quantum plugin (see next section).

Upgrading The Photon Server

The Upgrade-Server.ps1 script upgrades the local Photon Server inside Photon.Server with a downloaded Photon Server Plugin SDK zip (e.g. Photon-OnPremises-Server-WInterop-Plugin-SDK_v6-0-19-36800.zip) or with the Photon Server of a newer Quantum Plugin SDK zip. It does not upgrade the Quantum Plugin SDK itself (Lib folder, projects), to do that unzip the new Quantum Plugin SDK manually.

PowerShell

.\Upgrade-Server.ps1 -ZipPath C:\Users\Username\Downloads\Photon-OnPremises-Server-WInterop-Plugin-SDK_v6-0-19-36800.zip
  • Stop all running PhotonServer processes before running the script.
  • The script backs up Photon.Server into %TEMP%, replaces its files with the server files of the zip (deploy_win of a Photon Server Plugin SDK, Photon.Server of a Quantum Plugin SDK) and restores the license file (bin/*.license) and LoadBalancing/GameServer/bin/plugin.config.
  • The Photon.Server/Plugins folder is not touched.
  • On any error Photon.Server is restored from the backup. Add -RemoveBackup to delete the backup after a successful upgrade.
  • Zips and installations with the old 3.0 layout (Photon.Server/deploy_win) are refused.

Plugin Samples

The Quantum.Plugin.Custom.sln comes with multiple sample projects. Select one as a start-up project to be able to start it with F5.

Selecting a Project
Selecting a Project

See in the launchSettings.json how F5 will start a Photon Server:

Quantum 3.1
Quantum 3.0

JSON

{
  "profiles": {
    "Quantum.Plugin.Custom.Sample.ServerSimulation": {
      "commandName": "Executable",
      "executablePath": "$(ProjectDir)/../Photon.Server/bin/PhotonServer.exe",
      "commandLineArgs": "--run LoadBalancing --config PhotonServer.config",
      "workingDirectory": "$(ProjectDir)/../Photon.Server/bin"
    }
  }
}

JSON

{
  "profiles": {
    "Quantum.Plugin.Custom.Sample.ServerSimulation": {
      "commandName": "Executable",
      "executablePath": "$(ProjectDir)/../Photon.Server/deploy_win/bin/PhotonServer.exe",
      "commandLineArgs": "--run LoadBalancing --config PhotonServer.config",
      "workingDirectory": "$(ProjectDir)/../Photon.Server/deploy_win/bin"
    }
  }
}

The shared csproj file Quantum.Plugin.Shared.csproj.include is used in each project to support basic integration tasks like:

  • Referencing the Quantum libraries from the Lib folder and the Photon Server plugin libraries;
  • Copying the output to the destination folder: Photon.Server\Plugins\QuantumPlugin3.1\bin;
  • Copying the plugin.config from the SDK root folder to the Photon Server;
  • Zipping the plugin to prepare for Photon Cloud upload;
  • Checking for a license file.

Stock Sample

This sample is a blank slate which only consists of a custom DeterministicPluginFactory which is responsible to instantiate the required DeterministicPlugin. It will just instantiate the unmodified base plugin object.

Quantum 3.1
Quantum 3.0

C#

public override DeterministicPlugin CreateDeterministicPlugin(IPluginHost gameHost, String pluginName, Dictionary<String, String> config, ref String errorMsg) {
  return new DeterministicPlugin();
}

C#

public override DeterministicPlugin CreateDeterministicPlugin(IPluginHost gameHost, String pluginName, Dictionary<String, String> config, IPluginLogger logger, ref String errorMsg) {
  return new DeterministicPlugin();
}

HTTP Sample

In some situations, you may need to query an external service to get some information or to perform some action (such as giving a player's account rewards).

Different to the stock sample this sample includes a plugin factory that creates custom plugin and server classes called QuantumCustomPlugin and QuantumCustomServer.

The sample shows how to override the create game and player joined callbacks OnCreateGame and BeforeJoin. Both defer the continuation until a HTTP request to a custom backend was completed.

The sample demonstrates how to override OnDeterministicCommand() to perform a HTTP request when a player sends a command, then discards the command. The HTTP response is used to enqueue the command back into the session by calling SendDeterministicCommand()

Commands Sample

This sample shows how to intercept, modify or discard commands sent by clients in a custom DeterministicServer. It creates a session factory with runServerSimulation: false to get access to the command serializer of the session context, see Quantum Server API.

Server Simulation Sample

This sample shows how to enable server simulation on the Quantum server.

To compile this project all steps from the section Testing Server Simulation have to be completed first.

The classes required to run the simulation come from the Quantum.Simulation assembly built from Unity using the QuantumDotnetBuildSettings. The QuantumJsonSerializer is used to serialize and deserialize the AssetDB.

Quantum 3.1
Quantum 3.0

Override CreateSessionFactory() and return a ServerSessionFactory object with minimal configurations: assetSerializer and runServerSimulation. The ServerSessionFactory creates the session context and the ServerSessionRunner that runs the simulation.

C#

public override IDeterministicSessionFactory CreateSessionFactory() =>
  // We want to run server simulation (DeterministicServer.SessionRunner) and have to pass a session factory here.
  new ServerSessionFactory(
    assetSerializer: new QuantumJsonSerializer(),
    runServerSimulation: true);

public override DeterministicPlugin CreateDeterministicPlugin(IPluginHost gameHost, string pluginName, Dictionary<string, string> config, ref string errorMsg) => 
  // Create a default plugin with a custom server to test events and callbacks
  new DeterministicPlugin(new QuantumCustomServer());

The server requires to be started with session context and session runner instances. The DotNetSessionRunner is a simple implementation of the IDeterministicSessionRunner interface that allows the Quantum simulation to be run outside of Unity.

C#

public override DeterministicPlugin CreateDeterministicPlugin(IPluginHost gameHost, String pluginName, Dictionary<String, String> config, IPluginLogger logger, ref String errorMsg) {
  // The session context is required for the `DotNetSessionRunner` and it will make resource manager and command serializer accessible.
  var sessionContext = new DotNetSessionContext {
    AssetSerializer = new QuantumJsonSerializer()
  };

  // The session runner is responsible for running the game simulation. The class `DotNetSessionRunner` is located inside the Quantum SDK Unity project.
  var sessionRunner = new DotNetSessionRunner { 
    AssetSerializer = new QuantumJsonSerializer() 
  };

  return new DeterministicPlugin(new DeterministicServer(sessionContext, sessionRunner));
}

Events and Callbacks from Server Simulation

It is possible to, from the custom plugin, react to Events (defined and triggered in the simulation code) and Callbacks by subscribing to the EventDispatcher and CallbackDispatcher of the session runner.

Quantum 3.1
Quantum 3.0

Subscribe in a custom DeterministicServer when the session starts. SessionRunner is null when the server simulation is disabled.

C#

public class QuantumCustomServer : DeterministicServer {
  public override void OnDeterministicStartSession() {
    // SessionRunner is null when the server simulation is disabled (dashboard, percent, failed start)
    if (SessionRunner is ServerSessionRunner sessionRunner) {

      // Subscribe to callbacks
      sessionRunner.CallbackDispatcher.Subscribe<CallbackGameStarted>(this, c => Log.Info("Game Started"));

      // Subscribe to events
      sessionRunner.EventDispatcher.Subscribe<EventFoo>(this, OnEventFoo);
    }
  }

  private void OnEventFoo(EventFoo foo)  { }
}

Subscribe to the dispatchers of the DotNetSessionRunner created in the plugin factory.

C#

private void SubscribeToEvents(DotNetSessionRunner sessionRunner) {
    var eventDispatcher = (EventDispatcher)sessionRunner.EventDispatcher;

    eventDispatcher.Subscribe<EventFoo>(this, OnEventFoo);
}
    
private void OnEventFoo(EventFoo foo) {
    // Do something with the event
}

private void SubscribeToCallbacks(DotNetSessionRunner sessionRunner) {
    var callbackDispatcher = (CallbackDispatcher)sessionRunner.CallbackDispatcher;

    callbackDispatcher.Subscribe<CallbackGameStarted>(this, c => Log.Info("Game Started"));
}

Further Readings

The Quantum custom plugin is based of Photon-Server V5 and follows the workflow described in the Photon Server docs. Dive into these docs for further reading: Photon-Server V5 Manual

To upload the plugin to the Photon Enterprise cloud the following tutorial is helpful: Enterprise Plugin Setup

Last updated on

Back to top