News:

Want to praise Simutrans?
Your feedback is important for us ;D.

More players on network games?

Started by yorkeiser, August 07, 2017, 03:53:33 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

yorkeiser

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...) ?


DrSuperGood

As far as I am aware there is no reasonable limit to the number if connected players, 60 players could be spread over 16 companies and as long as they remain in sync all will work.

The 16 company limit is more difficult to get around. I suspect there are a lot of hard coded constants that expect companies to be in the range of 0 and 15.

prissi

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.

Ters

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

Leartin

Quote from: Ters on August 08, 2017, 10:47:17 AM
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.

Ters

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.)

DrSuperGood

QuoteI 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).

prissi

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).

DrSuperGood

QuoteYes, 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.

Ters

Quote from: DrSuperGood on August 11, 2017, 06:22:58 AM
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.

yorkeiser

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?

Dwachs

Parsley, sage, rosemary, and maggikraut.

yorkeiser

Mmmh that's a reasonable behavior but not really optimal on client's experience.
I'm thinking about a different approach but I can't figure another one just now

yorkeiser

Quote from: prissi on August 08, 2017, 10:02:59 AM
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?

DrSuperGood

QuoteI 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).

QuoteWouldn'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.

jamespetts

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.cc
line 499
line 520
line 511

network_socket_list.h
line 96
line 98
line 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():


for ( int i = 0; i<MAX_PLAYER_COST_BUTTON; i++) {
if (  comp == &filterButtons[i]  ) {
bFilterStates[player->get_player_nr()] ^= (1<<i);
if (bFilterStates[player->get_player_nr()] & (1<<i)) {
chart.show_curve(i);
mchart.show_curve(i);
}
else {
chart.hide_curve(i);
mchart.hide_curve(i);
}
return true;
}
}


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:


if(  desc->is_private_way()  ) {
// init ownership of private ways
ticks_ns = ticks_ow = 0;
if(  player->get_player_nr() >= 8  ) {
ticks_ow = 1 << (player->get_player_nr()-8);
}
else {
ticks_ns = 1 << player->get_player_nr();
}
}


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:


static uint8 selected_tab[MAX_PLAYER_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };


This should in principle be able to be fixed by using a loop using the MAX_PLAYER_COUNT as the maximum value.

I cannot parse the PLAYER_FLAG code in bool tool_add_message_t::init(player_t *player):


bool tool_add_message_t::init(player_t *player)
{
if (  *default_param  ) {
uint32 type = atoi(default_param);
const char* text = strchr(default_param, ',');
if ((type & ~message_t::local_flag) >= message_t::MAX_MESSAGE_TYPE  ||  text == NULL) {
return false;
}
welt->get_message()->add_message( text+1, koord::invalid, type,
    type & message_t::local_flag ? color_idx_to_rgb(COL_BLACK) : PLAYER_FLAG|player->get_player_nr(), IMG_EMPTY );
}
return false;
}


but this looks as though it might possibly rely on a specific, fixed number of maximum players. Similar logic can be found in line 1882 of simvehicle.cc and 6208 of simworld.cc.

We also have the get_player_mask() logic from roadsign_t:


uint16 get_player_mask() const { return (ticks_ow<<8)|ticks_ns; }


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?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

Quote from: jamespetts on August 13, 2017, 01:26:58 PM
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.

jamespetts

Quote from: Ters on August 13, 2017, 01:48:27 PM
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.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

Quote from: jamespetts on August 13, 2017, 01:58:06 PM
How much memory does each (unused) player actually take?

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.

jamespetts

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.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

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.

DrSuperGood

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.

Ters

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.)

yorkeiser

Sorry dudes for not replying before, August is the holidays' period for my wife and babies :)
I read your point of views (hard-coded chunks spotted by jamespetts, and "worries in letting the house stay up" by Ters) and I really understand both of you.
I'm a simutrans player from the beginning and still consider it to be the king of the transport simulators, although the "old" and bidimensional design, so I'd always like to see more and more features; however my job is head of sw development so I understand Ters' more conservative approach.

I'd like to see simutrans grow, and nowadays - don't hide this - multiplayer is a must if you want the community to grow. Simutrans lacks in this: the feature is there but there are few servers, with few slots. Actually only 25 people could play online on pak128 (that I assume to be the standard one, even if pak64 is the default), if they don't run their personal server. In the years there have been - and there are yet - some servers online, but they've always been really few. So players' slots are always full. Increasing number of companies (I can't imagine two or more players playing the same company, even if it's possible) imho could be a simple way of letting more people approach the game by playing it online and maybe develop the community

prissi

That is a very good point indeed.

But with servers, it is like with the whole internet (and the sucess of ASDL). There are way more consumers than contributors. You can rent a server good enough for large simutrans gams for 10-20€ a year. Even hosting was advertised some time ago. But no one, even for free hosting too that up.

I own three servers, and could connect also a fourth easily. But I lack time to monitor these games. So if there is a volunterr to oversee a server, I happily would offer one too.

jamespetts

I should note that it is possible to run multiple instances of a Simutrans server on a single virtual server provided that the server has enough threads. I am contemplating doing this for Simutrans-Extended once it is in a more advanced state of development and if it proves popular enough with players so that there is always a game running in different eras for players who prefer different eras to enjoy.

Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

DrSuperGood

QuoteI should note that it is possible to run multiple instances of a Simutrans server on a single virtual server provided that the server has enough threads. I am contemplating doing this for Simutrans-Extended once it is in a more advanced state of development and if it proves popular enough with players so that there is always a game running in different eras for players who prefer different eras to enjoy.
One also has to limit the maximum upload bandwidth that each server application instance can consume otherwise someone joining one game can cause all games to lag and potentially disconnect everyone from them due to the poor synchronization model currently used by Simutrans (no safety frames).

jamespetts

Quote from: DrSuperGood on August 22, 2017, 12:46:39 AM
One also has to limit the maximum upload bandwidth that each server application instance can consume otherwise someone joining one game can cause all games to lag and potentially disconnect everyone from them due to the poor synchronization model currently used by Simutrans (no safety frames).

Interesting, thank you for the tip. Do you know how to do this in Linux? Incidentally, is this something that is known to happen from testing, or is this something that you predict will happen? If the latter, it might be worthwhile testing this.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.