* Campaigns:
* An Orcish Incursion:
* Linaera can recruit Mage, and cannot recruit Elves
* Heir to the Throne:
* Add journey tracks for 19c/20b path.
* New sprites for Li'sar.
* S10: Clarify objectives and change egg image on capture.
* S19c: Removed the undead and the swamps.
* Tutorial
* Improve translatability for languages with gender-dependent pronouns
* S1: Fix unit being deselected after the select message
* S2: Highlight (outline) talked-about locations
* Legend of Wesmere
* S3: fix bug which silently disabled Urudin retreat AI
* Graphics:
* Updated generic portrait of Mermaid Initiate.
* Added generic portrait for Giant Spider.
* Language and i18n:
* Updated translations: British English, Galician, German, Italian, Japanese,
Polish, Portuguese, RACV, Russian, Scottish Gaelic, Spanish
* Networking:
* Reworked the multiplayer server to use asio functions for networking
operations instead of SDL_net, thus it no longer depends on SDL_net and SDL.
* The client now uses boost::asio for communication with wesnothd too.
* Removed support for SDL 1.2. SDL 2 is now the only supported version.
* Terrains:
* Changed terrain code of Desert Mountains from Mdy to Mdd.
* Editor:
* Allow to set special locations in the editor which can then be read by wml.
* User Interface:
* Fix flickering caused by tooltips, closing windows and tabbing into the game (bug #24532)
* Various design improvements to GUI2 widgets
* New simpler GUI2 loading screen
* New colored cursor graphics
* Fixed Mage of Light halo appearing in the top-left corner of the screen
while the mage is moving (bug #23712).
* Fixed Observers icon appearing behind other top bar items in MP games on
horizontal UI resolutions < 1024 (bug #24455).
* Fixed ToD schedule progress indicator appearing behind other top bar items
on vertical UI resolutions < 600.
* Improved the dialog for choosing what to do when a player leaves in
multiplayer.
* The side overview now also shows allied human sides in sp even if
they aren't discovered yet
* Added an option to disable the loadingscreen animation since it caused
bugs in some configurations.
* Added a gui method to activate loggers (Preferences -> Advanced -> Logging)
loggers activated in the gui print just like loggers activated in the
command line (i.e. messages appear in the console)
* The Lua console screen now has a clear button
* Fix bug #24762: Editor actions are out of sync after resizing.
* Increased the font size for text in buttons.
* Changed unit help topics to use smaller images on smaller monitors.
* WML engine:
* Add color= attribute to [message].
* Add [else], search_recall_list=, auto_recall= to [role]
* Fix some issues with [foreach]
* Fix some issues with backstab-like weapon specials
* Support [effect]times=<integer>
* Add highlight=yes|no to [scroll_to], [scroll_to_unit], [message]
Defaults to no in the first two cases, yes in the third
If yes, the target hex is outlined.
* New ~SCALE_INTO(w,h) IPF which preserves aspect ratio, using bilinear
interpolation scaling.
* New ~SCALE_INTO_SHARP(w,h) IPF which preserves aspect ratio, using
nearest neighbor scaling.
* Support delayed_variable_substitution= in [on_undo], [on_redo]
Note that this means $unit.x and $unit.y may not reflect the unit's
true location, so using [unstore_unit] on $unit may have unexpected effects.
This applies to $second_unit too. The $x1, $y1, $x2, $y2 variables work fine
though, so in most cases they can be used instead. Anything else in $unit
or $second_unit is also fine.
* formula= in SUF can now reference $other_unit via the formula variable "other"
* formula= now supported in location, side, and weapon filters
* Weapon filters now support number, parry, accuracy, and movement_used
* New [has_attack] in standard unit filters; supercedes has_weapon= and
uses full weapon filter.
* lua_function=var.member now works in SUF; however, 'var' still needs to
be a global variable.
* Added new keys name_generator, male_name_generator and female_name_generator
for the [race] tag to declare a context-free grammar to describe how names
are derived
* Modification tags in [modify_unit] now support delayed_variable_substitution
(This means [advancement], [object], and [trait] tags.)
* All looping tags now give an error if they contain no [do] tag.
(They may contain multiple [do] tags, however.)
* Add [message]image_pos=left|right, which mostly supercedes ~RIGHT()
* For [core] authors: New keys for game logo (game_logo, game_logo_background)
* AiWML:
* Filters within [micro_ai] can now use $this_unit, which was previously
impossible due to the config being prematurely parsed.
* Simplified aspect syntax which works for all aspects, present and future:
* All aspects with simple values can be specified as key=value
* Except attacks, all aspects with complex values have a simple tag form
containing only the aspect value (e.g. [avoid])
* All aspects, simple and complex, can be specified using a tag named by
the aspect, whose contents is the same as a corresponding [facet]
* The full [aspect] and [facet] syntax also still works
* [ai] configs no longer recognize the version= key
* ai_algorithm key now selects a preset AI; possible values include
"ai_default_rca", "experimental_ai", and "idle_ai", but custom AIs
defined by eras or modifications with an [ai] tag can also be used
* [leader_goal] now automatically sets facet ID for auto_remove
(Only if using simplified syntax; in full syntax, the ID must still be
specified in two places.)
* The AI config in the gamestate inspector is now split into multiple
sections according to the type of component.
* The following deprecated components have been removed:
* recruitment stage (name=ai_default::recruitment)
* old recruitment candidate action
(name=ai_default_rca::aspect_recruitment_phase)
* old simple move-to-targets candidate action
(name=ai_default_rca::simple_move_and_targeting_phase)
* number_of_possible_recruits_to_force_recruit aspect
* recruitment_ignore_bad_combat aspect
* recruitment_ignore_bad_movement aspect
* The recruitment aspect has been removed from the engine; however,
"recruitment" is now accepted as a synonym for
"recruitment_instructions". Old code should work without changes.
* [goal]name=protect_my_unit
* The following experimental components have been removed:
(Most of these were broken or non-functional)
* Experimental recruitment candidate action
This worked, but was worse than the default recruitment.
* Global fallback candidate action
* Akihara recruitment candidate action
* Fallback stage (functional but useless)
* Strategy Formulation with RCA stage
This worked, but was slow and unmaintained. If a maintainer
steps up, it may be restored later.
* Several of the development AIs available in debug mode in the
multiplayer setup menu
* The "Strong AI" has been renamed to "Default AI (RCA) with Alternate
Recruiting" and is now only available in debug mode.
* Lua components (goals, aspects, stages, and candidate actions)
now support an [args] subtag, which passes any sort of WML data
to the Lua code - this works similarly to [args] in a [lua] tag,
though not quite identically.
* Aspect syntax with [aspect] tag has been fully generalized so that
[aspect], [facet], and [default] are all exactly the same in terms of
what contents they expect. (Except that [facet] additionally takes
turns= and time_of_day=.) The most useful consequences of this:
* You can nest a [facet] inside another [facet] if the outer one has
name=composite_aspect
* You can define a [facet] with the Lua engine
* invalidate_on_tod_change= has been implemented for aspects. It applies
when the bonus resulting from time of day modifiers (excluding any
illumination abilities) changes at any location on the map. Thus, it
occurs on average less often than invalidate_on_turn_start and may
be best combined with an explicit invalidate_on_turn_start=no.
* Minor shorthands have been introduced in the recruitment_instructions
aspect:
* [pattern] tag is like [recruit] with pattern=yes
* [total] tag is like [recruit] with total=yes
* If no [recruit] tag is present, a default is added with importance=0.
This means recruitment will happen even with only [limit] tags.
* Extensions to [modify_ai]:
* [modify_ai]action=change works on aspects, using path=aspect[id].
Useful if you need to change all the facets at once, but note that
it also wipes the [default] facet.
* The [default] facet can be referenced as facet[default_facet].
This should rarely be needed, but is there in case it is.
It also makes them easily identifiable in the inspector.
* Automatically copy over the id= with action=change, if the
new component did not specify one.
* It can add, remove, and change jobs and limits in the
recruitment_instructions aspect. The path to use for this is
aspect[recruitment_instructions].facet[facet_id].recruit[recruit_id].
(For a limit, replace "recruit" with "limit".)
The [recruit] and [limit] tags now support id keys for this.
* Added side_name= attribute in [side], it's now no longer possible to
specify the current_player attribute in the [side] wml.
* unit filters, specially in wesnoth.get_units now have a limit= attribute
to limit the number or matched units.
* Added new attribute "registered_users_only" to MultiplayerServerWML which indicates
that only registered users should be allowed to join the game
* wesnoth now does a stricter check for unit type ids.
* Lua API:
* wesnoth.match_unit can now take a location (rather than a unit) as
the optional third parameter. This will cause the filter to consider
the unit to be on that location instead of its actual location.
This even works for units on a recall list.
* wesnoth.highlight_hex is no longer deprecated, but its effect is
slightly different from the old one. It outlines a hex, nothing more.
* wesnoth.select_hex is now deprecated in favour of the new
wesnoth.select_unit (or u:select). The effect is almost the same
(with the exception that it does not outline the hex if true is
passed as the second argument), but this name change was done to
emphasize that it acts on a unit, more than a location.
* New wesnoth.set_time_of_day function which sets the current time
of day, taken either as the time ID (eg "second_watch") or the index
of the time in the overall schedule (eg, 1 would be dawn in the default
schedule). Optional second argument takes a time area ID, to set
local instead of global time.
* New wesnoth.add_fog and wesnoth.remove_fog functions allow changing fog
on the map. The [lift_fog] and [clear_fog] tags now use this.
* New wesnoth.add_sound_source, wesnoth.remove_sound_source, and
wesnoth.get_sound_source functions to allow manipulation of sound
sources. The [sound_source] and [remove_sound_source] now use these.
* New wesnoth.log function for printing log messages. The [wml_message]
and [deprecated_message] tags now use this.
* New wesnoth.name_generator function builds a name generator and returns
it as a callable userdata. Both the original Markov chain generator
and the new context free grammar generator are supported
* New wesnoth.get_end_level_data() function which can be called in a
victory, defeat, or scenario_end event to access (or change) how
the scenario ends.
* Fix wesnoth.erase_unit failing if the unit was on a recall list.
* WML tables defined in Lua now accept string keys with array values
(where "array" is a table whose keys are all integers). This joins
the elements of the array with commas and produces a single string
value. eg {x = {1,2,3}} is equivalent to {x = "1,2,3"}.
* wesnoth.effects table can now be used to alter the behaviour of
built-in effects - for example, to add a new feature to
[effect]apply_to=attack. It also now supports effect descriptions,
for use by the [trait] tag.
* Additional fields in unit proxy:
* usage, cost - self-explanatory
* traits - list of the IDs of all traits
* abilities - list of the IDs of all abilities
* Additional fields in table returned by wesnoth.get_terrain_info:
* icon, editor_image, light
* Additional fields in unit type proxy:
* race, id, alignment
* attacks, which returns the same thing as unit.attacks
* abilities, same as unit.abilities
* Additional field in side proxy:
* faction (read-only), faction_name (read-only)
* LuaAI:
* The table returned by check_*() now has a "result" field which
gives a description of the action's result; similar to "status"
but more descriptive.
* Target tables now use a descriptive name for "type", instead of
an integer. This applies to the elements of the table returned by
ai.get_targets() and also to the elements of tables returned by
Lua goals. (However, Lua goals that used integers will continue
to work for now.)
* There are some compatibility-breaking changes to Lua candidate
actions - see the release notes or the wiki for full details.
* Lua AI code can now access the AI routines through the global ai
object. This object is only accessible to AI code; it does not exist
in the general Lua global scope.
* When executing Lua goals, aspects, or candidate action evaluations,
the ai is in "read-only" mode - the read_only key is set to true,
and functions that change the gamestate, such as ai.attack(), are
missing from the table. (ai.check_*() functions are still present.)
* The ai.aspects table provides access to every aspect known by the
engine, including several that previously did not have corresponding
ai.get_*() functions. You access them as ai.aspects.avoid, for example.
The table is read-only and raises an error if you attempt to write to it.
* The way to create Lua candidate actions has changed a little. Old code
will require minor changes.
* New wesnoth.micro_ais table contains the loaders for all Micro AIs.
New loaders can easily be installed by add-ons. See any built-in
micro AI (in ai/micro_ais/mai-defs/) for an example of how to do this.
* The attacks aspect can now be defined as a Lua aspect. The code
should return a table with keys "own" and "enemy", each of which may
be either a unit filter table or a function which takes a unit as a
parameter and returns true or false.
* Added wesnoth.game_events.on_mouse_move/on_mouse_actions callbacks
(fr #22635)
* Added wesnoth.special_locations
* [lua] tags now also support the [args] subtag outside events.
* added lua_function= attribute in location filters
* Added on_event.lua which is an eaiser to use wrapper for
wesnoth.game_events.on_event
* Multiplayer:
* Hornshark Island: simplified multiplayer faction determination
* Added "Registered users only" checkbox to multiplayer configuration dialog which
when checked, only allows registered users to join the game
* Wesnoth formula engine:
* Formulas in unit filters can now access nearly all unit attributes
The following attributes were renamed (old names still work, for now):
leader -> canrecruit
total_movement -> max_moves
movement_left -> moves
states -> status
* Nearly all unit type, side, weapon, and terrain attributes available
to Lua code are now also exposed to WFL. The exceptions are mainly
translatable strings.
* Unit and side WML variables are now accessible under "wml_vars".
Since WML variables don't easily translate to formula variables, the
special attributes __all_children, __children, and __attributes provide
specialized views of the variables config as a list, string-list map,
and string-value map, respectively.
* The 'special' attribute of weapons was renamed to 'specials', and it now
contains the special IDs rather than their translateable names.
* New syntax features:
* String interpolation syntax. Within a formula string (enclosed in
'single quotes'), the syntax [some_formula] interpolates the result
of the inner formula into the string. (The simplest use case is
interpolating the values of variables.)
* String can now escape special characters:
['] single quote, [(] open square bracket, [)] close square bracket
* New 'in' operator which tests if a list contains an item or if a map
contains a key.
* New concatenation operator a..b which works on strings and lists
* New range operator a~b which produces a list of consecutive integers
This can also be used for "list slicing" - eg my_list[3~5] returns
a new list containing elements 3 through 5 of my_list.
* Lists can be used as an index for a list. This is "selection indexing"
and returns a new list with only the elements specified by the indexing
list.
* Function definitions (using the def keyword) are now supported in all
formula contexts, which means that they can be used outside FormulaAI.
However, non-FormulaAI functions are currently local to the formula
that declares them.
* Maps containing string keys that are valid identifiers can now be
indexed with the dot operator instead of the indexing operator.
* Strings can now be indexed via 'string'.char[n]. Also supported are
'string'.word[n] and 'string'.item[n] (the latter splits on commas)
* Changes to core functions:
* head() takes an optional argument - if present, a sublist is returned.
* abs(), max(), min() now work on decimal numbers
* reduce() function can specify an optional initial accumulator
This will be returned for an empty list instead of null.
* substring() function can now accept a negative size parameter
This counts backwards from the specified offset
A size of -1 is the same as 1.
* if() can take two arguments; returns null if the condition is false
* tomap() will now invert the effect of tolist()
* debug_print() now shows in chat area if debug mode is on
* New core functions:
* Trig functions tan, acos, asin, atan have been added. (Sin and cos
existed since at least 1.9 but were undocumented until very recently.)
* Other common math functions - root(), sqrt(), cbrt(), log(), exp()
* hypot(x,y) function calculates sqrt(x*x+y*y) with minimal error
* pi() returning the circle ratio
* tail() - opposite of head()
* reverse() function for strings and lists
* zip() function - converts [[1,2,3],[4,5,6]] to [[1,4],[2,5],[3,6]]
* take_while() function returns items from a list until the first one
that fails a condition
* find_string() locates a substring within a string
* replace() replaces a sequence within a string
* type() function checks the type of a formula result
* distance_between() - this was promoted from FormulaAI to core
* pair() function that produces a key-value pair suitable for
passing to tomap() - this also means key-value pairs are now
serializable (relevant in FormulaAI)
* sgn(), trunc() and frac() functions for decimal numbers
* Map generator engine:
* makes now use of the new context free grammar name generator
* ported name generation from english.cfg to [naming]
* Bugfixes:
* Dice operator is now synced (where possible)
* Modulus (%) operator now works on decimal numbers
* Exponentiation (^) operator is now right-associative
* Fix several math operations returning a very large negative number when
the operation was invalid (for example, (-2) ^ 0.5).
Now they return null instead.
* Formula debugger (accessed with the debug() function):
* Now works again, but is skipped unless in debug mode
* No longer explodes on formulas using less-than
* Some better information and formatting in the execution trace
* You can now step through "where" variable assignments
* FormulaAI no longer starts recruiting if a formula evaluates to the
string 'recruit'.
* Deprecated:
* The fai/faiend keywords are deprecated as part of a move to clearly
define the difference between "Wesnoth Formula Language", the language,
and "FormulaAI", the AI engine that uses the language. For now they
still work, but any future code should use wfl/wflend instead.
Use of the .fai file extension is still fine for FormulaAI code;
for other formula code in a separate file, .wfl is recommended instead.
* Miscellaneous and bug fixes:
* Resolve translated logo images not being used (bug #24357)
* Ported the "hexometer" tool from Bash to Python 3
* Recognize hotkey release events
* Allow changing keybindings for scrolling the map.
* Fix the move-to-targets candidate action of the default AI ignoring tunnels
* Fix two rare bugs in the goto candidate action that resulted in goto moves
by other units being skipped after a unit could not get to its goal.
* Replace wmlxgettext tool with new python3 implementation by Nobun:
https://github.com/AncientLich/wmlxgettext-unoff/ * Debug commands that create units now do so for the currently controlled
side instead of always side 1.
* Fixed bug #24696 (Nightstalk ability not working)
* Ported the following scripts to Python 3: TeamColorizer, about_cfg_to_wiki,
campaign2wiki, terrain2wiki
* Wesnoth now ignores unknown arguments that XCode may pass when testing.