Just from memory (which is usually poor) the developer of the MMO Starter KIT did a stress test early on and got up to 168 (I think.) players. That was one dedicated server. I’m not sure if at that time he had the separate chat server that he has now. The info is still in that thread. The number could have been as high as a couple of hundred, but its still really low.
Edit: found where I asked
We’re trying to design around the concept of 500 to 1000 simultaneous players. There is another project called OWS (Open World System?) here on the forums that offers a package that handles backend data and multiple dedicated server management, but I’ve only watched it from afar.
Two of the current significant MMORPG efforts, Ashes of Creation and Chronicles of Elyria, are using Unreal. AoC is writing their own server code (according to their comments) and CoE is using SpatialOS (several dozen custom C++ workers.) Neither has demonstrated anything resembling finished gameplay, though AoC has shown some nice environments and some live footage that might show a client connected to a server, but this is not clear.
If you turn the server’s FPS down to 1 per second, and disable any physics calculations, it should be able to handle a couple hundred users.
Either way, if I’m correct it should then only do the bare minimum of what a multiplayer game needs (just location/rotation/velocity replication of users).
Any other network solution should do this as well, meaning that it shouldn’t offer a performance benefit over the Unreal server solution (unless the Unreal servers are inefficient in what they do, and other solutions are more efficient, but I doubt that would make a huge difference).
Anyway, you should test to see how low you can get your servers to run (FPS wise etc) for your game to still work, then see if you would be able to support enough users with that.
Posting here in the hopes that someone might have experience with VPSs and socket servers.
We’ve been using the Socket plugin and java server on our local network to connect to our MySQL db (also on our local network) and we have begun experimenting with moving both db and socket server to the internet.
Adding our db to one of the web hosts that we have proved to be rather simple and we have successfully tested the connection between a socket server running on one of our local machines and the hosted MySQL db. All of the location, inventory, & etc data for a test character was retrieved without a hitch.
In order to keep costs low during these experiments, we rented a Windows Server 2012 VPS for a month to host the java socket server. (In hindsight, this was apparently overkill.)
The first problem that we encountered was that Port 7780 is already in use in the Windows Server installation.
We changed the java socket server port to 7788 and this allowed the jar file to run in the command prompt on the Windows server VPS, but our first attempts to connect have failed and we are looking for suggestions.
One thing that we thought of was that a Linux VPS would have been more suitable for our purposes as we only want to run the java file. It also occurred to us that the usage that we want might require a dedicated server with full access to all of the hardware.
We’re planning on more experiments in the near future but will be trying to gather more information in the meantime to reduce the amount of trial and error.
Any hints, suggestions, comments, or other that anyone might have would be very much welcome.
What I use for my demo game is DigitalOcean (a Debian server of $5/month). Just install Oracle’s Java JRE and MySQL (or PostgreSQL etc), and install several things like UFW+IPtables (firewall, allows you to block all ports except your socket server port) and fail2ban (blocks IPs that try to brute-force your SSH login).
Besides that, you should probably also change your SSH port to something else (lots of bots try to bruteforce your SSH on port 22 and 23).
Anyway, I also suggest placing the database on the same server as the socket server, and then not allowing remote login into the database, this way it will be more secure and it will have far less latency between the socket server and the database server (since it will just use local sockets then).
All in all, getting things running well and secure on a linux server requires some experience/knowledge. You can either spend time on this yourself to look things up and to get good at this (which is what I did, took about ~3 months to get the hang of it), or you could again hire someone for that.
Know that by default, your server probably isn’t secure (SSH port is set to the default, there’s no brute force protection, there’s no firewall blocking access to things like telnet and your database, etc), so there’s quite some work to do when it comes to securing your server.
Also, servers usually have a (low) limit on how many open socket connections (called file handlers or something like that) that the server can have at the same time, this is something that you want to be increasing as well.
Lastly, servers usually don’t have swap space (memory on the ssd/hdd), so if you run out of memory, applications will crash. So swap space is something that you’ll have to create yourself as well (create a file, mount it, then use it as swap space).
Anyway, I’ve added the scripts I’ve executed on my demo game servers in the attachments. The most important is what’s in “01 secure and optimize”, everything else is just an example of how to install, run and manage your servers.
Some info:
The servers use Debian 8
“01 secure and optimize” is about securing your server (SSH etc) and removing the socket limit and such
“02 monitoring” adds a webserver with which you can access files and see the performance of the server online (my java servers log some information in text files, I’ve make a symlink of these files to the webserver so I can access these logs easily online)
“03 backend - main” is the installation of a new service I’m currently working on (this hasn’t been made public yet, it’s still in development)
“03 games - server 001 - *” are the installations of the servers for my demo game, so that’s the main server, game servers and bots, pretty much everything in there is just to make it easier for me to execute actions that I’ve programmed in the java servers for this game, like adding a user and such
Thanks once again for your excellent suggestions. We have the java server running on the VPS (changed to Debian) and everything is working in our basic tests. We have a lot more work to do, including implementing the security measures & etc, but this has been very encouraging.
Awesome, once you get something working you’ll get the hang of it quite fast, the hardest thing is finding something that works (there’s a lot of outdated install guides online, so it’s really trial and error when it comes to that).
Also, about that, if you’re going to try out something new, it’s usually good to make a snapshot (in DigitalOcean) first, that way if anything goes wrong, you can always rollback to the snapshot.
-edit-
Ah I forgot to tell you three more things:
It’s the easiest to read the server scripts with notepad++ and by then setting the “Syntax” (top of screen) to “Batch”.
If you try out something new, not only always make a snapshot before you do so, but also copy paste every command you do in a file (like I did with my server scripts), that way you can easily check back later and see what exactly you did (I didn’t do this at first, several months later I had to make some changes to a server, that’s when I realized I made a big mistake by not writing down exactly what I did, I basically had to look everything up again then which was a real pain).
When you start a new server, it’s a race against the clock when it comes to safety. From the second your server is live, there will be bots trying to bruteforce your SSH login. When I created my first ever server I didn’t know much about server security, well, my server got bruteforced and had malware installed on it within 4 days or so. The only reason I knew about it was because DigitalOcean noticed lots of outgoing messages from my server (the mallware turned my server into another bruteforce bot), and because of that, DigitalOcean shut down my server and send me a message about it. I then ran a virus-scanner (ClamAV) and then I noticed the malware. I threw away the server at that point and started from scratch again, this time with SSH bruteforce protection installed (fail2ban).
Well, you could use the LE File Manager plugin to read the content of the file as a string, and then just split the string (with , as the delimiter) into an array (the blueprint for this is called “Parse Into Array”).
Edit: Also, you might want to split the content string with a
delimiter first, this way you will have an array of lines. Lastly, don’t forget to trim each line though, in case of \r’s.
So, in short:
Read File (bytes) -> Convert Bytes to String (you can use the LE Extended Standard Library plugin for that) -> Split String (
as delimiter,
can be found in the LE Extended Standard Library plugin as well) -> For Each loop -> Trim String -> Split String (, as delimiter) -> now you have your comma separated values
Websockets add some overhead to each packet you send, they also don’t allow UDP packets. Why would you want to use websockets instead of normal sockets?
Sorry for dredging this up but it references my current learning effort. We need to connect to an instance of the LE java server from a C# program (login) and I have been studying sockets in C#. I have some example code running and I am trying to understand the exact sequence of bytes that I must stream to make a connection for a function call.
As it appears to me currently, the stream of bytes should be:
1st byte: value of 2 for FUNCTION_CALL
1-4 bytes (int32): a generated function call ID - Will a random value, i.e. 1234, be suitable or is there a defined format?
1-4 bytes (int32): length of packet (the following byte array)
uint8]: packet, a byte array (my message)
Going to try to build this above in C# and see if it makes a connection.
The function call ID will just be returned by the server. The function call ID is meant to tie a package to an identifier, so you know what you’re receiving. For example, if you would send two function calls to the server, then you will get two responses back, but you will have no idea of what response is what.
The UE4 client just sends an increasing integer to the server as the function ID (so 1, 2, 3, etc, till MAX_INT, where it is set to 1 again).
Also, the 1-4 bytes int works like this:
If the value is 127 or lower, it will send a single byte, otherwise it will send 4 bytes and set the highest bit (the signed bit) of the first byte to 1.
I would just create an application with Java if possible, that way you can just use the library, but if you really want to implement the protocol yourself, take a look at the following classes (inside the Java library):
classes/sockets/SocketConnection.java - this is where the client’s sending code is located
classes/sockets/SocketConnectionHandler.java - this is where the client’s receiving code is located
classes/sockets/SocketFunctions.java - here is the 1-4 byte int code
You could also take a look at the plugin code instead (Source/LowEntrySocketConnection/Private/Classes/LowEntrySocketConnection.cpp, especially at the OnConnect() function).
Raw sockets allow you to have UDP-only connections now.
Well, ‘connections’, since UDP doesn’t have a connection, it just sends and receives data to/from a given port.
To use it you should use the new create socket connection blueprint, which is called something like “Create Socket Connection (Raw) (UDP Only)”.
Edit:
By the way, I always try to keep the ‘normal’ socket’s network protocol the same, if anything changes in that protocol then the changes will also have to happen in the Java library as well (since the Java library contains both the server-side as well as the client-side of the protocol).