---
title: Multi-screen multiplayer
slug: multi-screen-multiplayer
docTags: 
createdAt: 2024-07-31T11:25:39.738Z
---

:::BlockQuote
Prerequisites: API 1.9.0 or Unity Plugin 2.5.0 or higher
:::

## *Key concepts explained*

- An environment, as provided by AirConsole for the screen device, is a limited environment that the current screen is part of.
- A multi-screen multiplayer session is an online multiplayer session where AirConsole screens act as players in an online multiplayer game.
- The primary screen is the screen responsible for all decisions in an ongoing multi-screen multiplayer session.
- Secondary screens are additional screens in a multi-screen multiplayer session that have no responsibility and ability to make decisions.
- The primary controller is what you receive from the API using **getMasterControllerDeviceId()**.
- The primary multi-screen controller is the master controller of the primary screen.
- An environment defines a grouping of multiple screens that share one or more characteristics.
- An identifier in an environment enables the screen to identify the current (physical) environment they are in, like a specific car.
- A partner in an environment enables screens to identify other screens in a similar environment, for example the same brand of car.

## *Multi-screen multiplayer: What is it and how does it help us to make more engaging games?*

### *What is a multi-screen multiplayer game?*

A multi-screen multiplayer game in AirConsole is an online multiplayer game that uses additional information to

- enable matchmaking to allow screens in a single physical environment (a single car with multiple screens for example) to play together.
- enable matchmaking to allow screens on the same general environment (cars of a brand, web) to play together with a similar experience across multiple physical environments.

These new capabilities make it possible to create multiplayer games suitable for in-car entertainment that provide a comparable, fair experience to the different players.

### *How can my players play together on multiple screens in the same environment / car?*

To enable games to implement environment based multi-screen multiplayer gaming, AirConsole provides the **screen device** with information on the *environment* it is part of. This environment contains the so called *environment identifier* (**id**) that identifies the environment the screen is as uniquely as possible.

An example of such an environment can be a single car with one or more screens, which all share the same **id**.

To ensure reliability of multi-screen multiplayer game implementations created today, AirConsole always provides an *environment* with a valid **id** and **partner**.
For screens that are not part of a specific physical environment, an *environment* with a generic **id** and **partner** is provided. Players in this case would play against other screens purely online without being in physical proximity to each other.

### *How can the environment identifier be used to enable multiple screens in the same environment to play together?*

After the *environment* with its **id** is obtained on the web or in Unity, the game can use this information to identify waiting games from other screens in the same physical environment.

Example usages of the **id** would be:

- In a solution like [Photon Fusion](https://www.photonengine.com/fusion), the environment id can be used as the SessionName in the StartGameArgs to either start or join the same game session of this particular car.
- In a solution like [Photon Realtime](https://www.photonengine.com/realtime), the environment id can be used as the room name to either create or join the same room of this particular car.

This way, the game can ensure that only players in the same physical environment can play together, while those without a specific physical environment can play.

It is in this context simplest to think of a screen as a **group of players** that in the multiplayer context act like a single player. One of the screens, we call it *primary screen*, would be the *primary screen* that would be responsible to handle the configuration of the multi-screen multiplayer session. The *primary multi-screen controller* of this *primary screen* is in that sense the *primary controller* for the whole session, while the main controller of the *secondary screen* must not have any special rights.

### *How can the partner be used to improve multiplayer games?*

After the *environment* with its **partner** is obtained on the web or in Unity, the game can use this information as a grouping parameter to provide match making between devices of the same platform or car brand.


- In a solution like [Photon Fusion](https://www.photonengine.com/fusion), the **partner&#x20;**&#x63;an be used in SessionProperty in the [Matchmaking API through StartGameArgs](https://doc.photonengine.com/fusion/current/manual/connection-and-matchmaking/matchmaking) to either start or join games running on the same partner platform.&#x20;
- In a solution like [Photon Realtime](https://www.photonengine.com/realtime), the **partner&#x20;**&#x63;an be used in [OpJoinRandomRoomParams](https://doc.photonengine.com/realtime/current/lobby-and-matchmaking/matchmaking-and-lobby#filtering-room-properties-in-join-random) to enable random match making to only take place against other screens on the same partner platform.

## *Best Practices*

Best practice for multiplayer on multiple screens in the same environment / same car:

1. Query the multiplayer platform to see if a room / session with the same *environment&#x20;***id&#x20;**&#x61;lready exists.
2. When the query result is received:
   1. If a corresponding room / session exists, the screen should offer the option to join the other screen
   2. If no corresponding room / session exists, the screen should offer the option to start a multiplayer game in the car.
      In this case the screen starting the multiplayer would need to wait for the second screen to join and confirm their readiness before the multiplayer round starts.

Best practice for using the environment identifier and partner in multiplayer games:

- Unless there is a strong reason against it, always use the *environment* **partner** as
  - a grouping parameter in room / session creation
  - as a filter in match making

Together these will ensure that players on the same platform or car brand with similar performance metrics play together.

- when multi-screen multiplayer in a single physical enviroment is supported
  - use the *environment* **id&#x20;**&#x61;s room / session name
  - use the *environment* **id&#x20;**&#x74;o query for pending games in the same physical environment and join them

Best practice for handling screens and master controllers

- Only a single controller must be considered the *primary multi-screen controller&#x20;*&#x6F;f all screens after multiple screens are in the same session.
- Only the *primary screen&#x20;*&#x6D;ust be able to configure and control the multi-screen multiplayer session.
- When the *primary screen* leaves the multi-screen multiplayer session
  - one of the *secondary screens&#x20;*&#x6E;eeds to be promoted to become the *primary screen.*
  - only the new new *primary screen&#x20;*&#x6D;ust have the ability to end the multi-screen multiplayer session to continue on a single screen.
    In consequence the *master controller&#x20;*&#x6F;f the new *primary screen&#x20;*&#x61;lso becomes the new *primary multi-screen controller.*

## *How to access the environment information*

### *On the web*

```javascript
var partner = undefined;
var environmentId = undefined;
if (airconsole.devices[AirConsole.SCREEN].hasOwnProperty("environment") {
  var environment = airconsole.devices[AirConsole.SCREEN].environment;
  environmentId = environment.id;
  partner = environment.partner;
}
```

:::BlockQuote
var environmentId = undefined;
var partner = undefined;
var airconsole = new AirConsole(\{});

// somewhen later for example as you reach the multiplayer matchmaking part of your game
if (airconsole.devices\[AirConsole.SCREEN] && airconsole.devices\[AirConsole.SCREEN].hasOwnProperty("environment")) \{
&#x20; var environment = airconsole.devices\[AirConsole.SCREEN].environment;
&#x20; environmentId = environment.id;
&#x20; partner = environment.partner;
}
:::

You also get this through the **onDeviceStateChange&#x20;**&#x65;vent, checking for the sending device\_id === AirConsole.SCREEN and then accessing **device\_state.environment.id**. Be aware that the initial device state update might not yet contain the information, so always check if **device\_state.hasOwnProperty("environment")**.

:::BlockQuote
var airconsole = new AirConsole(\{});
airconsole.onDeviceStateChange = handleOnDeviceStateChanged;

function handleOnDeviceStateChanged(device\_id, device\_state) \{
&#x20; if (device\_id === AirConsole.SCREEN && device\_state.hasOwnProperty("environment")) \{
&#x20;   const \{ environmentId, partner } = device\_state.environment;
&#x20;   // do something with the partner and environmentId or do something with device\_state.environment itself.
&#x20; }
}
:::

### *In Unity*

:::BlockQuote
JToken deviceData = AirConsole.instance.devices\[AirConsole.SCREEN];
JToken environment = deviceData?\["environment"];
string partner = environment?\["partner"]?.ToString();
string environmentId = environment?\["id"]?.ToString();
:::

You can also get it from the onDeviceStateChange event

:::BlockQuote
AirConsole.instance.onDeviceStateChange += HandleOnDeviceStateChange;

void HandleOnDeviceStateChange(int device\_id, JToken device\_data) \{
&#x20; JToken environment = device\_data?\["environment"];
&#x20; string partner = environment?\["partner"]?.ToString();
&#x20; string environmentId = environment?\["id"]?.ToString();
&#x20; // do something with the partner and environmentId or do something with environment itself.
}
:::

