Difference between revisions of "OOS (Out of Sync)"

From The Battle for Wesnoth Wiki
(Game begins out of sync)
m (Fix minor textual issues.)
Line 3: Line 3:
 
= OOS (Out of Sync) =
 
= OOS (Out of Sync) =
  
OOS is an error that occurs in a wesnoth scenario when two machines disagree (or one machine disagrees with a replay file) about the game state, i.e. which units are where, how much hp they have, how much gold each side has, etc. More precisely, OOS is announced when a client reads a command, such as "move Dwarf Fighter 8,4 -> 8,5 -> 8,6" or "recruit Gryphon Rider 9,7", which is illegal or nonsensical based on its understanding of the game state.
+
OOS is an error that occurs in a Wesnoth scenario when two machines disagree (or one machine disagrees with a replay file) about the game state, i.e. which units are where, how much HP they have, how much gold each side has, etc. More precisely, OOS is announced when a client reads a command, such as "move Dwarf Fighter 8,4 -> 8,5 -> 8,6" or "recruit Gryphon Rider 9,7", which is illegal or nonsensical based on its understanding of the game state.
  
OOS could in principle be caused by network issues such as dropped packets, by players having mismatched game files, or even by cheating, but it is commonly caused by scenario designers / add-on makers writing unsafe code. This page is about how to write wml that won't cause OOS. If you want to know what you should do if you get OOS in an online game, see [[http://forums.wesnoth.org/viewtopic.php?f=6&t=38881&p=554259&hilit=out+of+sync#p554262| here]].
+
OOS could in principle be caused by network issues such as dropped packets, by players having mismatched game files, or even by cheating, but it is commonly caused by scenario designers / add-on makers writing unsafe code. This page is about how to write WML that won't cause OOS. If you want to know what you should do if you get OOS in an online game, see [[http://forums.wesnoth.org/viewtopic.php?f=6&t=38881&p=554259&hilit=out+of+sync#p554262| here]].
  
 
== Why does OOS happen ==
 
== Why does OOS happen ==
Line 15: Line 15:
  
 
=== Game becomes out of sync ===
 
=== Game becomes out of sync ===
During a wesnoth mp scenario with add-on content, the cfg files for the add-on reside on the host. As the game proceeds the host evaluates this wml and transmits new events / changes to the game state, through the server, to the other clients.  
+
During a Wesnoth MP scenario with add-on content, the cfg files for the add-on reside on the host. As the game proceeds the host evaluates this WML and transmits new events / changes to the game state, through the server, to the other clients.  
  
 
Network economy demands that not only is not all data transmitted, but also data is only transmitted at certain times in response to certain events ("synchronized events").  
 
Network economy demands that not only is not all data transmitted, but also data is only transmitted at certain times in response to certain events ("synchronized events").  
  
A scenario designer will cause OOS if she runs wml during an unsynchronized time which requires user input / randomness to evaluate properly.
+
A scenario designer will cause OOS if she runs WML during an unsynchronized time which requires user input / randomness to evaluate properly.
  
 
Generally speaking a replay file receives the same kind of information about the game that a multiplayer observer of a game would receive, so any technique which would cause OOS for multiplayer will also cause corrupted replays.  
 
Generally speaking a replay file receives the same kind of information about the game that a multiplayer observer of a game would receive, so any technique which would cause OOS for multiplayer will also cause corrupted replays.  
Line 33: Line 33:
 
== Example ==
 
== Example ==
  
Konrad is writing an mp scenario in which players survive attacks from an ai enemy. At the beginning of the scenario he wants to query Player 1 what the difficulty level should be, so he uses a [message] dialog for this with several [option]'s. He puts this in a ''start'' event so that it happens on turn 1.
+
Konrad is writing an MP scenario in which players survive attacks from an AI enemy. At the beginning of the scenario he wants to ask Player 1 what the difficulty level should be, so he uses a [message] dialog for this with several [option]s. He puts this in a ''start'' event so that it happens on turn 1.
  
 
Unfortunately for Konrad, ''start'' is not synchronized -- traditionally in SP wesnoth campaigns, start events would only do things like place doodads on the map and initialize variables, so it isn't synchronized and the different players won't get the same results of the query. After a few turns all the players get OOS errors.
 
Unfortunately for Konrad, ''start'' is not synchronized -- traditionally in SP wesnoth campaigns, start events would only do things like place doodads on the map and initialize variables, so it isn't synchronized and the different players won't get the same results of the query. After a few turns all the players get OOS errors.
Line 39: Line 39:
 
== How to make your code safe ==
 
== How to make your code safe ==
  
# Make the wml happen at a synchronized time instead, i.e. after a moveto event.
+
# Make the WML run at a synchronized time instead, i.e. after a moveto event.
# Use lua wesnoth.synchronize_choice to make sure that all clients match (this is always necessary when using lua math.random). Note that this function doesn't work right in or before prestart.
+
# Use Lua wesnoth.synchronize_choice to make sure that all clients match (this is always necessary when using Lua math.random). Note that this function doesn't work right in or before prestart.
 
# End the scenario and proceed to another before the OOS is detected. The clients are resynchronized on load. (Note: This is used in at least one add-on but is a bit of a hack and only makes sense to do if e.g. you need to get randomness during prestart.)
 
# End the scenario and proceed to another before the OOS is detected. The clients are resynchronized on load. (Note: This is used in at least one add-on but is a bit of a hack and only makes sense to do if e.g. you need to get randomness during prestart.)
  
 
== Additional tricks and tips ==
 
== Additional tricks and tips ==
  
# It is a known bug that the wesnoth rand function is not properly seeded during start and prestart. You can use the lua random generator, or the timestamp function on the host, together with synchonize_choice to achieve this. See [[http://forums.wesnoth.org/viewtopic.php?f=21&t=39351&p=559655&hilit=randomness+in+mp#p559655| here]].
+
# It is a known bug that the Wesnoth rand function is not properly seeded during start and prestart. You can use the Lua random number generator, or the timestamp function on the host, together with synchronize_choice to achieve this. See [[http://forums.wesnoth.org/viewtopic.php?f=21&t=39351&p=559655&hilit=randomness+in+mp#p559655| here]].
 
# More?
 
# More?
  

Revision as of 23:24, 29 October 2013

work in progress, not comprehensive

OOS (Out of Sync)

OOS is an error that occurs in a Wesnoth scenario when two machines disagree (or one machine disagrees with a replay file) about the game state, i.e. which units are where, how much HP they have, how much gold each side has, etc. More precisely, OOS is announced when a client reads a command, such as "move Dwarf Fighter 8,4 -> 8,5 -> 8,6" or "recruit Gryphon Rider 9,7", which is illegal or nonsensical based on its understanding of the game state.

OOS could in principle be caused by network issues such as dropped packets, by players having mismatched game files, or even by cheating, but it is commonly caused by scenario designers / add-on makers writing unsafe code. This page is about how to write WML that won't cause OOS. If you want to know what you should do if you get OOS in an online game, see [here].

Why does OOS happen

Game begins out of sync

This can happen if one of the players has modified their game files, or if the players don't have matching add-on versions.

The OOS may still not appear until a mismatched resource actually appears and does something.

Game becomes out of sync

During a Wesnoth MP scenario with add-on content, the cfg files for the add-on reside on the host. As the game proceeds the host evaluates this WML and transmits new events / changes to the game state, through the server, to the other clients.

Network economy demands that not only is not all data transmitted, but also data is only transmitted at certain times in response to certain events ("synchronized events").

A scenario designer will cause OOS if she runs WML during an unsynchronized time which requires user input / randomness to evaluate properly.

Generally speaking a replay file receives the same kind of information about the game that a multiplayer observer of a game would receive, so any technique which would cause OOS for multiplayer will also cause corrupted replays.

A list of unsynchronized events can be found here: EventWML#Multiplayer_safety.

Example

Konrad is writing a scenario in which a small number of random units are spawned for various sides in a start event, to try to add replay value.

However when he watches replays of his scenario he always gets OOS messages and notices that each time he watches the replay he sees different units.

Example

Konrad is writing an MP scenario in which players survive attacks from an AI enemy. At the beginning of the scenario he wants to ask Player 1 what the difficulty level should be, so he uses a [message] dialog for this with several [option]s. He puts this in a start event so that it happens on turn 1.

Unfortunately for Konrad, start is not synchronized -- traditionally in SP wesnoth campaigns, start events would only do things like place doodads on the map and initialize variables, so it isn't synchronized and the different players won't get the same results of the query. After a few turns all the players get OOS errors.

How to make your code safe

  1. Make the WML run at a synchronized time instead, i.e. after a moveto event.
  2. Use Lua wesnoth.synchronize_choice to make sure that all clients match (this is always necessary when using Lua math.random). Note that this function doesn't work right in or before prestart.
  3. End the scenario and proceed to another before the OOS is detected. The clients are resynchronized on load. (Note: This is used in at least one add-on but is a bit of a hack and only makes sense to do if e.g. you need to get randomness during prestart.)

Additional tricks and tips

  1. It is a known bug that the Wesnoth rand function is not properly seeded during start and prestart. You can use the Lua random number generator, or the timestamp function on the host, together with synchronize_choice to achieve this. See [here].
  2. More?


See Also

BuildingMultiplayerExamples