---
title: Construct
slug: construct
docTags: 
createdAt: 2024-06-27T10:55:57.706Z
---

In this guide you will learn how to use the Construct2 AirConsole plugin to add local multiplayer to your game.

:::BlockQuote
If you are new to AirConsole then you should read the [Getting Started Guide](https://developers2.airconsole.com/)
:::

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/YJ5ooYD5BGFOBsXCWKBv3_image.png)

Crystal Control - made with Construct2

### *Setup*

You can download the plugin files at our [airconsole-construct2](https://github.com/AirConsole/airconsole-construct2) github repository.

1. [Download](https://github.com/AirConsole/airconsole-construct2) the <font color="#eb144c">`airconsole.c2addon`</font> file on github.
2. Open Construct2.
3. Drag and drop the <font color="#eb144c">`airconsole.c2addon`</font> file into the Construct2 window.

### *Enable AirConsole*

To be able to use the AirConsole in a Construct2 game you have to add a new object type. You will find the AirConsole Plugin in the "Web" category.

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/90vccMsUMDqd0hVmo4Q40_image.png)

### *Conditions*

If you create a new event in an event sheet, then you will find the following condition options:

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/zS8CSgAyJj5lm3649sY7m_image.png)

**Conditions reference:**

| Name                         | Description                                                                                                                                                                    |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| On device custom state check | Triggered when a device custom state matches a value (E.g. when calling airconsole.setCustomDeviceState(\{key: value}) on a controller).                                       |
| On message                   | Triggered when a device sends a message (\{message: "your-value"}) to the screen and the device id matches                                                                     |
| On specific message          | Triggered when a specific message is received from a specific device.                                                                                                          |
| On message from              | Triggered when any message is received from a specific device.                                                                                                                 |
| On message key               | Triggered when a device sends a message (\{key: "your-value"}) and the key matches *(Use this if the sender device id does not matter - e.g. for an action to start the game)* |
| On device join               | Triggered when a device joins                                                                                                                                                  |
| On device left               | Triggered when a specific device disconnects                                                                                                                                   |
| On any device left           | Triggered when any device disconnects.                                                                                                                                         |
| On too many players          | Triggered when max players is exceeded.                                                                                                                                        |
| OnPause                      | Triggered to pause the game. Pause should also pause any audio.                                                                                                                |
| onResume                     | Triggered to resume the game again.                                                                                                                                            |

### *Actions*

The following actions are available:

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/xoNi40kZZWpx5c0SzyEda_image.png)

**Actions reference:**

| Name                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Broadcast data          | Sends a message to all connected devices                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Send data               | Sends a message to a specified device id                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Game ready              | Sends a message to all devices that the game is ready (**Use this always on game start!**).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Set custom device state | Sets the screen-device custom state (Same as calling airconsole.setCustomDeviceState(\{key: value}) in the API).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Set active players      | Takes all currently connected controllers and assigns them a player number. Can only be called by the screen. The assigned player numbers always start with 0 and are consecutive. You can hardcode player numbers, but not device\_ids. Once the screen has called setActivePlayers you can get the device\_id of the first player by calling convertPlayerNumberToDeviceId(0), the device\_id of the second player by using ConvertPlayerNumberToDeviceId(1). You can also convert device\_ids to player numbers by using ConvertDeviceIdToPlayerNumber(device\_id). You can get all device\_ids that are active players by using GetActivePlayerDeviceIds(). |
| Show ad                 | Show ad on every connected controller and screen. onAdComplete is called when showing ad is over                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

### *Expressions*

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/srSjkBrT7fGMFiTnV0GtF_image.png)

Update December 2022:

| Name           | Description                                                                                |
| -------------- | ------------------------------------------------------------------------------------------ |
| GetLanguage    | Gets the language ISO Code (E.g. 'en', 'es')                                               |
| GetTranslation | Gets the [translation](http://localhost:8080/#!/guides/translations) for a translation-key |

You can find more about expressions in [this tutorial](https://www.scirra.com/tutorials/9415/airconsole-little-expression-guide).

### *Properties*

| Max players      | Sets the maximum amount of players the game can handle. (All other players who join after that should get a message like "Game is full") |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Use translations | Set to True if your game uses translations and you want to load them                                                                     |

### *Method examples*

Look at some of the examples on how to use the methods.

**ControllerDeviceIds**

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/YIVgPCEOmJyExHHNLvzQG_image.png)

**MasterControllerDeviceID**

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/d1GDSeV5in6ie3tjVGl19_image.png)

**ActivePlayerDeviceId**

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/PWeGrMUyJCpCro1B7pCYs_image.png)

**Storage**

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/T6bW_8vvwvqPqCbjkcHVS_image.png)

### *Connect screen with controllers*

For a usual HTML5 game we would normally just wait for the screen.html to load and then handle the devices. With Construct2 we have to wait for the entire game to initialize, because we are "talking" with AirConsole in the Construct2 context.

**Construct2 game ready event - Asking "who is here?"**

Simply call the<font color="#eb144c">`AirConsole.GameReady`</font>action once as soon as the game has started. This will broadcast a message to every already connected controller with the data<font color="#eb144c">`{ handshake: true }`</font>.

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/2zLORGOPdQIFZAvuH0YAS_image.png)

**Code in controller.html - Replying "me is here"**

The controller listens for the<font color="#eb144c">`{ handshake: true }`</font>data in the<font color="#eb144c">`onMessage`</font>method:

```html
<script type="text/javascript" src="https://www.airconsole.com/api/airconsole-1.9.0.js"></script>
<script type="text/javascript">
  var air_console = new AirConsole();

  var sendHandshake = function() {
    air_console.message(AirConsole.SCREEN, {
      handshake: true
    });
  };

  air_console.onReady = function() {
    sendHandshake();
  };

  // Let the screen know we are here
  air_console.onMessage = function(device_id, data) {
    if (data.handshake) {
      sendHandshake();
    }
  };
</script>
```

The controller will send a message back to the screen and trigger<font color="#eb144c">`AirConsole.onDeviceJoin`</font>events in Construct2, which you will also have to add. :)

### *Controller messages*

To send a message from a controller to the screen you have to stick to certain keys in the JSON data you send, so that the Construct2 plugin knows which condition you want to trigger.

| Key                                      | Type         | Description                                                             |
| ---------------------------------------- | ------------ | ----------------------------------------------------------------------- |
| <font color="#eb144c">`handshake`</font> | *\<Boolean>* | Send this as soon as the game is loaded and to register the controller. |
| <font color="#eb144c">`key`</font>       | *\<String>*  | Applied to the AirConsole.MessageKey expression                         |
| <font color="#eb144c">`message`</font>   | *\<String>*  | Applied to the AirConsole.Message expression                            |

**For example**

:::BlockQuote
&#x20;   \<script type="text/javascript" src="**https\://www\.airconsole.com/api/airconsole-1.9.0.js**">\</script>
&#x20;   \<script type="text/javascript">
&#x20;     var air\_console = new AirConsole();
&#x20;     // ...
&#x20;     air\_console.message(AirConsole.SCREEN, \{
&#x20;       **key**: "show\_main\_menu"
&#x20;     });

&#x20;     air\_console.message(AirConsole.SCREEN, \{
&#x20;       **message**: "move\_left"
&#x20;     });
&#x20;   \</script>
:::

### *Export your game*

Export the game as a usual HTML5 game. AirConsole will request a<font color="#eb144c">`/screen.html`</font>, which is why you should rename the<font color="#eb144c">`index.html`</font>into<font color="#eb144c">`screen.html`</font>. And of course, don't forget to create a<font color="#eb144c">`controller.html`</font>in the same directory, which includes the functionality for the controllers.

As soon as your game is ready make a zip file of the whole directory (screen.html and controller.html in the root) and [publish](https://developers2.airconsole.com/publishing-your-game) it on AirConsole.

### *Example Pong Game walktrough*

To show you how all of this works together we will go through our example (very basic) pong game.

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/5ThcPRBZ9Qb4nfrQNbAo4_image.png)

[Play example](https://www.airconsole.com/simulator/#!play=com.demo.construct)

Download Game: [https://github.com/AirConsole/airconsole-construct2/tree/master/example\_project](https://github.com/AirConsole/airconsole-construct2/tree/master/example_project)

**Event sheet**

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/5iJRhPufAj9HEUJaCMK0i_image.png)

**Trigger the GameReady Event**

As mentioned before, you **ALWAYS&#x20;**&#x68;ave to trigger a Game ready event when the game has loaded, so that the controllers can tell us they are there.

![](https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/6JB7yHJzmcM6_hlsUIKVm_image.png)

**Store and assign device\_ids**

Every controller owns a paddle-sprite. Which means if controller-2 presses the up-button, then we want the right paddle to move up. That means we have to know which device belongs to which sprite. We can achieve this by creating global vars for each device the game will support (In pong two global vars, because we will just have two players in our game).

::Image[]{src="https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/nrs3utCqLzHW6f5Mgplar_image.png" size="50" width="310" height="269" position="center" showCaption="false"}

If the first controller connects "On device join", then we assign the joined AirConsole.device\_id to the global DeviceID1\_Move. The second devices which connects get assigned to DeviceID2\_Move.

:::BlockQuote
**Device\_ids are random&#xA;**&#x54;he value of DeviceID1 does not have to be always "1". The device with another device\_id (2, 3, 6, ...) could join before the device\_id 1.
:::

**Device joins, set the device\_id**

With the condition<font color="#eb144c">`AirConsole.onDeviceJoin`</font>we can listen for events when a new device joins. If device joins, then assign the global variable device\_id to the value of<font color="#eb144c">`AirConsole.DeviceIDJoin`</font>.
The tricky part here is to have the order of devices which join in mind. This means the first player who joins should be assigned to DeviceID1. The second player should be the DeviceID2. Consequently we also have to check if the DeviceID1 already has a value. If yes, we check if the DeviceID2 var has none and if that is true we assign the device\_id.

**Move paddles**

To move our paddles we create another two global vars called<font color="#eb144c">`DeviceID1_Move`</font>and<font color="#eb144c">`DeviceID2_Move`</font>. Each of them can have one of the 3 values:

- -1 = Move up
- 0 = Stop
- 1 = Move down

**Send a message from a controller to the screen**

Our controller will only consist of two buttons: move up and move down. If we press one of this buttons we will send a message to the game (screen) and the corresponding paddle-sprite object should move - or if we release a button it should stop.

Our<font color="#eb144c">`controller.html`</font>contains the following code:

```html
<button id="up">MOVE UP</button>
  <button id="down">MOVE DOWN</button>

  <script type="text/javascript" src="https://www.airconsole.com/api/airconsole-1.9.0.js"></script>
  <script type="text/javascript" src="//code.jquery.com/jquery-3.1.1.min.js"></script>
  <script type="text/javascript">

    var airconsole = new AirConsole();

    // Let the screen know we are here
    var sendHandshake = function() {
      airconsole.message(AirConsole.SCREEN, {
        handshake: true
      });
    };

    airconsole.onReady = function() {
      sendHandshake();
    };

    airconsole.onMessage = function(device_id, data) {
      if (data.handshake) {
        sendHandshake();
      }
    };

    $("#up").on('touchstart', function () {
      airconsole.message(AirConsole.SCREEN, {
        message: 'up'
      });
    });

    $("#down").on('touchstart', function () {
      airconsole.message(AirConsole.SCREEN, {
        message: 'down'
      });
    });

    $("#up").on('touchend', function () {
      airconsole.message(AirConsole.SCREEN, {
        message: 'stop'
      });
    });

    $("#down").on('touchend', function () {
      airconsole.message(AirConsole.SCREEN, {
        message: 'stop'
      });
    });

  </script>
```

Now the game has to listen to a message which has the content "up", "down" or "stop".

In our event sheet, you can see two events of "On receive message data". They were added by the <font color="#eb144c">`AirConsole.onMessage`</font> event like this:

::Image[]{src="https://api.archbee.com/api/optimize/eODGJqzvP6Walum1Gn5N9/3wpOSrlwpIa5WHC1U4MNd_image.png" size="80" width="586" height="240" position="center" showCaption="false"}

To sum it up:
**IF&#x20;**&#x6D;essage == "up" AND device\_id matches the value of DeviceID1 **THEN&#x20;**&#x77;e set the variable<font color="#eb144c">`DeviceID1_Move`</font>to -1, which means our sprite moves down.

The same happens with message == 'stop' or message == 'down'.

### *External Tutorials*

- [HowTo: Construct2 and AirConsole](https://laurentchervet.wordpress.com/2016/11/30/howto-construct2-and-airconsole/)
- [Construct 2 and AirConsole](https://www.scirra.com/tutorials/9414/construct-2-and-airconsole)
- [Little expression guide](https://www.scirra.com/tutorials/9415/airconsole-little-expression-guide)

### *Troubleshooting*

**Game won't work because of Javascript errors**

If you get any javascript errors try to export your game without checking the "Minify script" checkbox.
