Multiplayer and Multi-host Testing

Learn how to build muti-player test scenarios using GameDriver

GameDriver supports multi-threaded and multi-host testing, which means you can control multiple instances of your application/game under test from a single test class. For example, you might have 3 game clients running in parallel, all controlled by the same test class where:

  1. Player 1 performs an action that triggers an event.
  2. Players 2 and 3 "see" that event in the form of displayed text or some other change.
  3. Player 2 or 3 can then take a subsequent action based on the result.

In a scenario like this, it makes sense to control all 3 players from a single test instead of 3 separate tests as it allows us to seamlessly pass information between the three clients. What this looks like from a test implementation perspective can illustrate the concept further.

// Initialize 3 separate ApiClients
ApiClient player1 = new ApiClient;
ApiClient player2 = new ApiClient;
ApiClient player3 = new ApiClient;

// Connect the ApiClients to 3 separate hosts
player1.Connect("192.168.100.1", 19734, false, 30);
player2.Connect("192.168.100.2", 19734, false, 30);
player3.Connect("192.168.100.3", 19734, false, 30);

// Do something on player1 and verify the results on players 2 and 3
player1.ButtonPress("Fire1", 100);
Assert.AreEqual(player2.GetObjectFieldValue("//*(@name='DamageCounter')/@counter"), player3.GetObjectFieldValue("//*(@name='DamageCounter')/@counter"));

As you can see in this simple example, it is possible to compare values across different tests, making automation for complex multiplayer scenarios easy to achieve.

Testing Multiplayer on Mobile builds

In the scenario above, we're connecting to 3 separate clients running on different machines. These could be Android mobile devices on the local Wi-Fi network or separate physical PCs, but if we're limited to testing on a single machine there are additional considerations and challenges. For example, a single Android device or emulator can be connected via USB using the Android Debug Bridge (ADB) command:

adb forward tcp:19734 tcp:19734

For iOS devices or simulators, use the equivalent iProxy command:

iproxy -l 19734:19734

However, if you need to connect multiple mobile devices these will need to connect over different ports to avoid conflict. To do this in ADB, simply specify the device you are connecting to using the -s flag, and specify a different internal port in the first argument for each device, such as:

adb -s 5c8b7e1e forward tcp:19734 tcp:19734
adb -s R5CR91RTK5R forward tcp:19735 tcp:19734
adb -s 21161FDF60051K forward tcp:19746 tcp:19734

In this example, we're connecting to 3 different devices on unique internal TCP port numbers. This will allow us to build the game using the standard configuration, and connect to each simply by modifying the port number used to connect in our test. Such as:

// Connect the ApiClients to 3 devices connected locally, but on different ports 
player1.Connect("localhost", 19734, false, 30);
player2.Connect("localhost", 19735, false, 30);
player3.Connect("localhost", 19736, false, 30);

The iProxy command has a similar method to specify the UDID of the connected device:

iproxy -u <UDID1> -l 19734:19734
iproxy -u <UDID2> -l 19735:19734
etc...

Testing Multiplayer on Standalone builds (PC/macOS)

The same concepts apply to testing standalone builds, except there are additional considerations when testing mobile applications. These additional considerations are:

  • Where the Standalone build is running - local or remote
  • Resource requirements for the standalone build: CPU, memory, GPU, storage, etc.
  • The build process

Local or Remote?

First, we cannot leverage tools like ADB and iProxy to direct network communications to specific instances of the running application or game. So additional steps will need to be taken to account for configuration when working on the same physical machine. This means each running instance of the Standalone build will need to be listening on a different port (19734, 19735, etc...). If the machines are remote, the port value can be kept default in the agent and the IP address or hostname of each machine used to connect. Be sure to configure firewall rules on each machine to allow the inbound connection.

To set the agent port manually for each build, use the GDIOAgent configuration dialog in the Unity editor:

In Unreal Engine, this port can be changed in the agent config file found under Plugins/UnrealCLR/gdio.unreal_agent.config.txt

Add the following line below the infobox line, and change the port number as needed.

<listening port="19734" />

To set the agent port programmatically, refer to this solution article.

Resource Requirements

The resource requirements for your game/application will greatly impact the decision of where to run standalone builds for multiplayer tests. If your build is relatively lightweight in terms of CPU, Memory, GPU, and storage speed/size requirements, it may be possible to run multiple instances on the same machine. However, it is not recommended as this will impact the performance and potentially the functionality in any case.

Virtualization may be useful here. However, it is important to note that your build may require dedicated GPU resources and this configuration may be difficult to get working as not all PCs support GPU virtualization. For more information, refer to your GPU, BIOS, and Virtualization software documentation.

The Build Process

Finally, you will need to consider the build process when deciding how best to set up for multiplayer testing. If any of the above considerations require you to modify the listening port of the agent, you may want to set that port number programmatically as outlined in this solution article using a script built into your project. This may require additional effort to coordinate builds and listening ports as they relate to the connected client/test.

The simplest approach is always to use a static port number in your build and deploy it to separate physical or virtual machines. This will allow you to use a single build across all of your tests, which is going to reduce the build process complexity.

Testing Multiplayer on XR

The process for testing multiplayer on XR devices is much the same as either Mobile or PC scenarios outlined above. The only additional consideration is what kind of platform(s) you intend to support. For standalone XR devices such as the Meta Quest 2/3, Pico 4, or the Vive XR Elite, the process should be very similar to that of a Mobile device running Android. For PC VR applications targeting SteamVR, the same considerations used for PC multiplayer should apply - even more so considering the GPU requirements for PC VR applications can be very high.