PreprocessorRef

From The Battle for Wesnoth Wiki
Revision as of 20:13, 29 June 2009 by Silene (talk | contribs) (Removed mention about outdated inclusion syntax and error-causing instance.)

[edit]WML Tags

A:

abilities, about, achievement, achievement_group, add_ai_behavior, advanced_preference, advancefrom, advancement, advances, affect_adjacent, ai, allied_with, allow_end_turn, allow_extra_recruit, allow_recruit, allow_undo, and, animate, animate_unit, animation, aspect, attack (replay, weapon), attack_anim, attacks (special, stats), avoid;

B:

base_unit, background_layer, berserk, binary_path, break, brush;

C:

campaign, cancel_action, candidate_action, capture_village, case, chance_to_hit, change_theme, chat, checkbox, choice, choose, clear_global_variable, clear_menu_item, clear_variable, color_adjust, color_palette, color_range, command (action, replay), continue, core, credits_group, criteria;

D:

damage, damage_type, death, deaths, default, defend, defends, defense, delay, deprecated_message, destination, difficulty, disable, disallow_end_turn, disallow_extra_recruit, disallow_recruit, do, do_command, drains, draw_weapon_anim;

E:

editor_group, editor_music, editor_times, effect, else (action, animation), elseif, endlevel, end_turn (action, replay), enemy_of, engine, entry (credits, options), era, event, experimental_filter_ability, experimental_filter_ability_active, experimental_filter_specials, extra_anim;

F:

facet, facing, fake_unit, false, feedback, female, filter (concept, event), filter_adjacent, filter_adjacent_location, filter_attack, filter_attacker, filter_base_value, filter_condition, filter_defender, filter_enemy, filter_location, filter_opponent, filter_own, filter_owner, filter_radius, filter_recall, filter_second, filter_second_attack, filter_self, filter_side, filter_student, filter_vision, filter_weapon, filter_wml, find_path, fire_event, firststrike, floating_text, fonts, for, foreach, found_item, frame;

G:

game_config, get_global_variable, goal, gold, gold_carryover;

H:

harm_unit, has_ally, has_attack, has_unit, has_achievement, have_location, have_unit, heal_on_hit, heal_unit, healed_anim, healing_anim, heals, hide_help, hide_unit, hides;

I:

idle_anim, if (action, animation, intro), illuminates, image (intro, terrain), init_side, insert_tag, inspect, item, item_group;

J:

jamming_costs, join;

K:

kill, killed;

L:

label, language, leader, leader_goal, leadership, leading_anim, levelin_anim, levelout_anim, lift_fog, limit, literal, load_resource, locale, lock_view, lua;

M:

male, menu_item, message, micro_ai, missile_frame, modification, modifications, modify_ai, modify_side, modify_turns, modify_unit, modify_unit_type, move, move_unit, move_unit_fake, move_units_fake, movement_anim, movement costs, movetype, multiplayer, multiplayer_side, music;

N:

not, note;

O:

object, objective, objectives, on_undo, open_help, option, options, or;

P:

part, petrifies, petrify, place_shroud, plague, poison, post_movement_anim, pre_movement_anim, primary_attack, primary_unit, print, progress_achievement, put_to_recall_list;

R:

race, random_placement, recall (action, replay), recalls, recruit, recruit_anim, recruiting_anim, recruits, redraw, regenerate, remove_event, remove_item, remove_object, remove_shroud, remove_sound_source, remove_time_area, remove_trait, remove_unit_overlay, repeat, replace_map, replace_schedule, replay, replay_start, reset_fog, resistance (ability, unit), resistance_defaults, resolution, resource, return, role, rule;

S:

save, scenario, screen_fade, scroll, scroll_to, scroll_to_unit, secondary_attack, secondary_unit, section, select_unit, sequence, set_achievement, set_extra_recruit, set_global_variable, set_menu_item, set_recruit, set_specials, set_variable, set_variables, sheath_weapon_anim, show_if (message, objective, set_menu_item), show_objectives, side, skirmisher, slider, slow, snapshot, sound, sound_source, source (replay, teleport), special_note, specials, split, stage, standing_anim, statistics, status, store_gold, store_items, store_locations, store_map_dimensions, store_reachable_locations, store_relative_direction, store_side, store_starting_location, store_time_of_day, store_turns, store_unit, store_unit_defense, store_unit_defense_on, store_unit_type, store_unit_type_ids, store_villages, story, swarm, sub_achievement, switch, sync_variable;

T:

target, team, teleport (ability, action), teleport_anim, terrain, terrain_defaults, terrain_graphics, terrain_mask, terrain_type, test, test_condition, test_do_attack_by_id, text_input, textdomain, theme, then, tile, time, time_area, topic, toplevel, trait, transform_unit, traveler, true, tunnel;

U:

unhide_unit, unit (action, scenario), unit_overlay, unit_type, unit_worth, units, unlock_view, unpetrify, unstore_unit, unsynced;

V:

value, variable, variables, variant, variation, victory_anim, village, vision_costs, volume;

W:

while, wml_message, wml_schema;

Z:

zoom;

The WML preprocessor

Wesnoth loads just one configuration file directly: data/_main.cfg. However the WML preprocessor allows game.cfg to load in more files. Whenever a WML file is read by Wesnoth, it is passed through the preprocessor.

The preprocessor can interpret a simple language of string-expansions known as "macros." A macro should always be defined before the place where it needs to be used.

The preprocessor is applied recursively, so included files will be parsed for macros, and after macro expansion will be parsed for macros again, and so on. As a result, you should not write a recursive macro, because it will cause errors (but, alas, not necessarily error messages).

The following directives are used to create and use macros, i.e. shortcuts which reduce repetition of information. See UtilWML, UsefulWMLFragments for examples and the macro reference for the predefined core macros.

  • #define symbol [parameters] newline substitution #enddef all subsequent occurences of {symbol [arguments]} (see below) will be replaced by substitution with all occurences of any parameter {parameter} within substitution replaced by the parameter's corresponding value in arguments. For example, the UNIT macro used below would be defined:
#define UNIT TYPE X Y## the ordering is important here;
                     ## since WML does not distinguish
                     ## data into different types, only
                     ## the ordering is used to determine which
                     ## arguments apply to which parameters.
[unit]
type={TYPE}## the unit will be of type TYPE, so different
           ## instantiations
           ## of this macro can create different units.
x={X}
y={Y}
side=2## the unit will be an enemy, regardless of the parameter
      ## values. This reduces "repetition of information",
      ## since it is no longer necessary to specify
      ## each created unit as an enemy.
[/unit]
#enddef

(See SingleUnitWML for information on creating units using WML.)

  • {symbol [arguments]} if symbol is defined, the preprocessor will replace this instruction by the expression symbol is defined as, using arguments as parameters. You can create multiple word arguments by using parentheses to restrain the argument. For example, while {UNIT Wolf Rider 18 24} will attempt to create a "Wolf" at (Rider,18), causing Wesnoth to crash, the macro {UNIT (Wolf Rider) 18 24} will create a "Wolf Rider" at (18,24) as it should. (UNIT is defined above). See the #define preprocessor instruction above for information on defining symbols, including symbols with arguments. Several symbols are defined in the normal game code; for reference they are listed in UtilWML.

Unlike the other preprocessor directives, #ifdef and #ifndef are not mere conveniences. They are necessary to distinguish between different modes of play.

  • #ifdef symbol substitution-if-stored [#else substitution-if-not-stored] #endif If symbol has been stored, the whole block will be replaced by substitution-if-stored. If not, it will be replaced by substitution-if-not-stored if it is available. symbol can take the following values:
    • a campaign difficulty level. Usually EASY, NORMAL, or HARD, it is decided by the key difficulties (see CampaignWML).
    • a campaign ID. Each campaign stores a preprocessor ID. See define, CampaignWML.
    • MULTIPLAYER is stored when the player is playing or setting up a multiplayer game (i.e. a game with scenario_type=multiplayer).
    • DEBUG_MODE is stored when the player has launched wesnoth in debug mode (i.e. with -d)
    • TUTORIAL is stored when the player is playing the tutorial.
    • APPLE is stored if the computer Wesnoth is being run on is an Apple. (this one is only available to the configuration of the game)
    • PYTHON is stored if Python support is built in and available. Use this to for example show a warning when starting a campaign that uses Python AI's, if Python isn't available.
  • #ifndef behaves exactly like #ifdef, except that it inverts the test sense; guarded text is included only if symbol has not been stored.

#undef can be useful too if #ifdef is not enough.

  • #undef symbol erases symbol

These directives expand a file by including other files, filename may not contain '..' or the directive will be skipped:

  • {filename} if filename isn't a predefined symbol (see above), Wesnoth will assume it's a path to a file in the main data/ subdirectory of Wesnoth and include the file it points to here "as is". Forward slashes(/) should be used to separate directories from their elements, even if your platform uses a different symbol such as colon (:) or backslash (\).
  • {~filename} similar to above, but the preprocessor assumes that the filename is relative to data/ subdirectory of the user data directory. The user data directory varies depending on platform. See Where_is_my_user_data_directory?
  • {./filename} is similar to the {filename} directive, but is assumed to be relative to the directory which contains the file in which this appears. For example, if used in game.cfg, it is equivalent to {filename}.
  • If filename points to a directory, the preprocessor will include all files in the directory filename, non-recursively and in alphabetical order. Starting in 1.3.3, some files in such directories are handled specially.

If there is a file named dir/_main.cfg in a directory referenced as {dir}, only that _main.cfg file is processed; it may include other files in itself, of course . This feature is useful for creating WML directories that are self-contained WML packages with their own initializations (like campaigns). This can replace the older convention of having a dir.cfg at the same level as dir which does {dir} somewhere in itself.

If there are files named dir/*/_main.cfg in a directory referenced as {dir}, where * is any subdirectories dir, then they all are processed (except if there is also a file named dir/_main.cfg). This means that if you have a layout like this:

dir/
dir/a/_main.cfg
dir/a/other.cfg
dir/b/_main.cfg
dir/b/other.cfg
dir/other.cfg

Then {dir} will process (in alphabetical order): dir/a/_main.cfg, dir/b/main.cfg, dir/other.cfg.

If there is a file named dir/_final.cfg in a directory referenced as {dir} (and no main.cfg, so that all files in the directory are processed normally) the _final.cfg is guaranteed to be processed after all other files in the directory.

If there is a file named dir/_initial.cfg in a directory referenced as {dir} (and no main.cfg, so that all files in the directory are processed normally) the _initial.cfg is guaranteed to be processed before all other files in the directory.


Note that the parser was changed various times, so don't expect older Wesnoth version to behave exactly the same.

See Also