Open cbeck88 opened 10 years ago
Yes I was thinking about this one as well.
There always were OOS errors in replays played using NM on regular maps. Lately I found out of sync state during 1v1 on regular (non RBY) map. I wonder if refactored NM code can be the case? I didn't had time to inspect this but... Historically there were always problems with NM behavior depending if campaign or single scenario was played. Even before I included it in RBY I had to do some patching for MP campaigns. Obviously recent modifications are definitely worth keeping even if eventually some of code changes are the case.
The solution you have proposed looks good but unfortunately I do not know how to implement it or if its doable. I myself was thinking about more brutal way to solve all kinds of campaign/single scenario problems once and forever :P. My idea was to check RBY variable when NM is played: if its RBY then continue otherwise end game with some kind of error message or silly map and force players to re with correct era. Some king of regular NM (non RBY) era could be extracted from one of the RBY releases to have something playable for non RBY games and eventually with time it will live its own life/be independently developed.
Yeah so there is some discussion with Anonymissimus which talks about this OOS issue in the forum thread about RBY.
As I understand it, OOS will occur if you make any random numbers which affect game state during a nonsynchronized event. In the wiki page for event wml there is a list of events which are synchronized.
TBH it is not really clear to me why wesnoth is designed this way, I guess it is some premature optimization having to do with reducing network load. But it seems that any WML that runs during nonsynchronized events will just get committed to the replay / sent to human players verbatim and not in the form of evaluated results. For instance if you start NM game on Den of Onis, then save a replay at turn 2, then every time you load the replay the leaders will be rerandomized XD, which is the cause of OOS replays. If you look at the save file you will see that redistribute factions code will run each time the replay loads, and if you comment out the randomness and hard code the leader variables to match what they were in the game then the replay is fixed and the OOS goes away. It seems that the only things the devs anticipated that you would do in prestart events is like place doodads around the map.
So its sort of a crazy accident I think that RBY works at all -- as far as I can tell what happens is that all NM games technically make an OOS every time they run, but because they end the level immediately after the randomness occurs it is not caught by the game, and the clients resynchronize when they load the next level. NM era runs again at the start of the next scenario but since there are no more yetis it doesn't do anything and there's no OOS.
Anonymissimus wrote in the forum post that calling math.random as we do is not "safe" and suggested that we put comments in the code so that people don't copy paste it. He says that the textbook thing is to use "wesnoth.synchronize_choice" which will force wesnoth to commit the results to mp / replay rather than the code, but that also synchronize_choice is not available in start / prestart for some reason.
Anyways I thought about this patch idea a little more, but so far as I know there is no way to ask wesnoth what the current scenario is, just as there is no way to ask what the current era is or the current timer. So I don't think there's any way to make NM work on non-rby sets unless the devs decide to support these kinds of queries somehow.
Yes I saw that discussion.
The idea of having events that are synchronized and others that are not doesn't look appealing to me :) but as far as I know Wesnoth wasn't designed for MP (support for it was added at later time). Well its a bit frustrating anyway :). And yes obviously the worst thing is no possibility of sync before prestart :). Even if there would still be two kinds of events but one can sync before prestart things will be orders of magnitude better/easier :).
Actually RBY history goes few years before initial release on github (since I created new repository for it). And if I remember correctly there was a time when replays weren't broken (sometime around early 1.8 maybe). I would have to install dev libs and try custom build to be sure but I kinda think that was the case then. Well maybe Wesnoth could get new replay parser in the future (I think think they were doing something about it in GSoC - don't know how it ended) the current one is maybe too limited/simple.
Cheers
Before I forget about this:
RBY era has always given two messages now -- one of them tells you the name of the map pool and the map set which are stored in variables, and one of them issues a warning to only play on RBY sets, because it causes OOS otherwise.
A few commits ago I made it so that it only gives the warning if it sees that the RBY Message variables are not set. So you don't get a warning if you played on an RBY set, only if you didn't.
Maybe a better behavior if you didn't choose an RBY set is instead of giving a warning, just immediately end level and restart the same level; if the prestart "redistribute factions" event happens and you set the message variables, this should be basically the same as if you did pick an RBY set. This way I think you would be able to use the RBY era without using one of the sets. Not completely sure about the details though. Main issue is if you can actually get the name of the current scenario in wml somehow.