LuaAPI/wesnoth/sync

From The Battle for Wesnoth Wiki
< LuaAPI‎ | wesnoth
Revision as of 06:12, 1 July 2021 by Celtic Minstrel (talk | contribs) (Document wesnoth.sync.invoke_command)

The wesnoth.sync module contains functions to synchronize data in a multiplayer scenario.

wesnoth.sync.evaluate_single

  • wesnoth.sync.evaluate_single([description], function, [ai_function], [for_side]) → result

Recovers a WML table that was computed on one client only or was stored in a replay. The actual computation is performed by the function passed as the first function argument, assuming that the client is the side currently playing. For all the other clients, the function will not be called. An optional second function can be passed; if present, it will be used instead of the first one when the client happens to be an AI (hence not enable to interact with a user interface).

local result = wesnoth.sync.evaluate_single(
  function()
    -- Called only on the client handling the current side, if it is a human.
    local choice = 0
    gui.show_dialog(
      some_dialog_cfg, nil,
      function(window)
        choice = window.some_list.value
      end)
    return { value = choice }
  end,
  function()
    -- Called only on the client handling the current side, if it is an AI.
    return { value = math.random(some_list_size) }
  end)
wesnoth.interface.add_chat_message(string.format("Selected item: %d", result.value))

Note: The return value must be a valid WML table - the same kind of thing you could store to a WML variable, and not, for instance, a proxy unit, anything else that uses metatables, or a lua table with another table as the value of a string attribute. Unlike other lua functions, wesnoth.sync.evaluate_single will not throw an error if the table is invalid, but will silently strip out the contents of any invalid subtag.

When wesnoth is running in debug mode (e.g. --debug flag on command line) evaluate_single will chat a "Lua Warning" if it finds that the table returned was partially invalid.

The optional first argument description is a string describing the type of the user input. This is displayed to the other clients while one client executes the passed function. Defaults to "input".

The final argument specifies on which side the function should be evaluated. Defaults to the currently playing side. If the specified side is empty/null controlled, the engine will choose another side.

wesnoth.sync.evaluate_multiple

  • wesnoth.sync.evaluate_multiple([description], function, [default_function], [for_sides]) → result map

Similar to the singular form above, this function takes a function parameter and evaluates it on the specified sides. It takes the following arguments:

  • An optional translatable string describing the type of the user input. This is displayed to the other clients while the specified clients execute the passed function. Defaults to "input"
  • A function that evaluates the choice, returning a WML table. Unlike above, this function is called for AI and human sides (use if controller == "ai" for checking if it is an AI side)
  • An optional function for evaluating the choice in case this side was null controlled. If this function is called, it is called on all clients (unlike the first passed function) defaults to a function returning an empty table.
  • An array of integers specifying on which sides this function should be evaluated. The function is evaluated on all passed sides, and each side may only appear once in this array. All specified sides execute the function simultaneously.

This function returns a table with integer as keys and WML tables as values. The keys are the sides where that action was evaluated, and the values are the values computed by the passed function on each side.

local _ = wesnoth.textdomain "my-scenario"
local result = wesnoth.sync.evaluate_multiple(
function()
  local options = {_"No", _"Yes"}
  local result = gui.show_narration({message = _ "Are you sure you want to play this game?"}, options)
  return { value = tostring(options[result]) }
end,
{1,2})
wesnoth.message("Player 1 wants to play: " .. result[1].value)
wesnoth.message("Player 2 wants to play: " .. result[2].value)

wesnoth.sync.run_unsynced

  • wesnoth.sync.run_unsynced(func)

Calls the given function in a unsynced context. In particular, while executing that function, random results will not be synced in mp. The function is called with no arguments, and any return values are ignored.

wesnoth.sync.invoke_command

  • wesnoth.sync.invoke_command(command_name, cfg)

Invoke a custom synced command, which is registered in the wesnoth.custom_synced_commands table. You can pass an arbitrary WML table as arguments.