From The Battle for Wesnoth Wiki

This is a list of places in the source code that appear to manipulate WML variables when starting or loading a game. It is intended to help with resolving bugs,

Variables Code

in mp_game_utils

level_to_gamestate: check in level for variables. set those variables in carryover sides. if there is a snapshot, also set those variables. if at the end none are found set empty.

if (const config& vars = level.child("variables")) {

// If we start a fresh game, there won't be any snapshot information.
// If however this is a savegame, we got a valid snapshot here.
if (saved_game) {
	state.snapshot = snapshot;
	if (const config& v = snapshot.child("variables")) {

if (sides.get_variables().empty()) {
	LOG_NG << "No variables were found for the game_state." << std::endl;
} else {
	LOG_NG << "Variables found and loaded into game_state:" << std::endl;
	LOG_NG << sides.get_variables();

in play_controller.cpp

init: for each modification, use gamedata_.add_variable_cfg for each block.

BOOST_FOREACH (const config::any_child& var_cfg, mod_cfg.child("variables").all_children_range()) {
	gamedata_.add_variable_cfg(var_cfg.key, var_cfg.cfg);

in playsingle_controller.cpp

in playscenario, check gamestate.snapshot.variables.["turn_number"] at various points.

in gamestatus.cpp

in constructors of carryover_sides and gamedata, variables data is grabbed from cfg root at various times

in convert_old_saves at line 1013, a large amount of logic:

//get variables according to old hierarchy and copy them to new carryover_sides
	if(const config& variables = snapshot.child("variables")){
		carryover.add_child("variables", variables);
		carryover_start.add_child("variables", replay_start.child_or_empty("variables"));
	} else if (const config& variables = cfg.child("variables")){
		carryover.add_child("variables", variables);
		carryover_start.add_child("variables", variables);
} else if (!replay_start.empty()){
	if(const config& variables = replay_start.child("variables")){
		carryover.add_child("variables", variables);
		carryover_start.add_child("variables", variables);
} else {
	carryover.add_child("variables", cfg.child("variables"));
	carryover_start.add_child("variables", cfg.child("variables"));

in playcampaign.cpp

at line 230, in play_replay, if the startingpos (level) has a [variables] child then add them to carryover sides start:

//for replays, use the variables specified in starting_pos
if (const config &vars = starting_pos.child("variables")) {
	gamestate.carryover_sides_start.child_or_add("variables") = vars;

at line 430, in play_game, we check the snapshot for variables and add them to carryover sides start:

// When starting wesnoth --multiplayer there might be
// no variables which leads to a segfault
if (const config &vars = gamestate.snapshot.child("variables")) {

at line 490, in play_game, in the `while(scenario!=NULL)` loop, we check replay_start for variables and clear and add from carryover sides start if we don't find.

const config &wmlvars = gamestate.replay_start().child("variables");
if (!wmlvars || wmlvars.empty()){
	gamestate.replay_start().add_child("variables", gamestate.carryover_sides_start.child_or_empty("variables"));


- In 1.12 and master this code block ^^ playcampaign.cpp:488-494 was removed to try to fix the bugs

Proposed Changes

- Move the code which gets variables from modifications out of play_controller.cpp and to playcampaign.cpp with similar code.

This page was last edited on 22 July 2017, at 19:18.