[show_if] behaviour clarification please?

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
User avatar
Spannerbag
Posts: 535
Joined: December 18th, 2016, 6:14 pm
Location: Yes

[show_if] behaviour clarification please?

Post by Spannerbag »

Hi,
I'm having fun and games trying to get [show_if] to work as I want/expected.
I've go to the point where I need to get advice from people more knowledgeable than me.

Edit: I've got things working the way I wanted using a bodge involving multiple flag variables but would still appreciate clarification :)

My experience with [show_if] is that it doesn't work properly if the data (test) value is a variable.
When the data variable changes the objectives do not, in my experience.
Manually viewing objectives (from the menu during gameplay which I understand should refresh objectives) doesn't display correctly and, in my experience, neither does [show_objectives].

Examples

These work fine:

Code: Select all

        [show_if]
            [have_unit]
                side=7
            [/have_unit]
        [/show_if]

Code: Select all

        [show_if]
            [have_unit]
                id=Bella
            [/have_unit]
        [/show_if]
But this doesn't:

Code: Select all

        [show_if]
            [have_unit]
                id=$goldband.bearer
                count=0
            [/have_unit]
        [/show_if]
$goldband.bearer begins with an invalid value but when this changes to the id of a unit on-map nothing changes in [objectives] :(
I even tried $goldband[0].bearer but it made no difference (not that I thought it would...)

In this instance using [show_objectives] when $goldband.bearer actually changes isn't a great option because the [show_if] relates to a hint that has multiple dependencies so it may well be that on-screen nothing needs to change.
However whilst debugging I did have a [show_if] with just this one condition and it still didn't change when $goldband.bearer did.

Code: Select all

      [note]
        red=128
        description= _ "<i>Hint:</i> "+_"DEBUG goldband.bearer count=0 no macro"
        [show_if]
          [have_unit]
            id=$goldband[0].bearer
            count=0
          [/have_unit]
        [/show_if]
      [/note]
I also added [show_objectives] after $goldband.bearer changed (with a DEBUG_MSG to let me know it fired correctly, which it did).

Also I understood that selecting objectives from the menu (the wiki mentions manually showing objectives which I presume is clicking the menu objectives option) would also refresh objectives so I thought everything should work as I expected.

This behaviour seems to be consistent; in general whenever the test value is a variable it doesn't seem to work as I'd expect?

So, am I being stupid/missing something, is this expected behaviour (i.e. you can't use variables as test values here) or a bug or what?

Hoping someone can dispel my consufion.

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, 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: 3000
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: [show_if] behaviour clarification please?

Post by Ravana »

Use $|goldband.bearer. First evaluation happens when you set objectives, changing $| to $, second evaluation when reading objectives gets variable value.
User avatar
Spannerbag
Posts: 535
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: [show_if] behaviour clarification please?

Post by Spannerbag »

Ravana wrote: January 23rd, 2023, 7:05 pm Use $|goldband.bearer. First evaluation happens when you set objectives, changing $| to $, second evaluation when reading objectives gets variable value.
Many thanks for taking the time to explain, much appreciated.
It will simplify things enormously in several places!
I can honestly say I would never have thought of that...

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, 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
lhybrideur
Posts: 369
Joined: July 9th, 2019, 1:46 pm

Re: [show_if] behaviour clarification please?

Post by lhybrideur »

For more clarity, you can instead add delayed_variable_substitution=yes in [objectives].
It does more or less the same thing.

I use that because my objective looks like that

Code: Select all

                        [objective]
			        {ALTERNATIVE_OBJECTIVE_CAPTION}
				[show_if]
					[variable]
						name=csia_spoke
						equals=1
					[/variable]
				[/show_if]
				description=_ "Buy some food and find a way to carry it. You have $food_counter| food."
				condition=win
			[/objective]
User avatar
Spannerbag
Posts: 535
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: [show_if] behaviour clarification please?

Post by Spannerbag »

lhybrideur wrote: January 24th, 2023, 1:34 pm For more clarity, you can instead add delayed_variable_substitution=yes in [objectives].
It does more or less the same thing...
Thanks for taking the trouble to reply... when I thought about it I was really consufed for awhile:
https://wiki.wesnoth.org/EventWML#Nested_Events wrote:Delayed Variable Substitution

Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key delayed_variable_substitution which is used in the nested event.

If this key is set to yes, the variables in the nested event will contain values from the turn in which the nested event was triggered. This is the default behavior if the key is omitted. If set to no, the variables in the nested event are set at the time the parent event is triggered.

This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal $variable syntax, use $|variable to cause a variable to contain values relevant to the turn in which the nested event was triggered even when delayed_variable_substitution is set to no. In this way you can have a mix of variables relevant to the parent and nested event trigger times.
... until I realised I'd missed this from the [objectives] wiki entry:
https://wiki.wesnoth.org/EventWML#Nested_Events wrote:Delayed Variable Substitution
delayed_variable_substitution: (Version 1.13.8 and later only) If set to yes, any variables or [insert_tag] are not substituted right away. Instead, they are substituted whenever the objectives are actually viewed.
So, within [objectives] the default is delayed_variable_substitution=no I guess?

Therefore, presumably, a request to display [objectives] (either from the player via menu->objectives or [show_objectives]) is the parent event and the actual [objectives] WML is the nested event?

If so I can see why you'd have delayed_variable_substitution=no as default... but then to make [objectives] evaluate variables when they are actually viewed it is necessary to set delayed_variable_substitution=yes or use $| ... which evaluate when the nested event fires ... and is the default for (as far as I am aware) the rest of WML.
Also, why not always substitute when [objectives] are viewed by default?

So, sadly my little brain is still consufed :?

Where have I gone wrong? What have I misunderstood?
Sorry if I'm being thick... :?

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, 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
Celtic_Minstrel
Developer
Posts: 2207
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: [show_if] behaviour clarification please?

Post by Celtic_Minstrel »

Spannerbag wrote: January 25th, 2023, 12:19 am Therefore, presumably, a request to display [objectives] (either from the player via menu->objectives or [show_objectives]) is the parent event and the actual [objectives] WML is the nested event?
[objectives] is not an event. Whatever it says on EventWML about delayed_variable_substitution is not guaranteed to apply to its use in [objectives].

That said, it has the same name because it essentially does the same thing. Normally, an ActionWML tag substitutes variables immediately when it's called. Some ActionWML tags however support delayed_variable_substitution. If it's set to no, then the tag does not substitute variables when it's called. That means any variables inside the tag are not substituted when the tag is called. They may still be substituted later on, and usually are (that's why those tags offer that key at all).

Ultimately, delayed_variable_substitution has nothing to do with events. It's not a key supported by events. If you put it in an event that's placed directly in the scenario, or an event placed in a campaign or other addon tag, then it does nothing and is ignored. However, you can also put an event inside an event, and that's where the key has meaning.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Spannerbag
Posts: 535
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: [show_if] behaviour clarification please?

Post by Spannerbag »

Celtic_Minstrel wrote: January 25th, 2023, 3:17 am
Spannerbag wrote: January 25th, 2023, 12:19 am Therefore, presumably, a request to display [objectives] (either from the player via menu->objectives or [show_objectives]) is the parent event and the actual [objectives] WML is the nested event?
[objectives] is not an event. Whatever it says on EventWML about delayed_variable_substitution is not guaranteed to apply to its use in [objectives].
Sorry, wasn't clear. I appreciate the [objectives] tag/WML isn't an [event] as such I was just mulling over how the implementation might work internally so as to require the behaviour I was seeing. That is to say when scenario objectives are displayed (by player or WML) some internal "event like" process presumably executes that has the same operational parameters as [event] regarding when variables are substituted?

Now you have clarified/confirmed (I had my suspicions :)) that delayed_variable_substitution differs to some extent when used in nested events vs objectives. OK, that's fine, got that... more or less.
Celtic_Minstrel wrote: January 25th, 2023, 3:17 am That said, it has the same name because it essentially does the same thing. Normally, an ActionWML tag substitutes variables immediately when it's called. Some ActionWML tags however support delayed_variable_substitution. If it's set to no, then the tag does not substitute variables when it's called. That means any variables inside the tag are not substituted when the tag is called. They may still be substituted later on, and usually are (that's why those tags offer that key at all).

Ultimately, delayed_variable_substitution has nothing to do with events. It's not a key supported by events. If you put it in an event that's placed directly in the scenario, or an event placed in a campaign or other addon tag, then it does nothing and is ignored. However, you can also put an event inside an event, and that's where the key has meaning.
Again, that's fine and makes sense. Thanks for taking the trouble to reply, much appreciated.

Unfortunately I am still left with my last question from my previous post:
Also, why not always substitute when [objectives] are viewed by default?
That is to say why is the default behaviour of [objectives] to not (apparently, apologies if I'm wrong) substitute variables when re-evaluated prior to being displayed?
That is, if I understand correctly, this won't work

Code: Select all

    [show_if]
        [have_unit]
            id=$unit_with_the_roofing_beam.id
        [/have_unit]
    [/show_if]
but

Code: Select all

    [show_if]
        [have_unit]
            id=$|unit_with_the_roofing_beam.id	# Use $| to make variable substitute at evaluation time (when viewed)
        [/have_unit]
    [/show_if]
(or equivalently have delayed_variable_substitution=yes in [objectives]) will work as expected (at least to me!).

Why not let WML coders do it the first way? I.e. why not embed delayed_variable_substitution=yes in [objectives] by default?
Am I missing something? Will doing this break other $variables or muck something else up? I'm really not trying to be awkward, I just don't like not understanding things. :)

Again, many thanks for taking the time and trouble to reply; I have learned something and am grateful.

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, 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: 3000
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: [show_if] behaviour clarification please?

Post by Ravana »

I expect it was to not needlessly break compatibility.
User avatar
Celtic_Minstrel
Developer
Posts: 2207
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: [show_if] behaviour clarification please?

Post by Celtic_Minstrel »

Spannerbag wrote: January 25th, 2023, 1:30 pm Now you have clarified/confirmed (I had my suspicions :)) that delayed_variable_substitution differs to some extent when used in nested events vs objectives. OK, that's fine, got that... more or less.
To be clear, I'm not sure that it does differ, but it may differ. The two tags are separate, and are free to interpret the key however they want.
Spannerbag wrote: January 25th, 2023, 1:30 pm
Also, why not always substitute when [objectives] are viewed by default?
That is to say why is the default behaviour of [objectives] to not (apparently, apologies if I'm wrong) substitute variables when re-evaluated prior to being displayed?
I think the only reason is that when [objectives] was first added they didn't notice that variable substitution might need to be delayed. So, in order to break anything that depended on it not being delayed, the key defaults to no.

There's always a chance the default will change one day, though. It has happened with other similar things in Wesnoth.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Spannerbag
Posts: 535
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: [show_if] behaviour clarification please?

Post by Spannerbag »

Ravana wrote: January 25th, 2023, 1:37 pm I expect it was to not needlessly break compatibility.
Celtic_Minstrel wrote: January 25th, 2023, 3:04 pm ...
I think the only reason is that when [objectives] was first added they didn't notice that variable substitution might need to be delayed. So, in order to break anything that depended on it not being delayed, the key defaults to no.

There's always a chance the default will change one day, though. It has happened with other similar things in Wesnoth.
I think, finally, I'm sorted :D
Thanks to everyone who took the trouble to reply and for your patience!
Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, 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...
Post Reply