CodeManipulatingWMLVariables

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 https://gna.org/bugs/?func=detailitem&item_id=19258, https://gna.org/bugs/?21962

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.

https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/mp_game_utils.cpp#L210

if (const config& vars = level.child("variables")) {
	sides.set_variables(vars);
}

https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/mp_game_utils.cpp#L229

// 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")) {
		sides.set_variables(v);
	}
	sides.get_wml_menu_items().set_menu_items(snapshot);
}

https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/mp_game_utils.cpp#L260

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. https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/play_controller.cpp#L292

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: https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/gamestatus.cpp#L1013

//get variables according to old hierarchy and copy them to new carryover_sides
if(!snapshot.empty()){
	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: https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/playcampaign.cpp#L227

//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: https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/playcampaign.cpp#L429

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

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. https://github.com/wesnoth/wesnoth/blob/0aa13d477d156929616a7409010474c4dc6b5439/src/playcampaign.cpp#L488

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

Changes

- 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 modified on 22 July 2017, at 19:18.