Another basic lua query

Discussion of Lua and LuaWML support, development, and ideas.

Moderator: Forum Moderators

User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query

Post by Spannerbag »

Uh... could I clarify/confirm something?

Suppose I have the following line of code:
local wanderers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", filter_wanderer } }
where
filter_wanderer contains the contents of a unit filter and presumably is already in an acceptable form for get_units_with_moves which expects a WML filter?

I believe that's correct ("and" does not need braces) because of this code (from ca_wolves_move.lua):

Code: Select all

local function get_wolves(cfg)
    local wolves = AH.get_units_with_moves {
        side = wesnoth.current.side,
        { "and", wml.get_child(cfg, "filter") }
    }
    return wolves
end
However, would extra braces: local wanderers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", { filter_wanderer } } } do any harm?
I fear they might as the extra braces could result in the desired table being nested in an (otherwise) empty table?
Or am I going down rabbit holes again?

Any deobfuscation gratefully received!

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
gnombat
Posts: 899
Joined: June 10th, 2010, 8:49 pm

Re: Another basic lua query

Post by gnombat »

Spannerbag wrote: June 22nd, 2025, 4:38 pm I was mulling over maybe having a hack at some text and examples for a wiki page: Lua introduction for WML coders for those who are interested - once I feel a bit more confident myself of course (anything I write now would be a great example of how not to do stuff in lua...).
Incorporating lua into a campaign is well documented and the existing wiki is a great reference once you know what you're doing.
However some grounding in basic syntax (with relevant examples) might provide people new to lua some signposts around the more common gotchas?
That is, it's not meant to be an exhaustive tutorial more a launch pad so readers aren't (quite as) overloaded when they refer to resources that assume knowledge/familiarity they may not have (and would maybe struggle to acquire through normal research).
I think that would be useful, although you would probably not want to start out the tutorial with AI-related code, as that is likely too complicated and would scare the noobs away. Probably you would want to start out with simple things like just displaying information on the screen.
Spannerbag wrote: June 22nd, 2025, 5:21 pm However, would extra braces: local wanderers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", { filter_wanderer } } } do any harm?
I fear they might as the extra braces could result in the desired table being nested in an (otherwise) empty table?
You'll probably get an error like "WML table expected, got table" (or maybe some other error).

It's not like an arithmetic expression where you can sometimes add additional parentheses and it will make no difference; e.g., 2 + 3 * 4 is the same thing as 2 + (3 * 4). It is expected that a WML table will have a very specific layout, and if you add additional braces you're inserting an extra table into that layout (so it is no longer a valid WML table).

If you're wondering whether you have the structure of a WML table correct, I would recommend just adding an extra line of debugging code to just display the table, like this:

Code: Select all

local my_filter = { side = wesnoth.current.side, { "and", { filter_wanderer } } }
wesnoth.interface.add_chat_message(wml.tostring(my_filter))
It will either display the WML (so you can check it and make sure that it's what you wanted) or it will generate an error (in which case you will know that you have the structure wrong).
User avatar
Celtic_Minstrel
Developer
Posts: 2376
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Another basic lua query

Post by Celtic_Minstrel »

Spannerbag wrote: June 22nd, 2025, 5:21 pm ("and" does not need braces)
This is an incorrect interpretation. You don't need braces not because it's "and" but because it's a variable. You can think of it as the braces being contained "inside" the name filter_wanderer. So, with that interpretation, you always need braces there, but they might not be literally at that point in the code.
Spannerbag wrote: June 22nd, 2025, 5:21 pm However, would extra braces: local wanderers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", { filter_wanderer } } } do any harm?
With the above interpretation, it should be obvious that extra braces won't work any more than putting a double pair of braces won't work.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query

Post by Spannerbag »

Thanks to everyone for all your patience and support.
I'll go away and digest all I've learned and do some testing and (re)coding.
Hopefully I'll not need to bother you again (at least for awhile ;) ).

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query: back waaaay too soon

Post by Spannerbag »

Hi,
Just spent ages unpicking various problems but am now stumped. :?

I have a scoping problem: values (variables) aren't being passed to functions in the ca definitions?

Here's the WML setup:

Code: Select all

{DEBUG_MSG (_"Setting up micro ai")}
    [micro_ai]
      side=3
      ai_type=wanderers
      action=add
#      action=add / change / delete
      [filter_wanderer]
        type=Great Icemonax
        [filter_wml]
          [variables]
            wmai=1
          [/variables]
        [/filter_wml]
      [/filter_wanderer]
      [filter_follower]
        type=Icemonax
        [filter_wml]
          [variables]
            wmai=1
          [/variables]
        [/filter_wml]
      [/filter_follower]
#  pacifist=no (boolean)	  # Use default for now
#  disable_protect =no (boolean)  # Use default for now
  disable_protect = yes
#  ca_score=integer or 300000	  # Use default for now
    [/micro_ai]
{DEBUG_MSG (_"Adding micro ai controlled units and other not micro ai units")}
    {GENERIC_UNIT 3 (Great Icemonax) 4 4}
    {GENERIC_UNIT 3 (Great Icemonax) 5 5}
    {GENERIC_UNIT 3 Icemonax 6 6}
    {GENERIC_UNIT 3 Icemonax 7 7}
    [modify_unit]
      [filter]
        side=3
        x=4,6
        y=4,6
      [/filter]
      {VARIABLE wmai 1}
    [/modify_unit]
    [unit_overlay]
      side=3
      x=4,6
      y=4,6
      image="misc/mai-overlay.png"
    [/unit_overlay]
Happily [filter_wanderer] and [filter_follower] are correctly extracted.
debugok.jpg
debugok.jpg (48.48 KiB) Viewed 302 times

No errors in lua console (loads of non-error lines deleted):
Initializing Basic Lua Kernel...
...
Running preload scripts...
$
wesnoth.dofile 'lua/wml-tags.lua'
wesnoth.dofile 'lua/feeding.lua'
wesnoth.dofile 'lua/diversion.lua'
wesnoth.dofile 'lua/stun.lua'

$ wesnoth.require '~add-ons/stub18/ai/mai_wanderers.lua'
$ wesnoth.require '~add-ons/stub18/lua/get_uxyid.lua'
$ wesnoth.require '~add-ons/stub18/lua/dbck.lua'
$ wesnoth.require '~add-ons/stub18/lua/gold_min.lua'
$ wesnoth.require '~add-ons/stub18/lua/bannermsg.lua'
$ wesnoth.require '~add-ons/stub18/lua/msglist.lua'
$ wesnoth.require '~add-ons/stub18/lua/filtertest.lua'



When the micro ai turn runs I see a load of lua errors, all complaining that variables aren't assigned?
The first of many such errors was:

Code: Select all

error scripting/lua: ~add-ons/stub18/ai/ca_wanderers_protect.lua:32: variable 'filter_wanderer' must be assigned before being used
stack traceback:
	[C]: in function '.error'
	lua/ilua.lua:138: in metamethod 'index'
	~add-ons/stub18/ai/ca_wanderers_protect.lua:32: in function <~add-ons/stub18/ai/ca_wanderers_protect.lua:30>
	(...tail calls...)
However adding these lines to ca_wanderers_protect.lua:

Code: Select all

  local filter_wanderer = wml.get_child(cfg,"filter_wanderer")
  local filter_follower = wml.get_child(cfg,"filter_follower")
Simply displaced the issue, resulting in a new error:

Code: Select all

error scripting/lua: ~add-ons/stub18/ai/ca_wanderers_move.lua:10: variable 'cfg' must be assigned before being used
stack traceback:
	[C]: in function '.error'
	lua/ilua.lua:138: in metamethod 'index'
	~add-ons/stub18/ai/ca_wanderers_move.lua:10: in main chunk
	[C]: in field 'dofile'
	lua/package.lua:53: in field 'require'
	[string "local self, params, data, filter_own = ......"]:2: in main chunk
Here's the definition file (in full, scroll down past comments to get to code):

Code: Select all

-- mai_wanderers.lua

-- Ugly hack of forest animals micro_ai (mai) to create "wanderers" mai (wmai).
--
-- Use of "wanderer" and "follower" rather than "parent" and "child" to
--   avoid possible confusion and name clashes with some lua functions
--
--   Controls 2 types of units; wanderers and followers so can have wanderers only / followers only / both.
--   A filter for at least one of wanderers and/or followers is required.
--
--  Summary of behaviours
--    Movement:	"wanderer" units move randomly, ignoring enemies.
--		"Follower" units follow wanderers (if any) otherwise move as "wanderer".
-- 		After movement, wanderers have movement set to zero and may attack if the RCA ai decides to do so.
--		Followers have movement and attacks set to zero after movement (i.e. followers never attack offensively).
--
--    Pacifist:	By default wanderers may attack after moving if the default (RCA) ai deems it appropriate (depending on aggression, caution etc.).
--		Setting this boolean to true does NOT disable "protect" behaviour below.
--
--    Disable_protect:	By default wanderers will protect followers whenever an enemy is adjacent ("protect" behaviour).
--
--
-- Tags and keys
--
--   [filter_wanderer]
--   Unit filter for wanderer units, if absent: no wanderers and [filter_follower] must be present.
-- 
--   [filter_follower]
--   Unit filter for follower units, if absent: no followers and [filter_wanderer] must be present.
--
--   [filter_wanderer] & [filter_follower] notes:
--     a) Code only tests for absence of both [filters...] above, it is possible that no units match these filter(s).
--     b) No check for "overlapping" filters (some units both wanderers and followers).  Do this at your own risk.
--
--   disable_protect= no: (boolean). If true disables "protect" behaviour.
--
--   pacifist=no: (boolean). If true wanderers behave like followers and do not attack (except to protect if disable_protect=true)
--			     Otherwise wanderers may attack adjacent enemy units after movement (depending on aggression, caution etc.).
--
--   ca_score		     Default 300000 (actual ca scores are this value -1, -2 and -3). 
--
--   Also honours [avoid] if specified.
--
--
-- Wmai setup skeleton
--
-- [micro_ai]
--  side=...
--  ai_type=wanderers
--  action=add / change / delete
--  [filter_wanderer]
--    Includes micro_ai side number above
--    Standard unit filter sub-tags and keys
--  [/filter_wanderer]
--  [filter_follower]
--    Includes micro_ai side number above
--    Standard unit filter sub-tags and keys
--  [/filter_follower]
--  pacifist=no (boolean)
--  disable_protect=no (boolean)
--  ca_score=integer or 300000
-- [/micro_ai]


function wesnoth.micro_ais.wanderers(cfg)
  local optional_keys = { filter_wanderer = 'tag', filter_follower = 'tag', pacifist = 'boolean', disable_protect = 'boolean'}
  local filter_wanderer = wml.get_child(cfg,"filter_wanderer")
  local filter_follower = wml.get_child(cfg,"filter_follower")

wesnoth.interface.add_chat_message(wml.tostring(filter_wanderer))
wesnoth.interface.add_chat_message(wml.tostring(filter_follower))
if (not cfg.pacifist) then wesnoth.interface.add_chat_message("Pacifist not set")               else wesnoth.interface.add_chat_message(string.format("'pacifist' is %s.", cfg.pacifist)) end
if (not cfg.disable_protect) then wesnoth.interface.add_chat_message("Disable_protect not set") else wesnoth.interface.add_chat_message(string.format("'disable_protect' is %s.", cfg.disable_protect)) end

  if (not filter_wanderer) and (not filter_follower) then wml.error "Wanderers [micro_ai] requires [filter_wanderer] and/or [filter_follower]." end
  local score = cfg.ca_score or 300000
  local CA_parms = {
    ai_id = 'mai_wanderers',
    { ca_id = "protect",	  location = '~add-ons/stub18/ai/ca_wanderers_protect.lua',	  score = score - 1 },
    { ca_id = "move",		  location = '~add-ons/stub18/ai/ca_wanderers_move.lua',	  score = score - 2 },
    { ca_id = "follower_move",	  location = '~add-ons/stub18/ai/ca_wanderers_follower_move.lua', score = score - 3 }
  }
  return {}, optional_keys, CA_parms
end
Here's the move ca:

Code: Select all

-- ca_wanderers_move.lua

-- Wanderers move randomly, ignoring enemies then followers follow wanderers
-- If no wanderers on map, followers (if any) move as wanderers (not as followers)

local AH = wesnoth.require "ai/lua/ai_helper.lua"
-- local LS = wesnoth.require "location_set"
local M = wesnoth.map

  local filter_wanderer = wml.get_child(cfg,"filter_wanderer") -- >>>>>>>>>>>>>>>>>>>> Line 10 <<<<<<<<<<<<<<<<<<<<
  local filter_follower = wml.get_child(cfg,"filter_follower")


local function get_followers(cfg)
  local followers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", filter_follower } }
  return followers
end

local function all_wanderers(cfg)
  local all_wanderers = AH.get_units.find_on_map { side = wesnoth.current.side, { "and", filter_wanderer } }
  return all_wanderers
end

local function get_wanderers(cfg)
  local wanderers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", filter_wanderer } }
  return wanderers
end


local ca_wanderers_move = {}

function ca_wanderers_move:evaluation(cfg)
  if get_wanderers(cfg)[1]				then return cfg.ca_score end  -- Move wanderers, followers (if any) use (ca_wanderers_follower_move)
  if ((not all_wanderers[1]) and get_followers(cfg)[1]) then return cfg.ca_score end  -- Move followers (no wanderers on map to follow)
  return 0
end

function ca_wanderers_move:execution(cfg)
  local unit = get_wanderers(cfg)[1] or ((not all_wanderers[1]) and get_followers(cfg)[1])	  -- Move wanderers (or followers if no wanderers) randomly
  if unit then
    local avoid_locs = AH.get_avoid_map(ai, nil, true)						  -- [avoid]ed locations, if any
    local reach_locs = AH.get_reachmap(unit, { avoid_map = avoid_locs, exclude_occupied = true })  -- Unoccupied hexes this unit can reach, honouring [avoid] if set
    local rand_x,rand_y = reach_locs:random()							  -- Randomly select one of reach_locs
    ai.move_full(unit, rand_x, rand_y)								  -- Move the unit (don't care about outcome or if unit didn't move)
    if unit and unit.valid and (cfg.pacifist or not all_wanderers[1])				  -- Followers (and wanderers if pacifist=true) do not attack
      then AH.checked_stopunit_attacks(ai, unit) end
  end
end

-- ??? Maybe use repeat...until to make units move more randomly until all movement used?
-- ???     local wmai_move_result = ai.move(unit, rand_x, rand_y)
-- ???   until ((not wmai_move_result.ok) or 

return ca_wanderers_move
Can anyone suggest where I look to fix this?
Pretty sure I'm missing something obvious but can't see it. :evil:
Spent hours checking and experimenting and have fixed many issues but this one eludes me. :augh:
I need to let my brain refresh so will leave this until tomorrow (if I get chance, otherwise whenever :roll: ).

Hopefully a fresh pair of eyes will skim through what I laughingly call my code and say Oh yeah, there's the problem!

Thanks in advance for any help and sorry I'm back again so soon... :augh:

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
gnombat
Posts: 899
Joined: June 10th, 2010, 8:49 pm

Re: Another basic lua query: back waaaay too soon

Post by gnombat »

Spannerbag wrote: June 23rd, 2025, 5:09 pm I have a scoping problem: values (variables) aren't being passed to functions in the ca definitions?
The cfg variable is being passed to functions, but you are using it outside of those functions. You will probably need to move those lines inside the function(s) that need them. (You might need to repeat them for every function which needs them.)
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query: back waaaay too soon

Post by Spannerbag »

gnombat wrote: June 23rd, 2025, 5:52 pm
Spannerbag wrote: June 23rd, 2025, 5:09 pm I have a scoping problem: values (variables) aren't being passed to functions in the ca definitions?
The cfg variable is being passed to functions, but you are using it outside of those functions. You will probably need to move those lines inside the function(s) that need them. (You might need to repeat them for every function which needs them.)
Ah... will do some more hacking.
I completely misunderstood section 3.5 of the lua 5.2 manual. :doh:

Thanks for your help! :D

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query: syntax query

Post by Spannerbag »

Hi again,
Is there any way to remove the [and] "wrapper" below?
I realise it's not doing any harm but - me being me - I'd like to get rid of it if possible.
(I've tried what I think are all the obvious options but can't seem to manage this myself.)
And.jpg
And.jpg (80.38 KiB) Viewed 183 times
So what I'd like to see on screen is:

Code: Select all

[filter_adjacent]
  side = 3
  type=Icemonax
  [filter_wml]
    [variables]
      wmai=1
    [/variables]
  [/filter_wml]
[/filter_adjacent]

Here's the function:

Code: Select all

-- Returns enemies adjacent to follower units
-- function ai_helper.get_attackable_enemies(filter, side, cfg)
local function get_adjacent_enemies(cfg)
  local filter_follower = wml.get_child(cfg,"filter_follower")
  if (cfg.disable_protect or (not filter_follower)) then
    return {}
  else
    local avoid_locs = AH.get_avoid_map(ai, nil, true)  -- [avoid]ed locations, if any

-- debug
local my_filter = {  wml.tag.filter_adjacent { side = wesnoth.current.side, { "and", filter_follower } } }
wesnoth.interface.add_chat_message(wml.tostring(my_filter))

    local adjacent_enemies = AH.get_attackable_enemies( { wml.tag.filter_adjacent { side = wesnoth.current.side, { "and", filter_follower } } }, wesnoth.current.side, { avoid_map = avoid_locs } )
    return adjacent_enemies
  end
end
If it's not possible (or too much effort) that'd be good to know too.
As always thanks for your patience and assistance.

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
gnombat
Posts: 899
Joined: June 10th, 2010, 8:49 pm

Re: Another basic lua query

Post by gnombat »

Something like this might work (but it requires you to modify filter_follower):

Code: Select all

local filter_follower = wml.get_child(cfg,"filter_follower")
filter_follower['side'] = wesnoth.current.side
local my_filter = { wml.tag.filter_adjacent(filter_follower) }
wesnoth.interface.add_chat_message(wml.tostring(my_filter))
User avatar
Ravana
Forum Moderator
Posts: 3324
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Another basic lua query

Post by Ravana »

https://wiki.wesnoth.org/LuaAPI/wml#wml.merge and then you can delete [and].
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query

Post by Spannerbag »

gnombat wrote: June 27th, 2025, 12:59 pm Something like this might work...

Code: Select all

local filter_follower = wml.get_child(cfg,"filter_follower")
filter_follower['side'] = wesnoth.current.side
local my_filter = { wml.tag.filter_adjacent(filter_follower) }
wesnoth.interface.add_chat_message(wml.tostring(my_filter))
Oh, good idea! :D
Many thanks for your help!
Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query

Post by Spannerbag »

Ravana wrote: June 27th, 2025, 2:05 pm https://wiki.wesnoth.org/LuaAPI/wml#wml.merge and then you can delete [and].
Very useful!
Many thanks for pointing that out to me, much appreciated!
Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Spannerbag
Posts: 780
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: Another basic lua query: syntax query #2

Post by Spannerbag »

Hi, hope this is a(nother) simple issue that I'm too stupid to solve. :augh:

From the original forest animals code this filter is created:

Code: Select all

    -- The tusker moves as close to enemy as possible
    -- Closeness to tusklets is secondary criterion
    local adj_tusklets = wesnoth.units.find_on_map {
        side = wesnoth.current.side,
        type = cfg.tusklet_type,
        { "filter_adjacent", { id = target.id } }
    }
As a starting point all I want to do is replace type = cfg.tusklet_type with ("the contents of the variable filter_follower").

local filter_follower = wml.get_child(cfg,"filter_follower") contains:

Code: Select all

  type=Icemonax
  [filter_wml]
    [variables]
      wmai=1
    [/variables]
  [/filter_wml]
So instead of:

Code: Select all

  side = 3
  type = cfg.tusklet_type
  [filter_adjacent]
    id = target.id
  [/filter_adjacent]
I want:

Code: Select all

  side = 3
  type=Icemonax
  [filter_wml]
    [variables]
      wmai=1
    [/variables]
  [/filter_wml]
  [filter_adjacent]
    id = target.id
  [/filter_adjacent]

wml.merge seems to output a non-WML table (at least I get errors saying something like got table, WML table expected) so "nesting" wml.merge doesn't seem to work (for me anyway).

Also tried using the voodoo __cgf which (except for metamethods) I've not found (helpfully) documented anywhere so I've no idea what it does or how it works (either generally or in the context of BfW lua environment). :roll: *

However had seen wml.get_child(cfg.__cfg, used so tried that.
local filter_follower = wml.get_child(cfg.__cfg, "filter_follower")
However this seems to be treated as "nil" so that doesn't work for me either.

_____________________________________________________________________________________________________________
* People did take the trouble to explain - and I appreciate their efforts - but they underestimated my stupidity and ignorance. :doh:

Code: Select all

  for i = 1, #units do
    units[i] = units[i].__cfg
  end
Ravana wrote: May 3rd, 2025, 10:39 am 1. It replaces each element in variable units with __cfg property of its original value.
2. For string format you have wml.tostring.
Would help if I had any clue at all what __cfg property of its original value meant... :(
Celtic_Minstrel wrote: May 3rd, 2025, 4:46 pm The word "metamethod" is not a correct descriptor for __cfg. As for what the code does, Ravana summarized the logic of the assignment, and the __cfg call is basically equivalent to [store_unit] – that is, it converts the unit to WML.
Useful but no idea of context; does the whatever-it's-called double underscore thing always convert to WMl or was it the case here due to context and the data the logic was processing?

https://stackoverflow.com/questions/34475995/variable-in-lua-has-a-special-meaning#34476033
And finally, the double underscore. I've only ever used these for metamethods, such as __index or __add, so if you're making a function or API or whatever that checks for a custom metamethod, make sure to be consistent, and use a double underscore.

https://www.lua.org/pil/13.html
Helped a bit but don't know if "__" alone "overrides" an operator and if so which one... :augh:
_____________________________________________________________________________________________________________

I feel I've been dancing round the correct syntax but can't quite get it exactly right. :x

If anyone can guide me out of this rabbit hole I'd be very grateful!

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.18, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Ravana
Forum Moderator
Posts: 3324
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Another basic lua query

Post by Ravana »

type=filter_follower.type then. It does not make any sense to say type=[filter_wml].

__cfg of unit has specific meaning (similar to [store_unit]). __cfg of other classes usually return wml table as well. It is quite common that __ attributes and functions are not implemented in Lua but anyways you need to check documentation.
gnombat
Posts: 899
Joined: June 10th, 2010, 8:49 pm

Re: Another basic lua query: syntax query #2

Post by gnombat »

Spannerbag wrote: Yesterday, 2:08 pm wml.merge seems to output a non-WML table (at least I get errors saying something like got table, WML table expected) so "nesting" wml.merge doesn't seem to work (for me anyway).
Try this:

Code: Select all

local my_filter = {
  side = wesnoth.current.side,
  { "filter_adjacent", { id = target.id } }
}
my_filter = wml.merge(filter_follower, my_filter, 'append')
wesnoth.interface.add_chat_message(wml.tostring(my_filter))
Post Reply