This document is about: SERVER 5
SWITCH TO

Plugins API Changelog

Photon Plugins are available only for Enterprise Cloud or self-hosted Photon Server.

This page lists the changes to the public plugins API (PhotonHivePlugin.dll), newest version first. For a walkthrough of the larger changes introduced in Photon Server 5 see What's New.

How Plugins API Versions Work

The plugins API version has the format major.minor.patch. It is the version of the API, not of Photon Server: the plugins API versions listed here apply to Photon Server 5.x (.NET Framework, net471) and 6.x (.NET, netcoreapp3.1), which use the same API. The Plugins SDK contains a build of PhotonHivePlugin.dll for each of the two runtimes. The assembly version of PhotonHivePlugin.dll has a fourth number, the build number, for example 1.5.0.xxxxx.

The server loads a plugin only if it was built against the same major version and a minor version that is not higher than the server's. Only the major and minor numbers are compared. If the build number (the fourth number) of the plugins API the plugin was built against is higher than the server's, a warning is logged, but the plugin is still loaded. This means:

  • A plugin built against an older minor version keeps working on a newer server.
  • A plugin built against a newer minor version than the server's can't be loaded: the server logs "Plugins version mismatch" and rooms can't be created or joined. Update your server (or private cloud) first, then deploy the plugin.
  • A new major version means every existing plugin must be rebuilt.

The minor version is increased for a release that adds or changes API. The patch version is increased for a single small addition. It is not checked when the plugin is loaded.

You can read the version your plugin was built with and the version of the running server using IPluginHost.GetEnvironmentVersion() (EnvironmentVersion.BuiltWithVersion and EnvironmentVersion.HostVersion).

Versions 1.2.0 to 1.4.0 were assigned afterwards to intermediate builds. Those builds were all stamped 1.1.0. If you built a plugin against a Photon Plugins SDK that reports 1.1.0 and use any of the members added in 1.2.0 to 1.4.0, it was built against one of these intermediate builds.

New members on interfaces that the server implements (IPluginHost, IFactoryHost, IPluginLogger, IPluginFiber, IOperationRequest, IHttpResponse, IPluginWorkerHost) only affect code that implements those interfaces itself, such as test doubles.

Version Date Notes
1.5.0 2026-08-20 Current.
1.4.0 2026-04-22 Intermediate version.
1.3.0 2025-09-25 Intermediate version.
1.2.0 2025-05-16 Intermediate version.
1.1.0 2025-01-23 Baseline of this changelog.

1.5.0

Date of the last API change: 2026-08-20.

Breaking

  • IGamePlugin.OnRawMessage(IOnRawMessageCallInfo) was added. Classes that implement IGamePlugin directly must implement it. PluginBase and PluginBase2 already do.
  • IDisconnectCallInfo was removed.

Only affects code written against 1.3.0 or 1.4.0:

  • IOnRawMessageCallInfo.Data (IRawMessageData) was replaced by RawMessageData RawMessageData.
  • InboundControllerSetup was removed.

Added

  • Raw messages, together with IGamePlugin.OnRawMessage above:
    • RawMessageData ref struct with GetClientData() and ClientDataLength.
    • IPluginHost.RawMessageDataAllocator.
    • IPluginHost.BroadcastRawMessage(...) and IPluginHost.SendRawMessage(...), with overloads taking RawMessageData or IRawMessageData.
  • Async on the room fiber: IPluginFiber.CurrentSynchronizationContext, IPluginFiber.SetSynchronizationContext(PluginSynchronizationContext, bool setForCurrentThread) and the PluginSynchronizationContext class.
  • Environment: the static Environment class (AppIdKey, AppVersionKey, CloudKey, RegionKey, GetAppId, GetAppVersion, GetCloud, GetRegion) and IFactoryHost.Environment.
  • Tagged loggers: IFactoryHost.CreateLogger(name, tags) and IPluginWorkerHost.CreateLogger(name, tags).
  • IHttpResponse.GetErrorInfo(): returns details about a failed request, ready to pass to a logger.

Changed

  • PluginFactoryBase.SetFactoryHost is virtual again, now as an empty hook. IPluginFactory2.SetFactoryHost is implemented explicitly: it stores the factory host, calls the hook, then calls OnFactoryHostSet. Calling SetFactoryHost directly on a PluginFactoryBase no longer stores the factory host.

1.4.0

Date of the last API change: 2026-04-22.

Breaking

Only affects code written against 1.3.0:

  • PluginFactoryBase.SetFactoryHost is no longer virtual (it is virtual again in 1.5.0).

Added

  • Factory lifecycle:
    • IPluginFactory3 : IPluginFactory2 with HostReleased().
    • IFactoryHost.InitializationFinished(bool success = true, string errorMessage = null).
    • PluginFactoryBase implements IPluginFactory3 and adds a virtual OnFactoryHostSet(FactoryParams), a virtual HostReleased() and a protected virtual SetupPlugin(...). Create(...) is now virtual.
  • WebFlags.Parse(string input, out string error): combines flag names separated by |, , or ; (case-insensitive) into one value. Unknown names are reported in error.

Behavior

  • For factories that implement IPluginFactory3, the server waits until the factory calls IFactoryHost.InitializationFinished. If that doesn't happen within PluginManagerInitializationTimeout (30 seconds by default), plugin initialization fails. PluginFactoryBase.OnFactoryHostSet makes the call by default, so an override must call the base method or call InitializationFinished itself.

1.3.0

Date of the last API change: 2025-09-25.

Breaking

  • PropertyBag size overloads take (int KeySize, int ValueSize) instead of KeyValuePair<int,int>: SetProperty(key, value, sizes), SetProperties(values, out changed, metaData) and SetPropertiesCAS(values, expectedValues, ref valuesChanged, out debugMessage, metaData). Set(key, value, sizes) still takes KeyValuePair<int,int>?.

Added

  • Room size: GameParameters.MaxPlayersInt (243) and GameParameters.DirectMode (244) property keys, and SerializableGameState.MaxPlayersInt.
  • Plugin base split: PluginBaseImpl holds the shared implementation. PluginBase now derives from it and keeps the same members. New PluginBase2 with a public virtual ReportError(short errorCode, Exception e, object state = null). GetPluginInfo() is now protected.
  • Operation requests: IOperationRequest.AddRef(), Release(), RequestSize, GetParameterSize(byte) and GetParamSubKeySizes(byte, object).
  • ActorNr on ICreateGameCallInfo and IBeforeJoinGameCallInfo, set after Continue().
  • Log-count guards: IFactoryHost.CreateLogCountGuard(TimeSpan, int msgCount = 1), IPluginHost.LogDebug, LogInfo, LogWarning, LogError and LogFatal overloads taking an ILogCountGuard, and 25 IPluginLogger overloads that take an ILogCountGuard first.
  • Experimental, replaced or removed in 1.5.0: IOnRawMessageCallInfo with IRawMessageData Data, PluginBaseImpl.OnRawMessage (never called, because IGamePlugin didn't declare it yet) and InboundControllerSetup.

Changed

  • PluginFactoryBase.SetFactoryHost is virtual.
  • PhotonHivePlugin.dll now depends on Photon.Plugins.Common.dll, which holds ILogCountGuard and the raw-message types. Reference it when using those types, and deploy it with your plugin.

Behavior

  • HttpRequest is a [DataContract]. Only Url, Method, Accept, ContentType, Headers, CustomHeaders, Async, Timeout and RetriesCount are serialized. Callback, DataStream, UserState and ServerCertificateValidationCallback are not.
  • The server no longer calls OnLeave for actors the plugin was never told had joined or created the room, and OnCloseGame can't be called twice.

1.2.0

Date of the last API change: 2025-05-16.

Added

  • Counters: ICounter (Increment(), Decrement(), IncrementBy(long), Value setter) and IPluginHost.GetCounter(string counterName, string category = null, string instance = null).
  • HttpRequest.RetriesCount: number of retries after the first attempt, so at most 1 + RetriesCount requests are sent.
  • HttpRequest.ServerCertificateValidationCallback and the RemoteCertificateValidationCallback delegate, for a custom TLS certificate check per request.

1.1.0

Date of the last API change: 2025-01-23.

Baseline for this changelog. It already includes the plugin worker API (IPluginWorker, IPluginWorkerHost, PluginWorkerBase), HttpRequest.Timeout, IBeforeJoinGameCallInfo.Defer() and the full LeaveReason error code set.

Last updated on

Back to top