
描述
Load-testing a dedicated server at realistic player counts is hard, and the bottleneck is
almost always the clients rather than the server.
A UE dedicated server is not a conventional game server. The engine's networking is a world
of its own — its own handshake, its own replication model, its own serialisation — which makes
it impractical to simulate from the outside. A bot that speaks the wire protocol directly means
reimplementing a large and version-sensitive part of the engine, and getting it subtly wrong
means measuring something that is not your game. That leaves the obvious route: launch a lot of
real clients. At the scale where the numbers start to mean anything, that stops being a software
problem and becomes a hardware one — a process, often a whole machine, per simulated player.
RealNetRobot takes the other option. It drives many simulated players from inside a single
headless client process, each connecting to a dedicated server named on the command line, each
going through real login and whatever gameplay follows.
Robots are NOT server-side AI bots. Every robot owns its own UWorld, UGameInstance, ULocalPlayer
and UNetDriver, and goes through the same handshake, replication and RPC paths a real player's
client does. That is the point: the server cost you are trying to measure lives in those paths.
WHAT IT SAVES
Memory, a lot — assets load once per process instead of once per client, so a fleet costs roughly
one client + N x (world + actors) instead of N x one client.
CPU, barely — N worlds still tick serially on one game thread. Past the per-process ceiling, add
processes rather than robots.
FEATURES
- N headless clients per process, each with a real connection to the dedicated server
- Per-robot world isolation, so robots do not share state
- Per-robot identity injected through the connect URL (UserId, RoleId, or anything your login
path reads), since UniqueNetId is process-wide
- Traditional streaming sublevels supported, including wire-level level visibility
- World Partition runtime cells supported from a packaged build
- Staggered joins, so the fleet ramps instead of bursting
- Command line, console and Blueprint/C++ control; the command path works in Shipping
- Inert on install — nothing happens until you ask for robots
- Ships with a demo map and a task-oriented user guide
PLEASE READ BEFORE BUYING
Three limits, stated up front rather than discovered later:
1. You drive the robots yourself. There is no behaviour framework and no base class to inherit.
The plugin exposes two queries (IsRobotWorld, GetRobotIndex) and you hang your own driver off
them — only your project knows its own input API. An undriven fleet measures a floor, not a
load.
2. World Partition maps with runtime cells need the optional engine class installed and must run
from a packaged build. Uncooked one-file-per-actor data caps the fleet at one robot and cannot
be worked around — the engine asserts before any plugin code runs. The plugin detects this and
says so rather than failing silently.
3. Identity travels in the connect URL, not through UniqueNetId. Your login path has to read
identity from the URL, or robots past the first will not log in distinctly.
Also: there is no metrics export. Results come out as log lines plus a fleet summary call.
Tested on UE 5.5.4, Win64, against both editor-launched and packaged dedicated servers.