Author
Topic: More players on network games? (Read 765 times)

Hi, sorry if the question appears to be a little stupid. Actually simutrans handles 15 players, that are not really 15 cause you have public service, observer account and so on... The question is: would it technically be so hard to handle more than 15 players in a game? What are the limitations (bandwidth, desynch, RAM on the server...) ?

The limti is rather because the storage used for player is 4 bit. One could extend this, but this would make each object 4 bytes larger, so it woudl increase the memory footprint a lot. (But then I think the image is now also 32 bit, so we would have 16 bit free for use now).

I think the praktical problems (keeping that many players in sync and now all the time be bothered by joining and leaving) might be the biggest hurdles.

On the not so technical side, I suspect coming up with more distinct player colors might also be a challenge.

That's technically solved already due to secondary player colors. Even if the 28 colors available are not always clearly destinctive, 784 color pairs should be more than enough. Granted, it's not really in use, but if it was required, it could be.

Yes, "could be". It is hard enough getting artists to use the primary player color. I'm not sure I've ever seen a vehicle using the secondary one. Even in pak64, where the maintainer does care about player colors. (Most vehicles are from before that, though.)

I think the praktical problems (keeping that many players in sync and now all the time be bothered by joining and leaving) might be the biggest hurdles.

One would need a better save/load system so that game state after load is the same as time of save. The sync issue is easy to solve, in theory, by using barrier frames that stop clients from passing the server (how RTS games are synced).

Yes, but the saveload issue is not easy to solve. And usually download on top of server save/client load is usually takinjg longer than the local saveload. So in any case the pause for the already joined players is the same.

And there are five engines with dual player colors in pak64 ... (but the second is mostly only a line or so).

Yes, but the saveload issue is not easy to solve. And usually download on top of server save/client load is usually takinjg longer than the local saveload. So in any case the pause for the already joined players is the same.

The main problem is that every time a client joins, the players are interrupted which can be annoying if players are frequently connecting.

In theory one could allow the server to passively save, background transfer the save file to a new client and then that client can load in and fast forward up to the server. For simple server maps the join process might be completely invisible to the clients.

Another approach would be to get rid of heavy clients. All calculations are done on the server and the server streams the results, or an approximation of them, to the clients based on what they need. This is more scalable and solves the save/load problem. However this would need major engine changes.

Another approach would be to get rid of heavy clients. All calculations are done on the server and the server streams the results, or an approximation of them, to the clients based on what they need. This is more scalable and solves the save/load problem. However this would need major engine changes.

It is possible that separating logic and presentation might solve problems both for network games and for doing hardware accelerated rendering. The biggest problem for the former is that the client will need lots of updates if the player has zoomed far enough out.

So let me understand: when a player joins a network game the server stops the game and all clients have to wait until the server pushes the game to the client that has just connected, in order to maintain synchro between all clients?

The limti is rather because the storage used for player is 4 bit. One could extend this, but this would make each object 4 bytes larger, so it woudl increase the memory footprint a lot. (But then I think the image is now also 32 bit, so we would have 16 bit free for use now).

I think the praktical problems (keeping that many players in sync and now all the time be bothered by joining and leaving) might be the biggest hurdles.

I imagine 4-bits data type is not used for all data structures (arrays, pointers or whatever you use), am I wrong? Wouldn't it be enough changing data type of the structure that holds companies list and related data?

I imagine 4-bits data type is not used for all data structures (arrays, pointers or whatever you use), am I wrong?

Technically there is no 4 bit data type as the smallest unit of memory most systems can read/write is 1 byte (octet, char). Some times one packs multiple values using a bitfield to increase memory density (cache performance) but decrease processing performance (cannot read the value directly, has to extract it using bit operations).

Quote

Wouldn't it be enough changing data type of the structure that holds companies list and related data?

If the code was properly written it would be. The problem is that it is more than likely that there are dozens, possibly hundreds, of scattered constants and hardcoded pieces of code that expect there to be at most 16 players.

The main issue is there might be a non-trivial performance regression due to worse caching. Also save files would likely be larger due to more possible unique values, and changing the save format would be non trivial due to how scattered it is.

It is a great shame that people use hard-coded numbers instead of defined constants with such frequency in this code, as it would have made a huge difference to how easy that such a feature is to implement. A good start might be to look for all occurrances of the numbers "15" and "16" as complete strings (rather than parts of strings), and change the code in that vicinity to refer instead to the MAX_PLAYER_COUNT defined constant.

An initial run finds relevant use of the numbers 15 and 16 at:

api_param.ccline 499line 520line 511

network_socket_list.hline 96line 98line 99

We also have some possibly suspicious code that I have not been able fully to parse owing to heavy bitwise operations in bool money_frame_t::action_triggered():

Searching for all instances of player_nr and get_player_nr() produces a good number of relevant results, too.

Note also that the player number is represented as an unsigned 8-bit integer in some places, e.g. line 948 of network_cmd_ingame.cc (but I do not imagine that this will be a difficulty, as 255 players will be far more than enough in any event).

In roadsign_t's constructor, we have some odd code that looks as though it assumes 16 players:

Line 111 of schedule_list.cc correctly uses the MAX_PLAYER_COUNT constant, but then initialises a whole set of values using a series of exactly 16 0s, meaning that the number 16 might just as well have been used in any event:

If I understand correctly, that may well use a 16-bit integer to encode all players into a bitfield, although I have not looked at this in detail. One might in principle simply use a 32-bit or 64-bit integer to replace this if the number of players were to be expanded.

If one could fix all of the above issues, one might relatively easily increase MAX_PLAYER_COUNT to, say, 64 (with save/load routines updated to check whether they are loading an old version with 16 player slots or a new version with 64 player slots - one might need an OLD_MAX_PLAYER_COUNT constant to deal with this so that we do not end up re-encoding lots of literal 16s), which should be a sufficient figure for a long time to come.

As to performance, it should be relatively straightforward to test this by profiling with a selection of large games, should it not?

If one could fix all of the above issues, one might relatively easily increase MAX_PLAYER_COUNT

That does read somewhat like "if we just built a rocket, going into space would be easy". You have at least done some of the necessary research, but there might still be other non-obvious caveats like the player mask for signs.

Personally, I only need two players (public player and my company), so any allocation of memory for a hardcoded number of players greater than that is just wasted memory for me.

That does read somewhat like "if we just built a rocket, going into space would be easy". You have at least done some of the necessary research, but there might still be other non-obvious caveats like the player mask for signs.

Personally, I only need two players (public player and my company), so any allocation of memory for a hardcoded number of players greater than that is just wasted memory for me.

How much memory does each (unused) player actually take? It is hard to imagine that it is very much in comparison with modern systems.

One might in theory have dynamic allocation of the number of players, but that would require quite a bit more coding work, as all of the arrays dimensioned by MAX_PLAYER_COUNT would need re-working.

I don't know, but I also don't know how many players people really want. 17? 100? 1000? I thought 64 thousand images would be more that enough, but that turned out to be wrong.

However, the point was merely that I only have something to lose from this. That I am a bit afraid that something that is working, as far as I am concerned, might get broken. For me, there is nothing to gain that outweighs the risk. And that that might add some bias to my input on the case.

64 would be a clear improvement on 16, and is quite a normal maximum number of players for even the latest high-end multi-player games (e.g. Battlefield 1). I was considering doing this for Extended one day in any event, as Extended tends to have very large online games; but I have other priorities to deal with first there.

Maybe. Any more that 64 players on a 2048x2048 map would seem awfully crowded to me, and considering how long it takes to save and load such a map, you probably don't want to multiplay with them the way multiplayer currently works. On the other hand, multiplayer maps are perhaps without trees, which probably account for a lot of the saving and loading time.

Be aware that the number of companies is limited to 16 and not the number of players. One could do something silly like have 60 players playing 15 companies with each company being serviced by 4 players. In fact I would encourage such cooperation as it not only makes playing easier, but also improves the quality of such companies. If there is a limit to the number of players, one could much more easily raise that as it has considerably better cohesion than the number of companies.

Yorkeiser should probably confirm which meaning is the intended one, however everyone seems to assume the original pre-multiplayer meaning of player in Simutrans, which is basically companies. (I guess AI players can't join forces in running a company.)