I’ve specifically coded a ‘minimal/headless client’ like that for unit testing (can connect multiple clients from within a single UE4 instance - minimizing overhead/memory-usage), which you can access in *UE4\Engine\Plugins\NetcodeUnitTest* - though it will require some adjustments for you to be able to make it launch multiple clients to the same server, as currently it is setup to launch a single headless client per server.
The primary code for that is in ClientUnitTest.cpp - that class basically encapsulates a single ‘headless client’ - and the easiest method for you to achieve what you want, may be to create 1 unit test class which launches a server and connects a headless client, and then code a 2nd unit test class, which does not launch a server, but instead connects another headless client to the existing server (it would require a big refactoring to get it all working within one unit test - which I will do in the future).
See ‘FTextCrash.cpp’ in Engine\Plugins\NetcodeUnitTest\NUTUnrealEngine4 for a unit test which launches a server and then connects a minimal client - you can use this as a template for the first unit test.
When the first unit test launches the server, the ‘ServerAddress’ variable will contain the address for the server - ‘ExecuteClientUnitTest’ in the first unit test, could be implemented to launch 31 instances of the second unit test class, using:
GEngine->Exec(NULL, TEXT(“UnitTest SecondUnitTestName”));
Then the second unit test class (which should leave out ‘EUnitTestFlags::LaunchServer’ from UnitTestFlags) can - in ‘ExecuteClientUnitTest’ - assign its ServerAddress value to the address of the first unit test, and then you can call ‘ConnectFakeClient’ to connect the minimal/headless client to that address.
Once all of this is done, you can run it using the commandline:
UE4Editor.exe YourGame -run=NetcodeUnitTest.UnitTestCommandlet -unittest=FirstUnitTestName
This unit test tool is recently public, yet still very much ‘in development’, and implementing in the above manner is untested/unsupported, so it may take a bit of messing to get this going - but let me know how you get on, and if it proves useful/difficult ![]()