Hello

Using Unity with Playroom Kit

🧪

The Unity SDK currently only supports Unity Web. This is an experimental technology.

Unity is the most popular game engine, it's also a great way to make web games thanks to the WebGL export option (opens in a new tab).

Playroom Kit complements Unity by simplifying the development of multiplayer games and interactive web-based applications.

Getting started

Video Tutorial

1. Install the SDK

  1. Download playroomkit.unitypackage from the releases page (opens in a new tab) (download playroomkit.unitypackage file).
  2. Drag the package into your Unity project and import all files.
  3. Open terminal, navigate to your project directory, and run:
cd Assets/PlayroomKit
npm install

This will install the required dependencies for the SDK.

2. Initialize Playroom

In your game's Start method, call PlayroomKit.InsertCoin:

using Playroom;
 
void Start() {
    PlayroomKit.InsertCoin(new PlayroomKit.InitOptions()
    {
        maxPlayersPerRoom = 2,
        defaultPlayerStates = new() {
            {"score", -500},
        },
    }, () =>
    {
        // Game launch logic here
    });
}

3. Manage game state

Use PlayroomKit.SetState and PlayroomKit.GetState to handle game state. These automatically sync with other players.

See the API reference for more information.

4. Export to WebGL

  1. Go to File > Build Settings and select WebGL as the platform.
  2. In Player Settings:
    • Set Resolution and Presentation > Run In Background to true.
    • Change WebGL Template to PWA (or to Discord, if you want to publish to Discord Activities).
    • Set Compression Format to None under Publishing Settings (this is to make sure the build works with most web servers including itch.io).
  3. Build your game.
  4. Test locally using python -m http.server in the build folder.

Do note that PlayroomKit for Unity only works with WebGL builds.

Testing your games

Mock Mode

Since the current SDK only supports Unity Web, we've introduced Mock mode - a way to test out your game's logic in Unity's Preview mode, without having to build for web every single time.

1. Local (simulated)

The "Local" mock mode doesn't connect to the actual Playroom server. Instead, it just mocks the API calls within Unity, and maintains a local state.

The "Local" Mock mode only works in single player mode for now. We aim to make it multiplayer by Q4.

✅ Pros👎 Cons
Super fastThere may be inconsistencies
Not much setup, lightweightCan't benchmark network load/bandwidth
Can work offlineDoesn't have multiplayer (yet), single-player only
No impact on Playroom bill

2. Browser Bridge (live)

Status: Beta

This mode connects to a live, multiplayer Playroom server. It will make real network calls, but to do so, it will launch a controlled browser (to run the underlying network calls).

✅ Pros👎 Cons
Live on Playroom servers, testers can join in from live gamesTakes time to set up
Completely accurate according to productionNetwork dependent (can't develop offline)
It will eat up your Playroom bill

Which one should I use?

  1. Start with Local mock mode for:
  • Initial project setup
  • Testing new features/algorithms
  • Rapid iterations
  1. Progress to Browser Bridge mock mode for:
  • Realistic testing scenarios
  • Multiplayer functionality
  • Network performance evaluation
ℹ️

Remember that both mock modes in the Unity Editor approximate the final WebGL build. Some differences may occur due to the underlying C++ and JS compilation in the web environment.

Multiple Player testing

Status: Beta

The PlayroomKit for Unity plugin includes a "Playroom Dev Manager" panel for multi-instance testing and ease-of-use:

Playroom Dev Manager

To test with multiple players:

  1. Ensure the latest version of the PlayroomKit plugin (opens in a new tab) is installed.
  2. Open the Playroom Dev Manager panel in Unity.
  3. Click "Launch player" to create a new Unity Editor instance.
  4. Repeat step 3 for additional player instances (limited by your computer's resources).

This feature uses ParrelSync (opens in a new tab) Unity Editor to create multiple Unity Editor clones, each representing a different player.

🧠

Tip: Use this method to simulate various multiplayer scenarios and test synchronization between players without deploying your game.

By utilizing both Mock Modes and the Multiple Player testing feature, you can thoroughly test your game's multiplayer functionality and performance within the Unity environment before proceeding to a full WebGL build.

Examples

Check out some simple and advanced use cases!

Simple Example

Use WASD or Arrow keys to move the player around. The player's position is synced with other players in real-time.

Code for this example can be found here (opens in a new tab).

Beanz: Discord Activity Demo

Once built, this demo works on both WebGL in the browser, and in Discord Activities.

Code for this example can be found here (opens in a new tab).

API Reference

See the API reference for more information.

FAQ

How to display player's profile picture in Unity?

PlayroomPlayer.GetProfile().photo is formatted as data:image/svg+xml,{svg encoded for url}. In order to display it in Unity:

  • Remove data:image/svg+xml from the string.
  • Decode the rest using HttpUtility.UrlDecode()
  • Display the result into an SVGImage component.

Warning: Requires Unity's Vector Graphics package from com.unity.vectorgraphics, which is an experimental package.

 private void LoadSVG(string svgBytes) {
    // Split the string to escape the real data
    svgBytes = svgBytes.Split(",".ToCharArray(), 2)[1];
    // Decode from the URL encoding
    svgBytes = HttpUtility.UrlDecode(svgBytes);
    VectorUtils.TessellationOptions tesselationOptions = new VectorUtils.TessellationOptions();
 
    using (StringReader reader = new StringReader(svgBytes))
    {
        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(reader);
        tesselationOptions.MaxCordDeviation = float.MaxValue;
        tesselationOptions.MaxTanAngleDeviation = float.MaxValue;
        tesselationOptions.StepDistance = 1f;
        tesselationOptions.SamplingStepSize = 0.1f;
 
        List<VectorUtils.Geometry> geoms =
        VectorUtils.TessellateScene(sceneInfo.Scene, tesselationOptions);
 
        // Build a sprite with the tessellated geometry.
        Sprite sprite = VectorUtils.BuildSprite(geoms, 100.0f, VectorUtils.Alignment.Center, Vector2.zero, 128, true);
        sprite.name = "SVGimage";
        profilePicture.sprite = sprite;
    }
}

Thanks to Zy from our Discord for this tip.

How to maintain an array of Players in Unity?

You can manage a list of players in Unity to track their state and perform actions on them simultaneously. Here’s how to use OnPlayerJoin (opens in a new tab) and Player.OnQuit (opens in a new tab):

object[] players = Array.Empty<object>();
 
PlayroomKit.OnPlayerJoin((player) => {
  players.push(player);
  player.OnQuit(() => {
    Debug.Log($"{player.id} quit!");
    players = players.Where(p => p != player).ToArray();
  });
});

This is similar to the PlayroomKit JavaScript SDK's usePlayersList hook (opens in a new tab).

How to do physics over the network?

1. Is it possible to achieve deterministic physics in Unity for networking?

Deterministic physics in Unity can be quite challenging to achieve due to the nature of the physics engines it uses. Unity uses PhysX for 3D physics and Box2D for 2D physics, both of which are deterministic by themselves. However, achieving determinism in a game involves more than just the physics engine being deterministic. For example, using the Rigidbody component in Unity has a property called Interpolate that affects how visuals are interpolated, which can cause differences between transform.position and rigidbody.position. This can lead to non-deterministic outcomes. For more details, you can check Unity's documentation on Rigidbody interpolation (opens in a new tab).

2. What are the conditions required for deterministic physics?

To achieve deterministic physics, all inputs (forces, impulses) must be applied to the same objects at the same time across all clients. Any delay in applying these inputs, even by one timestep, can lead to different results. This means that automatic updates of the physics engine in Unity should be disabled, and you should control these updates manually to ensure consistency. You can learn more about this in Unity's documentation on Physics.Simulate (opens in a new tab) and the article on Fix Your Timestep (opens in a new tab) by Gaffer On Games.

3. What is floating-point determinism, and why is it important?

Even if you manage to achieve deterministic physics in Unity, floating-point determinism is another hurdle. Different machines with different architectures may calculate floating-point numbers slightly differently, which can cause variations in physics simulations when networking. This can lead to desynchronization across clients. For more information, see the article on Floating Point Determinism (opens in a new tab) by Gaffer On Games.

4. What approach did the developers of Soccer Party use for networking physics?

Given the complexities of achieving deterministic physics, the developers of Soccer Party (opens in a new tab) decided not to rely on it. Instead, they opted to frequently send position and velocity updates for rigid bodies, and even rotation data in some cases. Their focus shifted to optimizing the size and frequency of these messages rather than ensuring deterministic physics. This approach also requires solutions for handling synchronization issues, such as what to do when objects get out of sync, how to avoid these issues, and how to prevent players from noticing them.

These excerpts come from conversations with an active Discord member, GuilhermeAlanJohann.

Aurea NetLayer: a higher level API for Unity

GuilhermeAlanJohann from our Discord community has created a higher level plugin (opens in a new tab) for Unity that makes it easier to use Playroom with Unity.

Features

  • Sync position and rotations of objects over the network (supports interpolation)
  • Different object authorities (Host and LocalPlayer)
  • Spawn/Unspawn objects over the network
  • Send Messages to others (including or excluding yourself)
  • RPC (...kind of). It uses Unity message system.